gparted/include/LUKS_Info.h

70 lines
2.1 KiB
C
Raw Permalink Normal View History

/* Copyright (C) 2015 Mike Fleetwood
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/* LUKS_Info
*
* Cache of active Linux kernel Device-mapper encryption mappings.
* (Named LUKS because only encryption using the LUKS on disk format is
* recognised and handled).
*/
#ifndef GPARTED_LUKS_INFO_H
#define GPARTED_LUKS_INFO_H
#include "BlockSpecial.h"
#include "Utils.h"
Add loading of LUKS mapping offset and length (#760080) Also load the starting offset and length of the active dm-crypt mapping into the LUKS_Info module from the dmsetup output. This provides the location and size of the encrypted data within the underlying block device. Note that dmsetup reports in units of 512 bytes sectors [1], the GParted LUKS_Info module uses bytes and GParted Partition objects work in device sector size units. However the actual sector size of a dm-crypt mapping [2] is the same as that of the underlying block device [3]. # modprobe scsi_debug dev_size_mb=128 sector_size=4096 # fgrep scsi_debug /sys/block/*/device/model /sys/block/sdd/device/model:scsi_debug # parted /dev/sde print Error: /dev/sde: unrecognised disk label Model: Linux scsi_debug (scsi) Disk /dev/sde: 134MB [3] Sector size (logical/physical): 4096B/4096B Partition Table: unknown # cryptsetup luksFormat /dev/sde # cryptsetup luksOpen /dev/sde sde_crypt # parted /dev/mapper/sde_crypt print Error: /dev/mapper/sde_crypt: unrecognised disk label Model: Linux device-mapper (crypt) (dm) Disk /dev/mapper/sde_crypt: 132MB [2] Sector size (logical/physical): 4096B/4096B Partition Table: unknown # cryptsetup status sde_crypt /dev/mapper/sde_crypt is active. type: LUKS1 cipher: aes-cbc-essiv:sha256 keysize: 256 bits device: /dev/sde offset: 4096 sectors size: 258048 sectors mode: read/write # dmsetup table --target crypt ... sde_crypt: 0 258048 crypt aes-cbc-essiv:sha256 0000000000000000000000000000000000000000000000000000000000000000 0 8:64 4096 [1] Both cryptsetup and dmsetup report the offset as 4096 and the size/ length as 258048. 128 MiB / (4096+258048) = 512 byte units, even on a 4096 byte sector size device. Update debugging of LUKS to this: # ./gpartedbin ====================== libparted : 2.4 ====================== DEBUG: /dev/sdb5: LUKS closed DEBUG: /dev/sdb6: LUKS open mapping /dev/mapper/sdb6_crypt, offset=2097152, length=534773760 /dev/sde: unrecognised disk label DEBUG: /dev/sde: LUKS open mapping /dev/mapper/sde_crypt, offset=2097152, length=132120576 Bug 760080 - Implement read-only LUKS support
2015-04-19 07:08:20 -06:00
#include <glibmm/ustring.h>
Add loading of LUKS mapping offset and length (#760080) Also load the starting offset and length of the active dm-crypt mapping into the LUKS_Info module from the dmsetup output. This provides the location and size of the encrypted data within the underlying block device. Note that dmsetup reports in units of 512 bytes sectors [1], the GParted LUKS_Info module uses bytes and GParted Partition objects work in device sector size units. However the actual sector size of a dm-crypt mapping [2] is the same as that of the underlying block device [3]. # modprobe scsi_debug dev_size_mb=128 sector_size=4096 # fgrep scsi_debug /sys/block/*/device/model /sys/block/sdd/device/model:scsi_debug # parted /dev/sde print Error: /dev/sde: unrecognised disk label Model: Linux scsi_debug (scsi) Disk /dev/sde: 134MB [3] Sector size (logical/physical): 4096B/4096B Partition Table: unknown # cryptsetup luksFormat /dev/sde # cryptsetup luksOpen /dev/sde sde_crypt # parted /dev/mapper/sde_crypt print Error: /dev/mapper/sde_crypt: unrecognised disk label Model: Linux device-mapper (crypt) (dm) Disk /dev/mapper/sde_crypt: 132MB [2] Sector size (logical/physical): 4096B/4096B Partition Table: unknown # cryptsetup status sde_crypt /dev/mapper/sde_crypt is active. type: LUKS1 cipher: aes-cbc-essiv:sha256 keysize: 256 bits device: /dev/sde offset: 4096 sectors size: 258048 sectors mode: read/write # dmsetup table --target crypt ... sde_crypt: 0 258048 crypt aes-cbc-essiv:sha256 0000000000000000000000000000000000000000000000000000000000000000 0 8:64 4096 [1] Both cryptsetup and dmsetup report the offset as 4096 and the size/ length as 258048. 128 MiB / (4096+258048) = 512 byte units, even on a 4096 byte sector size device. Update debugging of LUKS to this: # ./gpartedbin ====================== libparted : 2.4 ====================== DEBUG: /dev/sdb5: LUKS closed DEBUG: /dev/sdb6: LUKS open mapping /dev/mapper/sdb6_crypt, offset=2097152, length=534773760 /dev/sde: unrecognised disk label DEBUG: /dev/sde: LUKS open mapping /dev/mapper/sde_crypt, offset=2097152, length=132120576 Bug 760080 - Implement read-only LUKS support
2015-04-19 07:08:20 -06:00
#include <vector>
namespace GParted
{
Capture LUKS mapping master encryption key location (#59) ISSUE OVERVIEW When GParted tries to resize an open LUKS encryption mapping and the volume (master) key was stored in the kernel keyring service [1] it fails like this: Check and repair file system ([Encrypted] ext4) on /dev/...(ERROR) + calibrate /dev/sdd1 (SUCCESS) + check file system on /dev/mapper/sdd1_crypt for errors...(SUCCESS) + grow encryption volume to fill the partition (ERROR) + cryptsetup -v resize 'sdd1_crypt' (ERROR) Command failed with code -1 (wrong or missing parameters). Nothing to read on input. This error occurs with cryptsetup >= 2.0, kernel >= 4.10 and LUKS2 format because the crypt Device-Mapper target no longer has the volume key so cryptsetup resize prompts for a passphrase, but GParted doesn't provide it. THIS COMMIT Additionally capture the location of the volume (master) key location for active encryption mappings. Do this the using the same method that cryptsetup uses [2][3]. Namely if the first character of the KEY is a ":" then the key *was* stored in the kernel keyring service, otherwise it *is* store in the Device-Mapper crypt target as previously. # echo -n badpassword | cryptsetup luksFormat --type luks1 /dev/sdb1 - # echo -n badpassword | cryptsetup luksOpen /dev/sdb1 sdb1_crypt # cryptsetup status sdb1_crypt | egrep 'type|key location' type: LUKS1 key location: dm-crypt # echo -n badpassword | cryptsetup luksFormat --type luks2 /dev/sdb2 - # echo -n badpassword | cryptsetup luksOpen /dev/sdb2 sdb2_crypt # cryptsetup status sdb2_crypt | egrep 'type|key location' type: LUKS2 key location: keyring # dmsetup table --target crypt sdb1_crypt: 0 520192 crypt aes-xts-plain64 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0 8:17 4096 sdb2_crypt: 0 491520 crypt aes-xts-plain64 :64:logon:cryptsetup:3d040240-97ba-4559-af98-72c3be500498-d0 0 8:18 32768 ^ First character of the KEY field --------------' [1] Integration with the kernel keyring service https://gitlab.com/cryptsetup/cryptsetup/blob/v2.0.0/docs/Keyring.txt " Starting with cryptsetup 2.0 we load [Volume Key] VK in kernel keyring by default for LUKSv2 devices ... In summary, the key description visible in dm-crypt table line is a reference to VK that usually no longer exists in kernel keyring service if you used cryptsetup to for device activation. " [2] cryptsetup/v2.3.5/lib/libdevmapper.c:_dm_target_query_crypt() https://gitlab.com/cryptsetup/cryptsetup/-/blob/v2.3.5/lib/libdevmapper.c#L2031 if (key_[0] == ':') *act_flags |= CRYPT_ACTIVATE_KEYRING_KEY; [3] cryptsetup/v2.3.5/src/cryptsetup.c:action_status() https://gitlab.com/cryptsetup/cryptsetup/-/blob/v2.3.5/src/cryptsetup.c#L839 log_std(" key location: %s\n", (cad.flags & CRYPT_ACTIVATE_KEYRING_KEY) ? "keyring" : "dm-crypt"); Closes #59 - Resize of LUKS2 encrypted file system fails with "Nothing to read on input"
2021-03-26 04:46:56 -06:00
enum KeyLocation
{
KEYLOC_DMCrypt = 0, // Master encryption key is stored in DeviceMapper crypt target
KEYLOC_KeyRing // Master encryption key was stored in kernel Key Ring
};
Add loading of LUKS mapping offset and length (#760080) Also load the starting offset and length of the active dm-crypt mapping into the LUKS_Info module from the dmsetup output. This provides the location and size of the encrypted data within the underlying block device. Note that dmsetup reports in units of 512 bytes sectors [1], the GParted LUKS_Info module uses bytes and GParted Partition objects work in device sector size units. However the actual sector size of a dm-crypt mapping [2] is the same as that of the underlying block device [3]. # modprobe scsi_debug dev_size_mb=128 sector_size=4096 # fgrep scsi_debug /sys/block/*/device/model /sys/block/sdd/device/model:scsi_debug # parted /dev/sde print Error: /dev/sde: unrecognised disk label Model: Linux scsi_debug (scsi) Disk /dev/sde: 134MB [3] Sector size (logical/physical): 4096B/4096B Partition Table: unknown # cryptsetup luksFormat /dev/sde # cryptsetup luksOpen /dev/sde sde_crypt # parted /dev/mapper/sde_crypt print Error: /dev/mapper/sde_crypt: unrecognised disk label Model: Linux device-mapper (crypt) (dm) Disk /dev/mapper/sde_crypt: 132MB [2] Sector size (logical/physical): 4096B/4096B Partition Table: unknown # cryptsetup status sde_crypt /dev/mapper/sde_crypt is active. type: LUKS1 cipher: aes-cbc-essiv:sha256 keysize: 256 bits device: /dev/sde offset: 4096 sectors size: 258048 sectors mode: read/write # dmsetup table --target crypt ... sde_crypt: 0 258048 crypt aes-cbc-essiv:sha256 0000000000000000000000000000000000000000000000000000000000000000 0 8:64 4096 [1] Both cryptsetup and dmsetup report the offset as 4096 and the size/ length as 258048. 128 MiB / (4096+258048) = 512 byte units, even on a 4096 byte sector size device. Update debugging of LUKS to this: # ./gpartedbin ====================== libparted : 2.4 ====================== DEBUG: /dev/sdb5: LUKS closed DEBUG: /dev/sdb6: LUKS open mapping /dev/mapper/sdb6_crypt, offset=2097152, length=534773760 /dev/sde: unrecognised disk label DEBUG: /dev/sde: LUKS open mapping /dev/mapper/sde_crypt, offset=2097152, length=132120576 Bug 760080 - Implement read-only LUKS support
2015-04-19 07:08:20 -06:00
struct LUKS_Mapping
{
Glib::ustring name; // Name of the dm-crypt mapping
BlockSpecial container; // Underlying block device containing the LUKS mapping
Byte_Value offset; // Offset to the start of the mapping in the underlying block device
Byte_Value length; // Length of the mapping in the underlying block device
Capture LUKS mapping master encryption key location (#59) ISSUE OVERVIEW When GParted tries to resize an open LUKS encryption mapping and the volume (master) key was stored in the kernel keyring service [1] it fails like this: Check and repair file system ([Encrypted] ext4) on /dev/...(ERROR) + calibrate /dev/sdd1 (SUCCESS) + check file system on /dev/mapper/sdd1_crypt for errors...(SUCCESS) + grow encryption volume to fill the partition (ERROR) + cryptsetup -v resize 'sdd1_crypt' (ERROR) Command failed with code -1 (wrong or missing parameters). Nothing to read on input. This error occurs with cryptsetup >= 2.0, kernel >= 4.10 and LUKS2 format because the crypt Device-Mapper target no longer has the volume key so cryptsetup resize prompts for a passphrase, but GParted doesn't provide it. THIS COMMIT Additionally capture the location of the volume (master) key location for active encryption mappings. Do this the using the same method that cryptsetup uses [2][3]. Namely if the first character of the KEY is a ":" then the key *was* stored in the kernel keyring service, otherwise it *is* store in the Device-Mapper crypt target as previously. # echo -n badpassword | cryptsetup luksFormat --type luks1 /dev/sdb1 - # echo -n badpassword | cryptsetup luksOpen /dev/sdb1 sdb1_crypt # cryptsetup status sdb1_crypt | egrep 'type|key location' type: LUKS1 key location: dm-crypt # echo -n badpassword | cryptsetup luksFormat --type luks2 /dev/sdb2 - # echo -n badpassword | cryptsetup luksOpen /dev/sdb2 sdb2_crypt # cryptsetup status sdb2_crypt | egrep 'type|key location' type: LUKS2 key location: keyring # dmsetup table --target crypt sdb1_crypt: 0 520192 crypt aes-xts-plain64 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0 8:17 4096 sdb2_crypt: 0 491520 crypt aes-xts-plain64 :64:logon:cryptsetup:3d040240-97ba-4559-af98-72c3be500498-d0 0 8:18 32768 ^ First character of the KEY field --------------' [1] Integration with the kernel keyring service https://gitlab.com/cryptsetup/cryptsetup/blob/v2.0.0/docs/Keyring.txt " Starting with cryptsetup 2.0 we load [Volume Key] VK in kernel keyring by default for LUKSv2 devices ... In summary, the key description visible in dm-crypt table line is a reference to VK that usually no longer exists in kernel keyring service if you used cryptsetup to for device activation. " [2] cryptsetup/v2.3.5/lib/libdevmapper.c:_dm_target_query_crypt() https://gitlab.com/cryptsetup/cryptsetup/-/blob/v2.3.5/lib/libdevmapper.c#L2031 if (key_[0] == ':') *act_flags |= CRYPT_ACTIVATE_KEYRING_KEY; [3] cryptsetup/v2.3.5/src/cryptsetup.c:action_status() https://gitlab.com/cryptsetup/cryptsetup/-/blob/v2.3.5/src/cryptsetup.c#L839 log_std(" key location: %s\n", (cad.flags & CRYPT_ACTIVATE_KEYRING_KEY) ? "keyring" : "dm-crypt"); Closes #59 - Resize of LUKS2 encrypted file system fails with "Nothing to read on input"
2021-03-26 04:46:56 -06:00
KeyLocation key_loc; // Location where the master encryption key is stored
Add loading of LUKS mapping offset and length (#760080) Also load the starting offset and length of the active dm-crypt mapping into the LUKS_Info module from the dmsetup output. This provides the location and size of the encrypted data within the underlying block device. Note that dmsetup reports in units of 512 bytes sectors [1], the GParted LUKS_Info module uses bytes and GParted Partition objects work in device sector size units. However the actual sector size of a dm-crypt mapping [2] is the same as that of the underlying block device [3]. # modprobe scsi_debug dev_size_mb=128 sector_size=4096 # fgrep scsi_debug /sys/block/*/device/model /sys/block/sdd/device/model:scsi_debug # parted /dev/sde print Error: /dev/sde: unrecognised disk label Model: Linux scsi_debug (scsi) Disk /dev/sde: 134MB [3] Sector size (logical/physical): 4096B/4096B Partition Table: unknown # cryptsetup luksFormat /dev/sde # cryptsetup luksOpen /dev/sde sde_crypt # parted /dev/mapper/sde_crypt print Error: /dev/mapper/sde_crypt: unrecognised disk label Model: Linux device-mapper (crypt) (dm) Disk /dev/mapper/sde_crypt: 132MB [2] Sector size (logical/physical): 4096B/4096B Partition Table: unknown # cryptsetup status sde_crypt /dev/mapper/sde_crypt is active. type: LUKS1 cipher: aes-cbc-essiv:sha256 keysize: 256 bits device: /dev/sde offset: 4096 sectors size: 258048 sectors mode: read/write # dmsetup table --target crypt ... sde_crypt: 0 258048 crypt aes-cbc-essiv:sha256 0000000000000000000000000000000000000000000000000000000000000000 0 8:64 4096 [1] Both cryptsetup and dmsetup report the offset as 4096 and the size/ length as 258048. 128 MiB / (4096+258048) = 512 byte units, even on a 4096 byte sector size device. Update debugging of LUKS to this: # ./gpartedbin ====================== libparted : 2.4 ====================== DEBUG: /dev/sdb5: LUKS closed DEBUG: /dev/sdb6: LUKS open mapping /dev/mapper/sdb6_crypt, offset=2097152, length=534773760 /dev/sde: unrecognised disk label DEBUG: /dev/sde: LUKS open mapping /dev/mapper/sde_crypt, offset=2097152, length=132120576 Bug 760080 - Implement read-only LUKS support
2015-04-19 07:08:20 -06:00
};
class LUKS_Info
{
public:
static void clear_cache();
Add loading of LUKS mapping offset and length (#760080) Also load the starting offset and length of the active dm-crypt mapping into the LUKS_Info module from the dmsetup output. This provides the location and size of the encrypted data within the underlying block device. Note that dmsetup reports in units of 512 bytes sectors [1], the GParted LUKS_Info module uses bytes and GParted Partition objects work in device sector size units. However the actual sector size of a dm-crypt mapping [2] is the same as that of the underlying block device [3]. # modprobe scsi_debug dev_size_mb=128 sector_size=4096 # fgrep scsi_debug /sys/block/*/device/model /sys/block/sdd/device/model:scsi_debug # parted /dev/sde print Error: /dev/sde: unrecognised disk label Model: Linux scsi_debug (scsi) Disk /dev/sde: 134MB [3] Sector size (logical/physical): 4096B/4096B Partition Table: unknown # cryptsetup luksFormat /dev/sde # cryptsetup luksOpen /dev/sde sde_crypt # parted /dev/mapper/sde_crypt print Error: /dev/mapper/sde_crypt: unrecognised disk label Model: Linux device-mapper (crypt) (dm) Disk /dev/mapper/sde_crypt: 132MB [2] Sector size (logical/physical): 4096B/4096B Partition Table: unknown # cryptsetup status sde_crypt /dev/mapper/sde_crypt is active. type: LUKS1 cipher: aes-cbc-essiv:sha256 keysize: 256 bits device: /dev/sde offset: 4096 sectors size: 258048 sectors mode: read/write # dmsetup table --target crypt ... sde_crypt: 0 258048 crypt aes-cbc-essiv:sha256 0000000000000000000000000000000000000000000000000000000000000000 0 8:64 4096 [1] Both cryptsetup and dmsetup report the offset as 4096 and the size/ length as 258048. 128 MiB / (4096+258048) = 512 byte units, even on a 4096 byte sector size device. Update debugging of LUKS to this: # ./gpartedbin ====================== libparted : 2.4 ====================== DEBUG: /dev/sdb5: LUKS closed DEBUG: /dev/sdb6: LUKS open mapping /dev/mapper/sdb6_crypt, offset=2097152, length=534773760 /dev/sde: unrecognised disk label DEBUG: /dev/sde: LUKS open mapping /dev/mapper/sde_crypt, offset=2097152, length=132120576 Bug 760080 - Implement read-only LUKS support
2015-04-19 07:08:20 -06:00
static const LUKS_Mapping & get_cache_entry( const Glib::ustring & path );
private:
static void initialise_if_required();
static void load_cache();
static const LUKS_Mapping & get_cache_entry_internal( const Glib::ustring & path );
Add loading of LUKS mapping offset and length (#760080) Also load the starting offset and length of the active dm-crypt mapping into the LUKS_Info module from the dmsetup output. This provides the location and size of the encrypted data within the underlying block device. Note that dmsetup reports in units of 512 bytes sectors [1], the GParted LUKS_Info module uses bytes and GParted Partition objects work in device sector size units. However the actual sector size of a dm-crypt mapping [2] is the same as that of the underlying block device [3]. # modprobe scsi_debug dev_size_mb=128 sector_size=4096 # fgrep scsi_debug /sys/block/*/device/model /sys/block/sdd/device/model:scsi_debug # parted /dev/sde print Error: /dev/sde: unrecognised disk label Model: Linux scsi_debug (scsi) Disk /dev/sde: 134MB [3] Sector size (logical/physical): 4096B/4096B Partition Table: unknown # cryptsetup luksFormat /dev/sde # cryptsetup luksOpen /dev/sde sde_crypt # parted /dev/mapper/sde_crypt print Error: /dev/mapper/sde_crypt: unrecognised disk label Model: Linux device-mapper (crypt) (dm) Disk /dev/mapper/sde_crypt: 132MB [2] Sector size (logical/physical): 4096B/4096B Partition Table: unknown # cryptsetup status sde_crypt /dev/mapper/sde_crypt is active. type: LUKS1 cipher: aes-cbc-essiv:sha256 keysize: 256 bits device: /dev/sde offset: 4096 sectors size: 258048 sectors mode: read/write # dmsetup table --target crypt ... sde_crypt: 0 258048 crypt aes-cbc-essiv:sha256 0000000000000000000000000000000000000000000000000000000000000000 0 8:64 4096 [1] Both cryptsetup and dmsetup report the offset as 4096 and the size/ length as 258048. 128 MiB / (4096+258048) = 512 byte units, even on a 4096 byte sector size device. Update debugging of LUKS to this: # ./gpartedbin ====================== libparted : 2.4 ====================== DEBUG: /dev/sdb5: LUKS closed DEBUG: /dev/sdb6: LUKS open mapping /dev/mapper/sdb6_crypt, offset=2097152, length=534773760 /dev/sde: unrecognised disk label DEBUG: /dev/sde: LUKS open mapping /dev/mapper/sde_crypt, offset=2097152, length=132120576 Bug 760080 - Implement read-only LUKS support
2015-04-19 07:08:20 -06:00
static std::vector<LUKS_Mapping> luks_mapping_cache;
static bool cache_initialised;
};
}//GParted
#endif /* GPARTED_LUKS_INFO_H */