Loading crypto/block-luks.c +93 −62 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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; Loading @@ -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"); Loading Loading @@ -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 Loading
crypto/block-luks.c +93 −62 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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; Loading @@ -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"); Loading Loading @@ -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