I’d like to share with my observations on how the data is arranged on a physical disk and reading further you will also understand how does the encryption look like on a disk.
The test scenario is to create 16 bytes file, filled with ones “1”, then to see how does it look like on a disk, find its location relative to the beginning of a disk (/dev/vda), also to see how does it look like when encrypted, and what is changed when its contents are altered.
I’ll use Debian 7.2 running under KVM, ext4 filesystem on LVM and AES in XTS mode.
Virtual disk size is 8GB. FS,LVM and, later, encryption layouts are default as Debian installer recommends.
root@debian:~# lsblk -f /dev/vda
NAME FSTYPE LABEL MOUNTPOINT
vda
├─vda1 ext2 /boot
├─vda2
└─vda5 LVM2_member
├─rootvg-root (dm-0) ext4 /
├─rootvg-swap_1 (dm-1) swap [SWAP]
├─rootvg-usr (dm-2) ext4 /usr
├─rootvg-var (dm-3) ext4 /var
├─rootvg-tmp (dm-4) ext4 /tmp
└─rootvg-home (dm-5) ext4 /home
Create a file filled with “1”’s, 16bytes in size.
root@debian:/tmp# while true; do printf 1;done |dd bs=16 count=1 of=./test.txt
1+0 records in
1+0 records out
16 bytes (16 B) copied, 0.00459532 s, 3.5 kB/s
root@debian:/tmp# ls -la ./test.txt
-rw-r--r-- 1 root root 16 Nov 1 16:52 ./test.txt
root@debian:/tmp# hexdump -C ./test.txt
00000000 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 |1111111111111111|
00000010
Make sure that data was physically written on a disk
# sync && mount -o remount /tmp && echo 1 | tee /proc/sys/vm/drop_caches
(hdparm method) Find a file offset relative to the beginning of the device
root@debian:/tmp# hdparm --fibmap ./test.txt
./test.txt:
filesystem blocksize 1024, begins at LBA 0; assuming 512 byte sectors.
byte_offset begin_LBA end_LBA sectors
0 16902 16903 2
16902*512 = 8653824 byte
(filefrag method) Find a file offset relative to the beginning of the device
root@debian:/tmp# filefrag -bsv ./test.txt
Filesystem type is: ef53
File size of ./test.txt is 16 (1 block, blocksize 1024)
ext logical physical expected length flags
0 0 8451 1 eof
./test.txt: 1 extent found
8451 (in 1024 blocksize) - is an offset where data starts.
8451*1024 = 8653824 byte
Reading contents of a file relative to the beginning of the device
root@debian:/tmp# df .
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/rootvg-tmp 230069 6159 212032 3% /tmp
root@debian:/tmp# dd if=/dev/mapper/rootvg-tmp bs=1024 count=1 skip=8451 |hexdump -C
00000000 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 |1111111111111111|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000400
1+0 records in
1+0 records out
1024 bytes (1.0 kB) copied, 0.0161307 s, 63.5 kB/s
The same can be achieved with hexdump
root@debian:/tmp# hexdump -C -s $((8451*1024)) -n 1024 /dev/mapper/rootvg-tmp
00840c00 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 |1111111111111111|
00840c10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00841000
hexdump indicates the offset in HEX -> 0x00840c00 = 8653824 (8451*1024)
Note: ‘-u’ gives sizes in sectors instead of cylinders.
root@debian:/tmp# fdisk -u -l /dev/vda
Disk /dev/vda: 8589 MB, 8589934592 bytes
16 heads, 63 sectors/track, 16644 cylinders, total 16777216 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00020cff
Device Boot Start End Blocks Id System
/dev/vda1 * 2048 499711 248832 83 Linux
/dev/vda2 501758 16775167 8136705 5 Extended
/dev/vda5 501760 16775167 8136704 8e Linux LVM
dmsetup can show the beginning of the target device relative to the beginning of the parent device
root@debian:/tmp# dmsetup table rootvg-tmp
0 475136 linear 254:5 10053632
root@debian:/tmp# dd if=/dev/vda bs=512 count=1 skip=$(( 501760+(10053632)+(8451*1024)/512 )) status=noxfer 2>/dev/null|hexdump -C
00000000 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 |1111111111111111|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000200
What we skipped is following
With hexdump
root@debian:/tmp# hexdump -C -s $(( 512* (501760+(10053632)+(8451*1024)/512) )) -n 512 /dev/vda
142a40c00 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 |1111111111111111|
142a40c10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
142a40e00
0x142a40c00 = 5413014528 byte
Before starting I suggest to read
root@debian:~# lsblk -f /dev/vda
NAME FSTYPE LABEL MOUNTPOINT
vda
├─vda1 ext2 /boot
├─vda2
└─vda5 crypto_LUKS
└─vda5_crypt (dm-0) LVM2_member
├─rootvg-root (dm-1) ext4 /
├─rootvg-usr (dm-2) ext4 /usr
├─rootvg-var (dm-3) ext4 /var
├─rootvg-swap_1 (dm-4) swap [SWAP]
├─rootvg-tmp (dm-5) ext4 /tmp
└─rootvg-home (dm-6) ext4 /home
The ./test.txt file filled with ones “1” was created as follows
root@debian:/tmp# while true; do printf 1;done |dd bs=16 count=1 of=./test.txt
1+0 records in
1+0 records out
16 bytes (16 B) copied, 0.00459532 s, 3.5 kB/s
root@debian:/tmp# ls -la ./test.txt
-rw-r--r-- 1 root root 16 Nov 1 17:15 ./test.txt
root@debian:/tmp# hexdump -C ./test.txt
00000000 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 |1111111111111111|
00000010
Find a file offset relative to the beginning of the device (in our case the device is /dev/mapper/rootvg-tmp)
root@debian:/tmp# hdparm --fibmap ./test.txt
./test.txt:
filesystem blocksize 1024, begins at LBA 0; assuming 512 byte sectors.
byte_offset begin_LBA end_LBA sectors
0 16902 16903 2
root@debian:/tmp# filefrag -bsv ./test.txt
Filesystem type is: ef53
File size of ./test.txt is 16 (1 block, blocksize 1024)
ext logical physical expected length flags
0 0 8451 1 eof
./test.txt: 1 extent found
Reading file contents relative to the beginning of the device
root@debian:/tmp# dd if=/dev/mapper/rootvg-tmp bs=1024 count=1 skip=8451 |hexdump -C
00000000 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 |1111111111111111|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000400
1+0 records in
1+0 records out
1024 bytes (1.0 kB) copied, 0.0069164 s, 148 kB/s
root@debian:/tmp# hexdump -C -s $((8451*1024)) -n 1024 /dev/mapper/rootvg-tmp
00840c00 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 |1111111111111111|
00840c10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00841000
Looking at the encrypted block
root@debian:/tmp# fdisk -u -l /dev/vda
Disk /dev/vda: 8589 MB, 8589934592 bytes
16 heads, 63 sectors/track, 16644 cylinders, total 16777216 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000047b6
Device Boot Start End Blocks Id System
/dev/vda1 * 2048 499711 248832 83 Linux
/dev/vda2 501758 16775167 8136705 5 Extended
/dev/vda5 501760 16775167 8136704 83 Linux
root@debian:/tmp# dmsetup table rootvg-tmp
0 475136 linear 253:0 10053632
root@debian:/tmp# dmsetup table vda5_crypt
0 16269312 crypt aes-xts-plain64 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0 254:5 4096
root@debian:/tmp# dmsetup table rootvg-tmp
0 475136 linear 253:0 10053632
root@debian:/tmp# dd if=/dev/vda bs=512 count=1 skip=$(( 501760+4096+10053632+(8451*1024)/512 )) status=noxfer 2>/dev/null|hexdump -C -n32
00000000 96 6a 48 e3 7e 31 d8 f4 6c 2c 86 a6 02 49 f5 e5 |.jH.~1..l,...I..|
00000010 85 a1 cf d4 99 b2 ec cc 35 db 8c c9 94 db 28 14 |........5.....(.|
Altering the test file contents in order to see a change in the encrypted block.
Writing number “2” to the end of a test file.
root@debian:/tmp# printf 2 |dd of=./test.txt count=1 bs=1 seek=15 status=noxfer
1+0 records in
1+0 records out
root@debian:/tmp# filefrag -bsv ./test.txt
Filesystem type is: ef53
File size of ./test.txt is 16 (1 block, blocksize 1024)
ext logical physical expected length flags
0 0 8451 1 eof
./test.txt: 1 extent found
After each ./test.txt file modification, always make sure (using hdparm of filefrag) that physical offset did not changed.
root@debian:/tmp# hexdump -C ./test.txt
00000000 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 32 |1111111111111112|
00000010
root@debian:/tmp# sync && mount -o remount /tmp && echo 1 | tee /proc/sys/vm/drop_caches
root@debian:/tmp# dd if=/dev/vda bs=512 count=1 skip=$(( 501760+4096+10053632+(8451*1024)/512 )) status=noxfer 2>/dev/null|hexdump -C -n32
00000000 c8 c2 19 59 ea 54 3c e7 05 6f 80 98 94 7d df 37 |...Y.T<..o...}.7|
00000010 85 a1 cf d4 99 b2 ec cc 35 db 8c c9 94 db 28 14 |........5.....(.|
00000020
One more attempt.
root@debian:/tmp# printf 3 |dd of=./test.txt count=1 bs=1 seek=15 status=noxfer
1+0 records in
1+0 records out
root@debian:/tmp# hexdump -C ./test.txt
00000000 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 33 |1111111111111113|
00000010
root@debian:/tmp# sync && mount -o remount /tmp && echo 1 | tee /proc/sys/vm/drop_caches
1
root@debian:/tmp# dd if=/dev/vda bs=512 count=1 skip=$(( 501760+4096+10053632+(8451*1024)/512 )) status=noxfer 2>/dev/null|hexdump -C -n32
00000000 38 59 ca b4 86 b3 aa 99 27 5f 5c 3b c0 6c 4c 3d |8Y......'_\;.lL=|
00000010 85 a1 cf d4 99 b2 ec cc 35 db 8c c9 94 db 28 14 |........5.....(.|
00000020
Reading directly from /dev/vda5
root@debian:/tmp# dd if=/dev/vda5 bs=512 count=1 skip=$(( 4096+10053632+(8451*1024)/512 )) status=noxfer 2>/dev/null|hexdump -C -n32
00000000 38 59 ca b4 86 b3 aa 99 27 5f 5c 3b c0 6c 4c 3d |8Y......'_\;.lL=|
00000010 85 a1 cf d4 99 b2 ec cc 35 db 8c c9 94 db 28 14 |........5.....(.|
00000020
Reading directly from decrypted device
root@debian:/tmp# dd if=/dev/mapper/vda5_crypt bs=512 count=1 skip=$(( 10053632+(8451*1024)/512 )) status=noxfer 2>/dev/null|hexdump -C -n32
00000000 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 33 |1111111111111113|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020
Reading directly from LV
root@debian:/tmp# dd if=/dev/mapper/rootvg-tmp bs=512 count=1 skip=$(( (8451*1024)/512 )) status=noxfer 2>/dev/null|hexdump -C -n32
00000000 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 33 |1111111111111113|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020
Recreating new container using master key of original volume
root@debian:/tmp# cryptsetup luksDump /dev/vda5
LUKS header information for /dev/vda5
Version: 1
Cipher name: aes
Cipher mode: xts-plain64
Hash spec: sha1
Payload offset: 4096
MK bits: 512
MK digest: e2 51 ef 39 ba 4f 55 04 86 55 27 98 b0 fe 18 59 cc d7 df bd
MK salt: 23 e3 17 94 c1 40 f6 97 f5 26 fd 04 d9 89 a6 3b
72 b3 b3 3e ba 01 ec 9c 31 dd 0f 50 4f 60 93 3d
MK iterations: 43500
UUID: 814ed852-3354-4f79-beb2-12b0146492df
Key Slot 0: ENABLED
Iterations: 174019
Salt: 0c 9e 77 23 72 8d 9c 58 08 20 5a 0b 02 83 a9 51
d3 99 a7 70 1c ef 8c 1e 1f ec a6 3b a8 4c eb a4
Key material offset: 8
AF stripes: 4000
Key Slot 1: DISABLED
Key Slot 2: DISABLED
Key Slot 3: DISABLED
Key Slot 4: DISABLED
Key Slot 5: DISABLED
Key Slot 6: DISABLED
Key Slot 7: DISABLED
Dump your master key
root@debian:/tmp# dmsetup table vda5_crypt --showkeys
0 16269312 crypt aes-xts-plain64 9a7a685a9b03218f773d9235b7b51922df8ffad4900bbc97f4152c4fd5a85b821953bfb192c6d7f1c01a689462bae979ad8b757f5e2e89e523ad2bb9a50a63fc 0 254:5 4096
You can also use cryptsetup command to get the master key
root@debian:/tmp# cryptsetup luksDump --dump-master-key /dev/vda5
**WARNING!**
========
LUKS header dump with volume key is sensitive information
which allows access to encrypted partition without passphrase.
This dump should be always stored encrypted on safe place.
Are you sure? (Type uppercase yes): YES
Enter LUKS passphrase:
LUKS header information for /dev/vda5
Cipher name: aes
Cipher mode: xts-plain64
Payload offset: 4096
UUID: 814ed852-3354-4f79-beb2-12b0146492df
MK bits: 512
MK dump: 9a 7a 68 5a 9b 03 21 8f 77 3d 92 35 b7 b5 19 22
df 8f fa d4 90 0b bc 97 f4 15 2c 4f d5 a8 5b 82
19 53 bf b1 92 c6 d7 f1 c0 1a 68 94 62 ba e9 79
ad 8b 75 7f 5e 2e 89 e5 23 ad 2b b9 a5 0a 63 fc
Save the mater key to a file
# echo -n "9a7a685a9b03218f773d9235b7b51922df8ffad4900bbc97f4152c4fd5a85b821953bfb192c6d7f1c01a689462bae979ad8b757f5e2e89e523ad2bb9a50a63fc" | xxd -r -p > master.key
root@debian:/tmp# hexdump -C ./master.key
00000000 9a 7a 68 5a 9b 03 21 8f 77 3d 92 35 b7 b5 19 22 |.zhZ..!.w=.5..."|
00000010 df 8f fa d4 90 0b bc 97 f4 15 2c 4f d5 a8 5b 82 |..........,O..[.|
00000020 19 53 bf b1 92 c6 d7 f1 c0 1a 68 94 62 ba e9 79 |.S........h.b..y|
00000030 ad 8b 75 7f 5e 2e 89 e5 23 ad 2b b9 a5 0a 63 fc |..u.^...#.+...c.|
00000040
Copying encrypted block data to ./todecrypt.luks file
root@debian:/tmp# dd if=/dev/vda bs=512 count=1 skip=$(( 501760+4096+10053632+(8451*1024)/512 )) status=noxfer of=./todecrypt.luks 2>/dev/null
root@debian:/tmp# ls -lah todecrypt.luks
-rw-r--r-- 1 root root 512 Nov 1 18:55 todecrypt.luks
root@debian:/tmp# hexdump -C ./todecrypt.luks
00000000 38 59 ca b4 86 b3 aa 99 27 5f 5c 3b c0 6c 4c 3d |8Y......'_\;.lL=|
00000010 85 a1 cf d4 99 b2 ec cc 35 db 8c c9 94 db 28 14 |........5.....(.|
00000020 a1 46 a0 40 85 42 82 82 27 b1 99 89 25 b7 a1 c4 |.F.@.B..'...%...|
00000030 55 57 de 53 47 5d a8 d8 fe 2f 37 7a 4b 8c 7f 41 |UW.SG].../7zK..A|
00000040 b7 f9 ad 62 c8 49 0f 52 3b cd 7e 6a 39 89 ee 6a |...b.I.R;.~j9..j|
00000050 98 d9 23 f0 cf 3b ce 79 4c 11 87 62 33 0e 96 29 |..#..;.yL..b3..)|
00000060 7a 6f c2 25 50 eb 8f b8 b3 de 90 ba 97 b6 da b5 |zo.%P...........|
00000070 91 a4 c5 cc ab d0 c9 0a 2d 1f 2d 88 a0 28 8c 32 |........-.-..(.2|
00000080 15 f7 58 f0 aa cd 7f 50 01 55 23 f2 18 2f 90 6d |..X....P.U#../.m|
00000090 7c 03 7f a0 32 68 66 1c 48 cd ce 5c 07 9b f7 71 ||...2hf.H..\...q|
000000a0 80 fa 08 a8 2f 71 45 3d c0 f8 67 39 b4 96 10 ce |..../qE=..g9....|
000000b0 72 60 a0 bd ae 37 b1 32 10 b1 7a 1c 76 53 f6 3f |r`...7.2..z.vS.?|
000000c0 66 eb f8 96 3c 32 1e 18 4b a2 77 7e be 0d 8d bb |f...<2..K.w~....|
000000d0 a5 99 97 54 6d 9e dc 4d 1d c2 0d ba 78 db ff ed |...Tm..M....x...|
000000e0 44 8f 61 31 84 24 68 ab db 6a e7 9d 0a 44 a5 90 |D.a1.$h..j...D..|
000000f0 c1 f8 28 bc e3 4c ac 5c 1f bd 7e a4 90 57 89 3a |..(..L.\..~..W.:|
00000100 bb 90 3d c0 4b 7d a0 94 f5 1b 0a 12 c0 9e d9 d9 |..=.K}..........|
00000110 f8 25 a7 0f 6b ca 73 57 90 e4 96 bd 26 b4 a4 ad |.%..k.sW....&...|
00000120 28 7a 7c 69 d3 5a 8b a7 b4 f5 bf b8 a2 81 11 3d |(z|i.Z.........=|
00000130 8a d0 c6 a5 3f 12 0e 6e 37 2d 30 c7 c0 c9 f9 70 |....?..n7-0....p|
00000140 7f 13 45 ad 41 17 c4 96 8a 78 a5 4a da 61 3a fc |..E.A....x.J.a:.|
00000150 75 96 5c 39 d3 46 3f cb 10 2b 1c a5 84 3a 61 d1 |u.\9.F?..+...:a.|
00000160 44 37 67 4a a0 b4 44 70 b4 1a 86 45 4f be 1f 1b |D7gJ..Dp...EO...|
00000170 4a 20 70 a8 40 3e 69 a0 a9 50 89 7e 70 f4 ab 73 |J p.@>i..P.~p..s|
00000180 c7 b9 85 7b 3a 37 cd 0d 8a fc ad fc b4 13 c6 27 |...{:7.........'|
00000190 41 64 f0 a9 95 89 10 c5 8c f0 5b 9b 44 b6 af ab |Ad........[.D...|
000001a0 ec 9a 20 3f b9 ce c1 f0 18 e4 1c 36 d6 8d b5 d8 |.. ?.......6....|
000001b0 5c 42 21 b0 57 e7 a8 76 85 a9 ff f2 39 f8 d4 39 |\B!.W..v....9..9|
000001c0 ee 6a 4d db ad d6 ab ab f8 d6 3e 92 38 cf c9 58 |.jM.......>.8..X|
000001d0 54 be 74 af 40 c0 9d 4d 98 75 b1 9e 20 6d 28 6b |T.t.@..M.u.. m(k|
000001e0 ec 71 5a ff 39 3a cb dd 37 7f aa 73 c9 13 d4 9e |.qZ.9:..7..s....|
000001f0 d1 8a 1f cc c0 a3 d6 a7 41 f8 ae 3e a4 8e 46 88 |........A..>..F.|
00000200
Create dummy.luks file with size of 2MB (which is just enough to store LUKS Header and Keyslots)
root@debian:/tmp# dd if=/dev/zero of=./dummy.luks bs=512 count=4096
4096+0 records in
4096+0 records out
2097152 bytes (2.1 MB) copied, 0.0183268 s, 114 MB/s
root@debian:/tmp# ls -latrh dummy.luks
-rw-r--r-- 1 root root 2.0M Nov 1 19:00 dummy.luks
root@debian:/tmp# losetup /dev/loop1 ./dummy.luks
root@debian:/tmp# cryptsetup luksFormat --cipher aes-xts-plain64 --key-size 512 --master-key-file ./master.key /dev/loop1
WARNING!
========
This will overwrite data on /dev/loop1 irrevocably.
Are you sure? (Type uppercase yes): YES
Enter LUKS passphrase:
Verify passphrase:
root@debian:/tmp#
NOTE: You can leave an empty passphrase. (just hit Enter)
Appending encrypted block to the LUKS container
root@debian:/tmp# dd if=./todecrypt.luks of=./dummy.luks bs=512 count=1 oflag=append conv=notrunc
1+0 records in
1+0 records out
512 bytes (512 B) copied, 8.9331e-05 s, 5.7 MB/s
root@debian:/tmp# losetup -c /dev/loop1
root@debian:/tmp#
Open the dummy LUKS container
root@debian:/tmp# cryptsetup luksOpen /dev/loop1 dummy.deluks
Enter passphrase for /dev/loop1:
root@debian:/tmp# hexdump -C /dev/mapper/dummy.deluks
root@debian:/tmp# cryptsetup luksClose dummy.deluks
Alternatively you could “clone” the original LUKS headers to the dummy LUKS container
root@debian:/tmp# cryptsetup luksHeaderBackup /dev/vda5 --header-backup-file ./vda5.luks.header
root@debian:/tmp# cryptsetup luksHeaderRestore /dev/loop1 --header-backup-file ./vda5.luks.header
root@debian:/tmp# cryptsetup luksOpen /dev/loop1 dummy.deluks
Enter passphrase for /dev/loop1: luks
To completely recreate LUKS headers without destroying the encrypted data
root@debian:/tmp# cryptsetup luksClose dummy.deluks
root@debian:/tmp# dd if=/dev/zero of=./dummy.luks bs=512 count=4096 conv=notrunc
root@debian:/tmp# cryptsetup luksFormat --cipher aes-xts-plain64 --key-size 512 --master-key-file ./master.key /dev/loop1
root@debian:/tmp# cryptsetup luksOpen /dev/loop1 dummy.deluks
root@debian:/tmp# hexdump -C /dev/mapper/dummy.deluks
00000000 e4 47 d7 3f 21 1f de 8b 50 92 7c e8 5a cc 7b 86 |.G.?!...P.|.Z.{.|
...
Moving encrypted block of data to the dummy LUKS device
root@debian:/tmp# dd if=/dev/vda bs=512 count=1 skip=$(( 501760+4096+10053632+0 )) status=noxfer of=./todecrypt.luks 2>/dev/null
If you are changing size of a dummy LUKS device, you have to let device-mapper and LUKS aware of this
root@debian:/tmp# losetup -c /dev/loop1
root@debian:/tmp# cryptsetup resize dummy.deluks
To replace 512 bytes starting from 4096’s sector (sector size is 512 bytes)
root@debian:/tmp# dd if=./todecrypt.luks of=./dummy.luks bs=512 seek=4096 count=1 conv=notrunc
Trying to decrypt previously copied encrypted block of data
root@debian:/tmp# hexdump -C /dev/mapper/dummy.deluks
For some reason it does not give the desired result…
However, it will be OK if starting to decrypt the data from the very beginning of the encrypted area, see below.
root@debian:/tmp# dd if=/dev/vda bs=512 count=1 skip=$(( 501760+4096 )) status=noxfer of=./todecrypt.luks 2>/dev/null
root@debian:/tmp# hexdump -C /dev/mapper/dummy.deluks
00000000 be 87 04 3b 77 d9 c2 20 f7 11 c5 5b 46 1a d2 71 |...;w.. ...[F..q|
00000010 f5 e8 84 fe 59 6c c4 0f 91 d6 0f 19 56 e1 cb e3 |....Yl......V...|
00000020 3b 51 f7 fc a8 1c d6 db bd da 1e c1 28 e3 ae 54 |;Q..........(..T|
00000030 10 0c 3d d8 90 b7 18 85 a5 08 eb 9b 48 a1 ff 52 |..=.........H..R|
00000040 e8 98 f2 db d2 ba c1 dd f9 c0 f7 c3 85 1c 99 a7 |................|
00000050 65 67 c8 b3 a2 16 b3 f5 b1 a2 69 58 c1 37 cf 7e |eg........iX.7.~|
00000060 1a dc d9 88 95 fe 24 51 6b 40 ee ec 56 59 8e 04 |......$Qk@..VY..|
00000070 51 60 05 33 67 cc a9 ec f2 21 86 30 9e 11 a1 d6 |Q`.3g....!.0....|
00000080 db 49 cb 79 d4 6a 9a 9a fc 05 89 53 98 d3 0c 6f |.I.y.j.....S...o|
00000090 f8 da 24 0d 66 64 f3 73 10 6b a7 da 89 dc 0a 39 |..$.fd.s.k.....9|
000000a0 3e 4c 4c 61 9d 87 6e b3 83 06 a3 48 ef 92 59 db |>LLa..n....H..Y.|
000000b0 49 d5 09 0b b9 3f f3 6a 33 f2 8b 53 1d c1 5a 5d |I....?.j3..S..Z]|
000000c0 a6 25 74 07 2b c9 44 03 98 a6 71 d5 72 4e 9f 25 |.%t.+.D...q.rN.%|
000000d0 19 c3 01 77 f0 d7 49 07 e3 2f bb ae 34 45 33 25 |...w..I../..4E3%|
000000e0 fc 4d c8 ab 23 93 f6 7e 36 d7 1e 42 31 08 d2 e4 |.M..#..~6..B1...|
000000f0 d5 bd 4b d3 57 b5 d6 7e 00 26 b5 12 2a 2e da 23 |..K.W..~.&..*..#|
00000100 a0 8b 6e f5 66 d1 39 b3 09 11 52 50 a4 f4 38 1c |..n.f.9...RP..8.|
00000110 89 00 ad 93 58 9d 7d 15 b2 22 eb ed e2 62 86 f4 |....X.}.."...b..|
00000120 d0 6a f6 da c6 85 48 da b5 eb 69 48 17 d8 1f 05 |.j....H...iH....|
00000130 63 1c 2f f5 13 8f 02 18 b0 58 88 d4 ad 37 94 44 |c./......X...7.D|
00000140 b9 c4 d0 29 58 c8 a2 1e 38 e4 13 61 89 bc a8 00 |...)X...8..a....|
00000150 3d 2a 3a 16 f3 f3 42 e0 89 87 29 c7 76 ca 30 19 |=*:...B...).v.0.|
00000160 7b 3a 50 21 02 60 ec db 4c 5a 26 1c 2b 7b dc ae |{:P!.`..LZ&.+{..|
00000170 84 76 70 1c 24 13 8a 7c 18 3e 13 53 57 ee f7 b6 |.vp.$..|.>.SW...|
00000180 f4 f9 19 28 42 43 d3 79 50 ac 32 2c 17 34 30 2f |...(BC.yP.2,.40/|
00000190 16 b8 0f 54 78 fe 9a fe 08 0b da 9c 71 a2 94 89 |...Tx.......q...|
000001a0 c7 15 4d 85 98 75 0a e0 0a f8 9d 5b 78 93 c7 b8 |..M..u.....[x...|
000001b0 b0 01 12 7e c8 24 cb 10 4d af 7a 96 2a 83 17 11 |...~.$..M.z.*...|
000001c0 87 e3 fa 2d ca 13 8e f7 90 85 4e 87 04 6b 8d fe |...-......N..k..|
000001d0 a9 9e b0 b0 27 80 70 0f 7f 97 ee 54 fa 07 13 fb |....'.p....T....|
000001e0 2e 43 70 11 b9 c4 51 21 b0 e9 96 1c 8e da 27 db |.Cp...Q!......'.|
000001f0 6e 00 42 4a 08 1c 9d 67 ba b4 70 ad d9 5f 62 ce |n.BJ...g..p.._b.|
00000200
root@debian:/tmp# dd if=./todecrypt.luks of=./dummy.luks bs=512 seek=4096 count=1
1+0 records in
1+0 records out
512 bytes (512 B) copied, 5.2223e-05 s, 9.8 MB/s
root@debian:/tmp# hexdump -C /dev/mapper/dummy.deluks
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000200
root@debian:/tmp#
That is correct, first 512 bytes of /dev/vda5 device -> are empty (00 in HEX).
One-liner commands would look as follows
root@debian:/tmp# dd if=/dev/vda bs=512 count=1 skip=$(( 501760+4096 )) status=noxfer of=./dummy.luks seek=4096 2>/dev/null && losetup -c /dev/loop1 && cryptsetup resize dummy.deluks && hexdump -C /dev/mapper/dummy.deluks |less
root@debian:/tmp# dd if=/dev/vda bs=512 count=1 skip=$(( 501760+4096+10053632 )) status=noxfer 2>/dev/null |dd bs=512 count=1 status=noxfer seek=4096 of=./dummy.luks 2>/dev/null && losetup -c /dev/loop1 && cryptsetup resize dummy.deluks && hexdump -C /dev/mapper/dummy.deluks |less
After many attempts trying to get the desired output (contents of test.txt file), I have found that the encryption/decryption is depending on the sector number where encrypted block is located.
Basically this is because encryption alogrithm AES is “supplied” by XTS block cipher mode.
You can learn more at the Block cipher-based modes wiki page.
Truncate dummy LUKS file (Remove everything after LUKS part that ends at 2MB point keep)
root@debian:/tmp# dd if=/dev/zero of=./dummy.luks bs=512 count=0 seek=4096 oflag=append
Add one block (512 bytes) to a dummy LUKS file so that it will be possible to luksOpen it
root@debian:/tmp# dd if=/dev/zero of=./dummy.luks bs=512 seek=4096 count=1
root@debian:/tmp# cryptsetup luksOpen /dev/loop1 dummy.deluks
Reading 512 block of encrypted test.txt and writing this block to LUKS dummy container, also keeping the same sector offset when writing.
root@debian:/tmp# dd if=/dev/vda bs=512 count=1 skip=$(( 501760+4096+10053632 + (8451*1024)/512 )) status=noxfer 2>/dev/null |dd bs=512 count=1 status=noxfer seek=$((4096+10053632 + (8451*1024)/512 )) of=./dummy.luks 2>/dev/null && losetup -c /dev/loop1 && cryptsetup resize dummy.deluks && dd bs=512 count=1 skip=$((10053632 + (8451*1024)/512)) if=/dev/mapper/dummy.deluks status=noxfer 2>/dev/null |hexdump -C
00000000 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 33 |1111111111111113|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000200
root@debian:/tmp# ls -la dummy.luks
-rw-r--r-- 1 root root 5158211584 Nov 2 07:55 dummy.luks
root@debian:/tmp# ls -lah dummy.luks
-rw-r--r-- 1 root root 4.9G Nov 2 07:55 dummy.luks
Voila! This proves that sector (which is 512bytes block) decryption was depending on the sector number that was kept in ‘seek=’ parameter to dd write command (of=./dummy.luks).
Below is one more confirmation that we have the only 1 encrypted block at the location 0x133740c00 = 5158210560 (decimal) relative to the beginning of the disk (/dev/vda). 512* (4096+10053632 + (8451*1024)/512) = 5158210560 bytes.
root@debian:/tmp# hexdump -C -s $((4096*512)) dummy.luks
00200000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
133740c00 38 59 ca b4 86 b3 aa 99 27 5f 5c 3b c0 6c 4c 3d |8Y......'_\;.lL=|
133740c10 85 a1 cf d4 99 b2 ec cc 35 db 8c c9 94 db 28 14 |........5.....(.|
133740c20 a1 46 a0 40 85 42 82 82 27 b1 99 89 25 b7 a1 c4 |.F.@.B..'...%...|
133740c30 55 57 de 53 47 5d a8 d8 fe 2f 37 7a 4b 8c 7f 41 |UW.SG].../7zK..A|
133740c40 b7 f9 ad 62 c8 49 0f 52 3b cd 7e 6a 39 89 ee 6a |...b.I.R;.~j9..j|
133740c50 98 d9 23 f0 cf 3b ce 79 4c 11 87 62 33 0e 96 29 |..#..;.yL..b3..)|
133740c60 7a 6f c2 25 50 eb 8f b8 b3 de 90 ba 97 b6 da b5 |zo.%P...........|
133740c70 91 a4 c5 cc ab d0 c9 0a 2d 1f 2d 88 a0 28 8c 32 |........-.-..(.2|
133740c80 15 f7 58 f0 aa cd 7f 50 01 55 23 f2 18 2f 90 6d |..X....P.U#../.m|
133740c90 7c 03 7f a0 32 68 66 1c 48 cd ce 5c 07 9b f7 71 ||...2hf.H..\...q|
133740ca0 80 fa 08 a8 2f 71 45 3d c0 f8 67 39 b4 96 10 ce |..../qE=..g9....|
133740cb0 72 60 a0 bd ae 37 b1 32 10 b1 7a 1c 76 53 f6 3f |r`...7.2..z.vS.?|
133740cc0 66 eb f8 96 3c 32 1e 18 4b a2 77 7e be 0d 8d bb |f...<2..K.w~....|
133740cd0 a5 99 97 54 6d 9e dc 4d 1d c2 0d ba 78 db ff ed |...Tm..M....x...|
133740ce0 44 8f 61 31 84 24 68 ab db 6a e7 9d 0a 44 a5 90 |D.a1.$h..j...D..|
133740cf0 c1 f8 28 bc e3 4c ac 5c 1f bd 7e a4 90 57 89 3a |..(..L.\..~..W.:|
133740d00 bb 90 3d c0 4b 7d a0 94 f5 1b 0a 12 c0 9e d9 d9 |..=.K}..........|
133740d10 f8 25 a7 0f 6b ca 73 57 90 e4 96 bd 26 b4 a4 ad |.%..k.sW....&...|
133740d20 28 7a 7c 69 d3 5a 8b a7 b4 f5 bf b8 a2 81 11 3d |(z|i.Z.........=|
133740d30 8a d0 c6 a5 3f 12 0e 6e 37 2d 30 c7 c0 c9 f9 70 |....?..n7-0....p|
133740d40 7f 13 45 ad 41 17 c4 96 8a 78 a5 4a da 61 3a fc |..E.A....x.J.a:.|
133740d50 75 96 5c 39 d3 46 3f cb 10 2b 1c a5 84 3a 61 d1 |u.\9.F?..+...:a.|
133740d60 44 37 67 4a a0 b4 44 70 b4 1a 86 45 4f be 1f 1b |D7gJ..Dp...EO...|
133740d70 4a 20 70 a8 40 3e 69 a0 a9 50 89 7e 70 f4 ab 73 |J p.@>i..P.~p..s|
133740d80 c7 b9 85 7b 3a 37 cd 0d 8a fc ad fc b4 13 c6 27 |...{:7.........'|
133740d90 41 64 f0 a9 95 89 10 c5 8c f0 5b 9b 44 b6 af ab |Ad........[.D...|
133740da0 ec 9a 20 3f b9 ce c1 f0 18 e4 1c 36 d6 8d b5 d8 |.. ?.......6....|
133740db0 5c 42 21 b0 57 e7 a8 76 85 a9 ff f2 39 f8 d4 39 |\B!.W..v....9..9|
133740dc0 ee 6a 4d db ad d6 ab ab f8 d6 3e 92 38 cf c9 58 |.jM.......>.8..X|
133740dd0 54 be 74 af 40 c0 9d 4d 98 75 b1 9e 20 6d 28 6b |T.t.@..M.u.. m(k|
133740de0 ec 71 5a ff 39 3a cb dd 37 7f aa 73 c9 13 d4 9e |.qZ.9:..7..s....|
133740df0 d1 8a 1f cc c0 a3 d6 a7 41 f8 ae 3e a4 8e 46 88 |........A..>..F.|
133740e00 28 4b 6d 2a df ea ca 76 0c f2 45 25 c6 90 6b 06 |(Km*...v..E%..k.|
133740e10 9a e8 f3 95 d7 2c 3e 78 08 c1 0a 7c 92 9a 40 b2 |.....,>x...|..@.|
133740e20 d7 a7 c4 f9 8c aa 31 81 23 a7 e4 df f7 23 96 fd |......1.#....#..|
133740e30 3c ae 2a de c8 c9 9c 39 75 16 65 a9 52 6e 50 00 |<.*....9u.e.RnP.|
133740e40 8a 7a f9 df a5 85 29 be 18 7a b9 3f 97 85 0a c3 |.z....)..z.?....|
133740e50 ca 2c 2e d6 4c 5f 03 2a 91 0f ee 5b 08 f4 bc 00 |.,..L_.*...[....|
133740e60 96 66 5e 80 eb ea a3 69 c2 16 03 61 24 5d ae d5 |.f^....i...a$]..|
133740e70 e3 bc 6a 8e 92 9b c6 82 06 2f 6b aa f6 87 00 08 |..j....../k.....|
133740e80 8d 0c f4 4f a7 ec 19 e3 5b b4 4b 31 84 8e a9 6f |...O....[.K1...o|
133740e90 7d 37 bc c9 26 3d 39 b5 5c 7f 43 aa ca 54 d3 5a |}7..&=9.\.C..T.Z|
133740ea0 9a d3 10 0c 4b cc bb 68 ff 86 86 cc a7 18 fc 37 |....K..h.......7|
133740eb0 c4 67 0e 98 4d 93 3e 1c 92 8b 22 11 fd be 5b 0b |.g..M.>..."...[.|
133740ec0 9b 2f 81 0a d0 db 83 3e 55 23 d8 03 a0 21 c1 c2 |./.....>U#...!..|
133740ed0 f0 6f a4 ef c5 55 63 37 f2 4c 4c 03 54 5c e6 8b |.o...Uc7.LL.T\..|
133740ee0 d1 9b 59 9e 76 38 cd 93 5a 31 3f a5 d6 4d cc d2 |..Y.v8..Z1?..M..|
133740ef0 a8 09 88 ad 49 ce 2f 13 07 42 86 b1 07 5f 9c 33 |....I./..B..._.3|
133740f00 24 7b a9 cb 1c 68 d5 4a 8f 91 aa 9f c1 f1 3a cf |${...h.J......:.|
133740f10 d7 0a 5e 2b a7 63 35 76 d9 3a 5f 95 72 bf 54 7b |..^+.c5v.:_.r.T{|
133740f20 f4 e4 d0 e3 02 40 95 e8 f5 28 13 ab 91 d9 6a 10 |.....@...(....j.|
133740f30 2d 45 ba 3f d3 d1 a4 d5 cf 80 e0 7f 05 81 62 c7 |-E.?..........b.|
133740f40 7c 0d f9 3a 16 0e d6 02 0c 53 15 0e ab 2b 5f 9c ||..:.....S...+_.|
133740f50 56 0c 50 ec d1 d4 1f 4f 62 48 bb 2d 72 af b2 ca |V.P....ObH.-r...|
133740f60 8d 80 3e d6 4e 81 12 d3 04 63 cb 95 4a 29 0d 6b |..>.N....c..J).k|
133740f70 65 b3 73 eb 59 ae 96 c7 72 0b 4d 1a b2 ac e2 0f |e.s.Y...r.M.....|
133740f80 be 8d c4 16 c6 1c 03 f9 cd 3c 6c 96 03 56 ef e1 |.........<l..V..|
133740f90 75 90 89 c7 a2 1f 43 dc 0a e2 a0 0a fb 1c f1 05 |u.....C.........|
133740fa0 e5 0e a8 71 42 de 11 6e a5 60 26 57 10 04 b9 7c |...qB..n.`&W...;||
133740fb0 79 bf fd 5f 5e c8 e4 cb 09 16 6b 8d 30 67 0c 0f |y.._^.....k.0g..|
133740fc0 fb 53 a5 b2 ec 6c b1 c2 cd 25 37 1f 12 a6 a3 b2 |.S...l...%7.....|
133740fd0 98 af 1d 03 5c a0 b2 2d f9 fc e3 8b 51 0b 16 a8 |....\..-....Q...|
133740fe0 65 1a c5 97 9f df 82 e2 2c bf 0f ba 6b 03 b9 af |e.......,...k...|
133740ff0 42 99 3f b0 11 62 19 0c 57 df d0 a8 a8 65 71 46 |B.?..b..W....eqF|
133741000
Extra test, trying to alter the test.txt file by adding a number “4” to the end of it.
root@debian:/tmp# printf 4 |dd of=./test.txt count=1 bs=1 seek=15 status=noxfer
1+0 records in
1+0 records out
root@debian:/tmp# filefrag -bsv ./test.txt
Filesystem type is: ef53
File size of ./test.txt is 16 (1 block, blocksize 1024)
ext logical physical expected length flags
0 0 8451 1 eof
./test.txt: 1 extent found
root@debian:/tmp# hexdump -C ./test.txt
00000000 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 34 |1111111111111114|
00000010
root@debian:/tmp# dd if=/dev/vda bs=512 count=1 skip=$(( 501760+4096+10053632 + (8451*1024)/512 )) status=noxfer 2>/dev/null |dd bs=512 count=1 status=noxfer seek=$((4096+10053632 + (8451*1024)/512 )) of=./dummy.luks 2>/dev/null && losetup -c /dev/loop1 && cryptsetup resize dummy.deluks && dd bs=512 count=1 skip=$((10053632 + (8451*1024)/512)) if=/dev/mapper/dummy.deluks status=noxfer 2>/dev/null |hexdump -C
00000000 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 33 |1111111111111113|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000200
root@debian:/tmp# sync && mount -o remount /tmp && echo 1 | tee /proc/sys/vm/drop_caches1
root@debian:/tmp# dd if=/dev/vda bs=512 count=1 skip=$(( 501760+4096+10053632 + (8451*1024)/512 )) status=noxfer 2>/dev/null |dd bs=512 count=1 status=noxfer seek=$((4096+10053632 + (8451*1024)/512 )) of=./dummy.luks 2>/dev/null && losetup -c /dev/loop1 && cryptsetup resize dummy.deluks && dd bs=512 count=1 skip=$((10053632 + (8451*1024)/512)) if=/dev/mapper/dummy.deluks status=noxfer 2>/dev/null |hexdump -C
00000000 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 34 |1111111111111114|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000200
In the end of tests do not forget to dismount encrypted LUKS dummy device and sanitize the master key if it is important for you.
root@debian:/tmp# cryptsetup luksClose dummy.deluks
root@debian:/tmp# losetup -d /dev/loop1
root@debian:/tmp# shred -uvz master.key
root@debian:/tmp# rm ./dummy.luks ./todecrypt.luks