mirror of https://gitee.com/openkylin/qemu.git
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
|
@ -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
|
||||
* the master encryption key from the key slot.
|
||||
|
@ -622,7 +713,6 @@ qcrypto_block_luks_open(QCryptoBlock *block,
|
|||
{
|
||||
QCryptoBlockLUKS *luks = NULL;
|
||||
Error *local_err = NULL;
|
||||
size_t i;
|
||||
g_autofree uint8_t *masterkey = NULL;
|
||||
char *ivgen_name, *ivhash_name;
|
||||
g_autofree char *password = NULL;
|
||||
|
@ -644,30 +734,10 @@ qcrypto_block_luks_open(QCryptoBlock *block,
|
|||
luks = g_new0(QCryptoBlockLUKS, 1);
|
||||
block->opaque = luks;
|
||||
|
||||
/* Read the entire LUKS header, minus the key material from
|
||||
* the underlying device */
|
||||
if (readfunc(block, 0,
|
||||
(uint8_t *)&luks->header,
|
||||
sizeof(luks->header),
|
||||
opaque,
|
||||
errp) < 0) {
|
||||
if (qcrypto_block_luks_load_header(block, readfunc, opaque, errp) < 0) {
|
||||
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,
|
||||
QCRYPTO_BLOCK_LUKS_MAGIC_LEN) != 0) {
|
||||
error_setg(errp, "Volume is not in LUKS format");
|
||||
|
@ -1216,46 +1286,7 @@ qcrypto_block_luks_create(QCryptoBlock *block,
|
|||
goto error;
|
||||
}
|
||||
|
||||
/* Everything on disk uses Big Endian, so flip header fields
|
||||
* 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);
|
||||
if (qcrypto_block_luks_store_header(block, writefunc, opaque, errp) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue