[gparted] Populate LUKS partition usage (#760080)



commit 317114ffcb5543563cc4b36c54c6cecad270d29e
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Sun Nov 15 13:14:54 2015 +0000

    Populate LUKS partition usage (#760080)
    
    Populate the used, unused and unallocated figures in the Partition
    object for a LUKS formatted partition.  See comment in
    luks::set_used_sectors() for the rational of what is used, unused and
    unallocated.
    
    As that rational mentions, a LUKS header does not store the size of the
    encrypted data and is assumed to extend to the end of the partition by
    the tools which start the mapping.
    
    An underlying block device of 128 MiB (131072 KiB).
        # sfdisk -s /dev/sde
        131072
    
    An active LUKS mapping at offset 2 MiB (4096 512-byte sectors) and
    length 126 MiB (129024 KiB, 258048 512-byte sectors).
        # sfdisk -s /dev/mapper/sde_crypt
        129024
        # 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
    
    No size/length reported when dumping the LUKS header, just (payload)
    offset.
        # cryptsetup luksDump /dev/sde
        LUKS header information for /dev/sde
    
        Version:        1
        Cipher name:    aes
        Cipher mode:    cbc-essiv:sha256
        Hash spec:      sha1
        Payload offset: 4096
        MK bits:        256
        MK digest:      7f fb ba 40 7e ba e4 3b 2f c6 d0 93 7b f7 05 49 7b 72 d4 ad
        MK salt:        4a 5b 54 f9 7b 67 af 6e ef 16 31 0a fe d9 7e 5f
                        c3 66 dc 8a ed e0 07 f4 45 c3 7c 1a 8d 7d ac f4
        MK iterations:  37750
        UUID:           0a337705-434a-4994-a842-5b4351cb3778
        ...
    
    Shrink the LUKS mapping to 64 MiB (65536 KiB, 131072 512-byte sectors).
        # cryptsetup resize --size 131072 sde_crypt
        # sfdisk -s /dev/mapper/sde_crypt
        65536
        # 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:    131072 sectors
          mode:    read/write
    
    Stop and start the LUKS mapping.
        # cryptsetup luksClose sde_crypt
        # cryptsetup luksOpen /dev/sde sde_crypt
    
    The size of the LUKS mapping is back to 126 MiB (129024 KiB, 258048
    512-byte sectors), extending to the end of the partition.
        # sfdisk -s /dev/mapper/sde_crypt
        129024
        # 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
    
    Bug 760080 - Implement read-only LUKS support

 include/luks.h |    2 ++
 src/luks.cc    |   50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 52 insertions(+), 0 deletions(-)
---
diff --git a/include/luks.h b/include/luks.h
index a5dfa37..86e4e15 100644
--- a/include/luks.h
+++ b/include/luks.h
@@ -19,6 +19,7 @@
 #define GPARTED_LUKS_H
 
 #include "../include/FileSystem.h"
+#include "../include/Partition.h"
 
 namespace GParted
 {
@@ -28,6 +29,7 @@ class luks : public FileSystem
 public:
        FS get_filesystem_support();
        bool is_busy( const Glib::ustring & path );
+       void set_used_sectors( Partition & partition );
 };
 
 } //GParted
diff --git a/src/luks.cc b/src/luks.cc
index 396c373..d420590 100644
--- a/src/luks.cc
+++ b/src/luks.cc
@@ -16,6 +16,7 @@
 
 
 #include "../include/LUKS_Info.h"
+#include "../include/Utils.h"
 #include "../include/luks.h"
 
 namespace GParted
@@ -27,6 +28,8 @@ FS luks::get_filesystem_support()
        fs.filesystem = FS_LUKS;
 
        fs.busy = FS::EXTERNAL;
+       fs.read = FS::EXTERNAL;
+       fs.online_read = FS::EXTERNAL;
 
        return fs;
 }
@@ -37,4 +40,51 @@ bool luks::is_busy( const Glib::ustring & path )
        return ! mapping.name.empty();
 }
 
+void luks::set_used_sectors( Partition & partition )
+{
+       // Rational for how used, unused and unallocated are set for LUKS partitions
+       //
+       // A LUKS formatted partition has metadata at the start, followed by the encrypted
+       // data.  The LUKS format only records the offset at which the encrypted data
+       // starts.  It does NOT record it's length.  Therefore for inactive LUKS mappings
+       // the encrypted data is assumed to extend to the end of the partition.  However
+       // an active device-mapper (encrypted) mapping does have a size and can be resized
+       // with the "cryptsetup resize" command.
+       //
+       //  *  Metadata is required and can't be shrunk so treat as used space.
+       //  *  Encrypted data, when active, is fully in use by the device-mapper encrypted
+       //     mapping so must also be considered used space.
+       //  *  Any space after an active mapping, because it has been shrunk, is considered
+       //     unallocated.  This matches the equivalent with other file systems.
+       //  *  Nothing is considered unused space.
+       //
+       // Therefore for an active LUKS partition:
+       //     used        = LUKS data offset + LUKS data length
+       //     unused      = 0
+       //     unallocated = remainder
+       //
+       // And for an inactive LUKS partition:
+       //     used        = partition size
+       //     unused      = 0
+       //     unallocated = 0
+       //
+       // References:
+       // *   LUKS On-Disk Format Specification
+       //     https://gitlab.com/cryptsetup/cryptsetup/wikis/LUKS-standard/on-disk-format.pdf
+       // *   cryptsetup(8)
+       LUKS_Mapping mapping = LUKS_Info::get_cache_entry( partition.get_path() );
+       if ( mapping.name.empty() )
+       {
+               // Inactive LUKS partition
+               T = partition.get_sector_length();
+               partition.set_sector_usage( T, 0 );
+       }
+       else
+       {
+               // Active LUKS partition
+               T = Utils::round( ( mapping.offset + mapping.length ) / double(partition.sector_size) );
+               partition.set_sector_usage( T, 0 );
+       }
+}
+
 } //GParted


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]