Sunday, December 3, 2023

dm-integrity, dm-crypt, luks

Build dm-integrity for RPI

dm-integrity was not included in my Raspian kernel, built as per -

https://www.raspberrypi.com/documentation/computers/linux_kernel.html

and load (as a module)

dm-integrity (no encryption)

Create an image file as backing for a loop device

$ dd if=/dev/zero of=./file.img bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 2.28869 s, 45.8 MB/s

Create the loop device

$ sudo losetup --find --show ./file.img
/dev/loop0

Create key, format, open using integrity setup

$ dd if=/dev/urandom bs=32 count=1 of=./keyfile

$ sudo integritysetup format /dev/loop0 --tag-size 32 --integrity hmac-sha256 --integrity-key-file ./keyfile --integrity-key-size 32 --batch-mode

$ sudo integritysetup open /dev/loop0 testinteg --integrity hmac-sha256 --integrity-key-file ./keyfile --integrity-key-size 32 --batch-mode

$ sudo integritysetup status testinteg
/dev/mapper/testinteg is active.
  type:    INTEGRITY
  tag size: 32
  integrity: hmac(sha256)
  device:  /dev/loop0
  loop:    /home/pi/dm-integrity/file.img
  sector size:  512 bytes
  interleave sectors: 32768
  size:    190920 sectors
  mode:    read/write
  failures: 0
  journal size: 811008 bytes
  journal watermark: 50%
  journal commit time: 10000 ms

$ lsblk /dev/loop0
NAME        MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINT
loop0         7:0    0  100M  0 loop
└─testinteg 254:0    0 93.2M  0 crypt

Format with ext4, mount, test

$ sudo mkfs.ext4 /dev/mapper/testinteg 
$ sudo mkdir /mnt/testinteg 
$ sudo mount /dev/mapper/testinteg /mnt/testinteg 

Create a test file

$ sudo dd if=/dev/zero of=/mnt/testinteg/zero bs=1M count=50
$ sudo hexdump /mnt/testinteg/zero
0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
3200000

Tamper

$ dd if=/dev/random of=./file.img bs=1 seek=40M count=512
$ sudo umount /mnt/testinteg
$ sudo integritysetup close testinteg

Remount and check

$ sudo integritysetup open /dev/loop0 testinteg --integrity hmac-sha256 --integrity-key-file ./keyfile --integrity-key-size 32 --batch-mode

$ dmesg |tail
[  514.542274] device-mapper: integrity: dm-0: Checksum failed at sector 0x2e900
[  514.542773] device-mapper: integrity: dm-0: Checksum failed at sector 0x2e900
[  514.542802] Buffer I/O error on dev dm-0, logical block 23840, async page read

$ sudo integritysetup status testinteg
/dev/mapper/testinteg is active.
  type:    INTEGRITY
  tag size: 32
  integrity: hmac(sha256)
  device:  /dev/loop0
  loop:    /home/pi/dm-integrity/file.img
  sector size:  512 bytes
  interleave sectors: 32768
  size:    190920 sectors
  mode:    read/write
  failures: 2
  journal size: 811008 bytes
  journal watermark: 50%
  journal commit time: 10000 ms

dm-integrity finds the 'corrupt' data when mapping

$ sudo fsck.ext4 -a /dev/mapper/testinteg 
$ sudo mount /dev/mapper/testinteg /mnt/testinteg 
$ sudo hexdump /mnt/testinteg/zero
0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
hexdump: /mnt/testinteg/zero: Input/output error
01bf800

dm-crypt (no integrity)

Create key and format, open using cryptsetup

$ dd if=/dev/urandom bs=32 count=1 of=./keyfile

$ sudo cryptsetup luksFormat --type luks2 /dev/loop1 --cipher aes-xts-plain64 --key-file ./keyfile --batch-mode
$ sudo cryptsetup open /dev/loop1 testcrypt --key-file ./keyfile

$ sudo cryptsetup status testcrypt
/dev/mapper/testcrypt is active and is in use.
  type:    LUKS2
  cipher:  aes-xts-plain64
  keysize: 512 bits
  key location: keyring
  device:  /dev/loop1
  loop:    /home/pi/luks2wip/file.img
  sector size:  512
  offset:  32768 sectors
  size:    172032 sectors
  mode:    read/write

$ lsblk /dev/loop1
NAME        MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINT
loop1         7:1    0  100M  0 loop
└─testcrypt 254:0    0   84M  0 crypt

Format with ext4, mount, test

$ sudo mkfs.ext4 /dev/mapper/testcrypt
$ sudo mkdir /mnt/testcrypt
$ sudo mount /dev/mapper/testcrypt /mnt/testcrypt
$ sudo umount /mnt/testcrypt

Unmount

$ sudo cryptsetup close testcrypt
$ file file.img
file.img: LUKS encrypted file, ver 2 [, , sha256] UUID: 3f01b422-6a29-4d58-a9f4-ffbe992790b6

Tamper and check

$ dd if=/dev/zero of=./file.img bs=1 seek=40M count=1
$ sudo cryptsetup open /dev/loop1 testcrypt --key-file ./keyfile
$ sudo fsck.ext4 -a /dev/mapper/testcrypt
$ sudo mount /dev/mapper/testcrypt /mnt/testcrypt

dm-integrity + dm-crypt


Create key and format, open using cryptsetup

$ dd if=/dev/urandom bs=32 count=1 of=./keyfile

$ sudo cryptsetup luksFormat --type luks2 /dev/loop2 --cipher aes-xts-plain64 --integrity hmac-sha256 --key-file ./keyfile --batch-mode

$ sudo cryptsetup open /dev/loop2 testintegcrypt --key-file ./keyfile

$ sudo cryptsetup status testintegcrypt
/dev/mapper/testintegcrypt is active.
  type:    LUKS2
  cipher:  aes-xts-plain64
  keysize: 768 bits
  key location: keyring
  integrity: hmac(sha256)
  integrity keysize: 256 bits
  device:  /dev/loop2
  loop:    /home/pi/dm-integ-crypt/file.img
  sector size:  512
  offset:  0 sectors
  size:    160200 sectors
  mode:    read/write

$ lsblk /dev/loop2
NAME                 MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINT
loop2                  7:2    0  100M  0 loop
└─testintegcrypt_dif 254:1    0 78.2M  0 crypt
  └─testintegcrypt   254:2    0 78.2M  0 crypt

Format with ext4, mount, test

$ sudo mkfs.ext4 /dev/mapper/testintegcrypt
$ sudo mkdir /mnt/testintegcrypt
$ sudo mount /dev/mapper/testintegcrypt /mnt/testintegcrypt

Create a test file

$ sudo dd if=/dev/zero of=/mnt/testintegcrypt/zero bs=1M count=50
$ sudo hexdump /mnt/testintegcrypt/zero
0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
3200000

Unmount

$ sudo umount /mnt/testintegcrypt
$ sudo cryptsetup close testintegcrypt

Tamper and check

$ dd if=/dev/random of=./file.img bs=1 seek=40M count=512

$ sudo cryptsetup open /dev/loop2 testintegcrypt --key-file ./keyfile

The 'corrupt' data isn't found until it is accessed

$ sudo fsck.ext4 -a /dev/mapper/testintegcrypt
Error reading block 32769 (Input/output error).

/dev/mapper/testintegcrypt: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.
        (i.e., without -a or -p options)

$ sudo mount /dev/mapper/testintegcrypt /mnt/testintegcrypt
$ sudo hexdump /mnt/testintegcrypt/zero
0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
hexdump: /mnt/testintegcrypt/zero: Input/output error
0b38000