| 241 | |
| 242 | |
| 243 | [=#dmcrypt] |
| 244 | == Secure filesystem with dm_crypt |
| 245 | Linux dm-crypt is a transparent disk encryption sybsystem. It is part of the device mapper infrastructure and uses the kernel crypto API. Being implemented at the device mapper layer means it can be stacked on top of other devices or even other device mappers thus it can be used to encrypted whole disks, partitions, software RAID volumes, and logical volumes. Linux Unified Key Step (LUKS) is the format used on the device in place of a file system which provides a whole host of key options. |
| 246 | |
| 247 | Kernel requirements for dm-crypt: |
| 248 | - CONFIG_MD (RAID and LVM) |
| 249 | - CONFIG_BLK_DEV_DM (device-mapper) |
| 250 | - CONFIG_DM_CRYPT (dm-crypt) |
| 251 | - CONFIG_CRYPTO_* options for various cipher/hash you want to use, for example: |
| 252 | - CONFIG_CRYPTO_XTS |
| 253 | - CONFIG_ARM64_CRYPTO |
| 254 | - CONFIG_CRYPTO_SHA1_ARM64_CE |
| 255 | - CONFIG_CRYPTO_SHA2_ARM64_CE |
| 256 | - CONFIG_CRYPTO_SHA512_ARM64_CE |
| 257 | - CONFIG_CRYPTO_AES_ARM64_CE_CCM |
| 258 | - CONFIG_CRYPTO_AES_ARM64_CE_BLK |
| 259 | - CONFIG_CRYPTO_USER_API_HASH |
| 260 | - CONFIG_CRYPTO_USER_API_SKCIPHER |
| 261 | |
| 262 | Userspace requirements for dm-crypt: |
| 263 | - cryptsetup (Buildroot BR2_PACKAGE_CRYPTSETUP) |
| 264 | |
| 265 | For more info: |
| 266 | - https://en.wikipedia.org/wiki/Dm-crypt |
| 267 | |
| 268 | Example: |
| 269 | 1. Create a key to use for encryption: |
| 270 | {{{#!bash |
| 271 | dd if=/dev/urandom of=$KEY_DIR/fs.key bs=1 count=4096 |
| 272 | }}} |
| 273 | 1. Boot a Linux provisioning kernel+ramdisk such as the prebuilt images at http://dev.gateworks.com/buildroot/ (see wiki:buildroot) |
| 274 | 1. Create encrypted device using dm-crypt |
| 275 | {{{#!bash |
| 276 | # get key file, ie via network |
| 277 | ifconfig eth0 192.168.1.20 |
| 278 | cd /tmp |
| 279 | wget http://server/fs.key |
| 280 | # format a LUKS device |
| 281 | echo "YES" | cryptsetup luksFormat /dev/mmcblk0p1 fs.key - |
| 282 | }}} |
| 283 | * use 'cryptsetup benchmark' to show all cipher and hash algos available in your running kernel as well as their performance |
| 284 | * use 'cryptsetup --help' to see options; options you may wish to change are --cipher (default aes-xts-plain64), --key-size (default is 256) --hash (default is sha256) and --use-urandom (default is --use-random) |
| 285 | 1. Open (unlock) the LUKS device |
| 286 | {{{#!bash |
| 287 | # open (unlock) LUKS device and map it to /dev/mapper/rootfs |
| 288 | cryptsetup luksOpen /dev/mmcblk0p1 rootfs --key-file=fs.key |
| 289 | }}} |
| 290 | 1. Create your filesystem: |
| 291 | {{{#!bash |
| 292 | wget http://server/rootfs.tar.xz |
| 293 | mkfs.ext4 -q -F -L rootfs /dev/mapper/rootfs |
| 294 | mount /dev/mapper/rootfs /mnt |
| 295 | tar -C /mnt -xf rootfs.tar.xz --keep-directory-symlink |
| 296 | umount /dev/mapper/rootfs |
| 297 | }}} |
| 298 | 1. Close (lock) LUKS device |
| 299 | {{{#!bash |
| 300 | cryptsetup luksClose rootfs |
| 301 | }}} |
| 302 | 1. Create a simple initramdisk responsible for unlocking dm-crypt via buildroot: |
| 303 | {{{#!bash |
| 304 | cat <<EOF >output/target/init |
| 305 | #!/bin/sh |
| 306 | |
| 307 | # Mount things needed by this script |
| 308 | mount -n -t devtmpfs devtmpfs /dev |
| 309 | mount -n -t proc proc /proc |
| 310 | mount -n -t sysfs sysfs /sys |
| 311 | mount -n -t tmpfs tmpfs /run |
| 312 | |
| 313 | init="/sbin/init" |
| 314 | root="mmcblk0p1" |
| 315 | key=/fs.key |
| 316 | |
| 317 | # Wait for device to exist |
| 318 | echo "Waiting for /dev/${root}..." |
| 319 | while [ ! -b "/dev/${root}" ]; do |
| 320 | sleep 1 |
| 321 | echo -n . |
| 322 | done |
| 323 | |
| 324 | #Open encrypted partition |
| 325 | mkdir -p /run/cryptsetup |
| 326 | echo "Opening /dev/$root..." |
| 327 | cryptsetup luksOpen "/dev/${root}" "${root}" --key-file=$key |
| 328 | |
| 329 | #Mount the root device |
| 330 | echo "Mounting /dev/mapper/${root}..." |
| 331 | mkdir /newroot |
| 332 | mount "/dev/mapper/${root}" /newroot |
| 333 | |
| 334 | #Switch to the new root and execute init |
| 335 | echo "Switching to new root..." |
| 336 | cd /newroot |
| 337 | exec switch_root . "${init}" "$@" |
| 338 | |
| 339 | #This will only be run if the above line failed |
| 340 | echo "Failed to switch_root" |
| 341 | EOF |
| 342 | chmod +x output/target/init |
| 343 | }}} |
| 344 | 1. Create a FIT image (see above) containing your kernel fdt and initramfs and boot it with boom or built it as a kernel+ramdisk |