嵌入式 ARM 平台使用dm-crypt加密磁盘分区
By Toradex秦海
1). 簡介
出于安全考慮,嵌入式設備有時需要將某個數(shù)據(jù)分區(qū)甚至整個文件系統(tǒng)進行加密處理,本文就介紹在嵌入式Linux系統(tǒng)下基于dm-crypt進行加密示例,dm-crypt加密具有速度快,易用性強,適用性廣等特點,dm-crypt集成于linux kernel中,通過前端應用cryptsetup來進行調用。
?
本文演示所使用的ARM平臺來自Toradex基于NXP iMX6Q SoC平臺的Apalis iMX6 ARM核心板。
?
?
2). 準備
a). Apalis iMX6Q ARM核心版配合Apalis Evaluation Board載板,連接調試串口UART1(載板X29)到開發(fā)主機方便調試。更多關于Apalis iMX6配合Apalis Evaluation Board載板的說明請參考Datasheet和開發(fā)上手指南。
?
b). 開發(fā)Linux PC主機, 用于搭建Ycoto Project/OpenEmbedded 編譯環(huán)境,方便編譯針對Apalis iMX6Q的集成所需功能的測試Linux image。
?
?
3). 編譯集成dm-crypt的Linux image
a). 首先根據(jù)下面文章的描述在Linux開發(fā)主機上面配置Ycoto Project/OpenEmbedded編譯環(huán)境
https://developer.toradex.cn/knowledge-base/board-support-package/openembedded-(core)
?
本文配置使用 LinuxImageV2.8 分支。
?
b). 配置Linux kernel,增加dm-crypt的支持
-----------------------
$ cd oe-core/build
$ make -c menuconfig virtual/kernel
?
Device Drivers? --->
[*] Multiple devices driver support (RAID and LVM)? --->
<*>?? Device mapper support
[*]???? Device mapper debugging support
<*>???? Crypt target support
?
-*- Cryptographic API? --->
<*>?? User-space interface for hash algorithms
<*>?? User-space interface for symmetric key cipher algorithms
<*>?? User-space interface for random number generator algorithms
<*>?? User-space interface for AEAD cipher algorithms
?
$ bitbake virtual/kernel -f -c deploy
$ bitbake virtual/kernel -f -c compile
-----------------------
?
c). 修改配置文件以增加所需要的安裝包
./ conf/local.conf 文件
https://github.com/simonqin09/crypt_test/blob/master/local.conf.patch
./ layers/meta-openembedded/meta-oe/recipes-support/lvm2/libdevmapper_2.02.171.bb 文件
https://github.com/simonqin09/crypt_test/blob/master/libdevmapper.patch
d). 編譯部署image
./ 執(zhí)行下面命令編譯 Linux image
-----------------------
$ bitbake -k angstrom-lxde-image
-----------------------
./ 編譯成功的image位于 ../deploy/images/apalis-imx6/ 目錄,參考這里的說明將linux image更新到Apalis iMX6模塊上
?
?
4). 測試加密數(shù)據(jù)分區(qū)(非rootfs啟動分區(qū))
a). 進入上一步驟更新好的Apalis iMX6 Linux系統(tǒng)串口終端,首先準備用于加密的分區(qū),可以是實際的物理分區(qū)(如外部USB盤,SD卡或者sata硬盤等),也可以通過 dd 命令在現(xiàn)有eMMC Linux 分區(qū)上面創(chuàng)建一個分區(qū)塊,其后續(xù)加密操作都是類似的,本文就以后者作為演示。
?
b). 具體操作流程如下:
-----------------------
# 在 $HOME 目錄下創(chuàng)建用于測試的分區(qū)塊,100MB容量
root@apalis-imx6:~# cd /home/root/
root@apalis-imx6:~# dd if=/dev/urandom of=test.luks bs=1M count=100
?
# 創(chuàng)建加密分區(qū),這里會要求設置加密密碼,如果需要調試,可以增加 --debug 調試參數(shù)
root@apalis-imx6:~# cryptsetup luksFormat test.luks
?
WARNING!
========
This will overwrite data on test.luks irrevocably.
?
Are you sure? (Type uppercase yes): YES
Enter passphrase:
Verify passphrase:
?
# 可選操作:如果想要實現(xiàn)自動通過腳本掛載,則需要配置 key 文件,并添加到加密分區(qū)
root@apalis-imx6:~# dd if=/dev/urandom of=key bs=1024 count=4
root@apalis-imx6:~# cryptsetup luksAddKey test.luks key
Enter any existing passphrase:
?
# 打開加密分區(qū)
// 手動方式,需要手動輸入并驗證密碼
root@apalis-imx6:~# cryptsetup luksOpen test.luks testvolume
Enter passphrase for test.luks:
// 通過 key 文件自動方式
root@apalis-imx6:~# cryptsetup luksOpen --key-file key test.luks testvolume
?
# 格式化加密分區(qū)
root@apalis-imx6:~# mkfs.ext4 -j /dev/mapper/testvolume
mke2fs 1.43.5 (04-Aug-2017)
Creating filesystem with 100352 1k blocks and 25168 inodes
Filesystem UUID: db13767e-9057-48f2-9908-31a14ec6d02c
Superblock backups stored on blocks:
??????? 8193, 24577, 40961, 57345, 73729
?
Allocating group tables: done???????????????????????????
Writing inode tables: done???????????????????????????
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done
?
# 掛載加密分區(qū)
root@apalis-imx6:~# mkdir /mnt/test
root@apalis-imx6:~# mount /dev/mapper/testvolume /mnt/test/
?
# 然后就可以進入 /mnt/test/ 對加密分區(qū)進行操作,操作完成后,解除掛載并關閉加密分區(qū)
root@apalis-imx6:/# umount /mnt/test
root@apalis-imx6:/# cryptsetup luksClose testvolume
-----------------------
?
?
5). 測試加密 Rootfs 啟動分區(qū)
a). 由于Uboot下無法完成對加密啟動分區(qū)的解密,因此我們需要準備一個最小啟動initramfs鏡像,uboot加載initramfs啟動后再解密并掛載rootfs啟動分區(qū),最后切換到這個啟動分區(qū)來完成整個啟動過程
?
b). 首先還是通過之前配置好的Ycoto環(huán)境編譯所需的initramfs鏡像
-----------------------
# 配置busybox,增加 --install 和 mdev 支持
./ 添加 fragment.cfg 文件到 layers/openembedded-core/meta/recipes-core/busybox/busybox/ 目錄,內容如下:
https://github.com/simonqin09/crypt_test/blob/master/fragment.cfg
./ 如下修改 layers/openembedded-core/meta/recipes-core/busybox/busybox_1.24.1.bb 文件
https://github.com/simonqin09/crypt_test/blob/master/busybox.patch
./ 如下修改 layers/meta-openembedded/meta-initramfs/recipes-bsp/images/initramfs-debug-image.bb 文件
https://github.com/simonqin09/crypt_test/blob/master/initramfs-debug-image.patch
?
# 編譯 initramfs image
$ cd build
$ bitbake -k initramfs-debug-image
-----------------------
?
c). 添加 key 文件到initramfs image中
-----------------------
# 從生成目錄將 initramfs image文件復制到PC的工作目錄
$ mkdir work-dir
$ cd work-dir
$ cp deploy/images/apalis-imx6/Angstrom-initramfs-debug-image-glibc-ipk-v2017.12-apalis-imx6.rootfs.cpio.gz .
?
# 解壓cpio.gz文件,并生成隨機內容的key文件,為后面加密rootfs啟動分區(qū)使用
$ mkdir temp
$ cd temp
$ gunzip -c ../Angstrom-initramfs-debug-image-glibc-ipk-v2017.12-apalis-imx6.rootfs.cpio.gz | cpio -i
$ dd if=/dev/urandom of=key bs=1024 count=4
?
# 重新壓縮為 cpio.gz 文件
$ find . | cpio -H newc -o | gzip -9 > ../initramfs.cpio.gz
?
# 將生成的 cpio.gz 文件轉換為 uboot 可用的initramfs image
$ cd ..
$ mkimage -A arm -O linux -T ramdisk -n "Initial Ram Disk" -d initramfs.cpio.gz initramfs.img
-----------------------
?
d). 將生成的 initramfs.img 文件復制到FAT32分區(qū)的SD卡上面,連接到Apalis iMX6底板X18 8bit SD插槽。啟動Apalis iMX6模塊,進入 uboot 命令行,將 initramfs image文件復制到 iMX6 boot 分區(qū)并修改啟動參數(shù)
-----------------------
# 復制 initramfs image到boot分區(qū)
Apalis iMX6 # mmc rescan
Apalis iMX6 # load mmc 1:1 ${ramdisk_addr_r} initramfs.img
Apalis iMX6 # fatwrite mmc 0:1 ${ramdisk_addr_r} initramfs.img ${filesize}
?
# 修改啟動環(huán)境變量
Apalis iMX6 # setenv boot_initfs ‘run load_initramfs_files && bootm ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}’
Apalis iMX6 # setenv load_initramfs_files ‘load mmc 0:1 ${fdt_addr_r} ${fdt_file}; load mmc 0:1 ${ramdisk_addr_r} initramfs.img; load mmc 0:1 ${kernel_addr_r} ${boot_file}’
Apalis iMX6 # setenv bootcmd ‘run boot_initfs; echo; echo initramfs_failed; run emmcboot ; echo ; echo emmcboot failed ; run nfsboot ; echo ; echo nfsboot failed ; usb start ;setenv stdout serial,vga ; setenv stdin serial,usbkbd’
Apalis iMX6 # saveenv
-----------------------
?
e). 重新啟動后,系統(tǒng)會加載到initramfs環(huán)境下,然后進行對rootfs 分區(qū)進行加密操作
-----------------------
# 加密并掛載 rootfs 分區(qū) /dev/mmcblk0p2
/ # cryptsetup luksFormat /dev/mmcblk0p2
/ # cryptsetup --debug luksAddKey /dev/mmcblk0p2 key
/ # cryptsetup luksOpen --key-file key /dev/mmcblk0p2 rootfs
/ # mke2fs -t ext4 /dev/mapper/rootfs
/ # mkdir -p /mnt/rootfs
/ # mount /dev/mapper/rootfs /mnt/rootfs
?
# 將rootfs 文件復制到加密啟動分區(qū)
./ 首先將前面章節(jié)3生成的Linux image文件 Apalis-iMX6_LXDE-Image-Tezi_2.8b6-2019xxxx.tar 解壓,并提取 rootfs壓縮包到FAT32 SD卡
$ tar xvf Apalis-iMX6_LXDE-Image-Tezi_2.8b6-2019xxxx.tar
$ cd Apalis-iMX6_LXDE-Image-Tezi_2.8b6
$ cp Apalis-iMX6_LXDE-Image.rootfs.tar.xz /media/sd (SD卡掛載目錄)
./ 然后將SD卡連接到 Apalis iMX6進行掛載
mkdir /mnt/sd
/ # mount -t vfat /dev/mmcblk1p1 /mnt/sd
./ 最后將SD卡里面的rootfs文件系統(tǒng)壓縮包解壓到剛才創(chuàng)建并掛載的加密啟動分區(qū)中
/ # cd /mnt/rootfs
/ # tar Jxf /mnt/sd/Apalis-iMX6_LXDE-Image.rootfs.tar.xz
?
# 卸載并關閉加密啟動分區(qū)
/ # umount /mnt/rootfs
/ # cryptsetup luksClose rootfs
-----------------------
?
f). 為了實現(xiàn)在 initramfs 環(huán)境下實現(xiàn)自動解密rootfs啟動分區(qū)并切換到啟動分區(qū)加載啟動,需要修改 initramfs image的 init腳本文件
-----------------------
# 重新解壓上面操作 c 添加 key文件后生成的 initramfs cpio.gz文件
$ mkdir temp
$ cd temp
$ gunzip -c ../ initramfs.cpio.gz | cpio -i
?
# 替換 init 文件為如下內容
https://github.com/simonqin09/crypt_test/blob/master/init.mod
?
# 重新壓縮并轉換為 uboot 可用的文件
$ find . | cpio -H newc -o | gzip -9 > ../initramfs-new.cpio.gz
$ cd ..
$ mkimage -A arm -O linux -T ramdisk -n "Initial Ram Disk" -d initramfs-new.cpio.gz initramfs.img
-----------------------
?
g). 和上述操作 d 同樣方法將新的 initramfs.img 文件復制到Apalis iMX6 boot分區(qū)后重新啟動,系統(tǒng)會正常啟動到最初的文件系統(tǒng)了,然后就可以繼續(xù)進行其他操作了。
-----------------------
U-Boot 2016.11-2.8.6+g83a53c1 (Jul 29 2019 - 04:51:51 +0000)
?
CPU:?? Freescale i.MX6Q rev1.5 at 792 MHz
Reset cause: POR
I2C:?? ready
DRAM:? 2 GiB
…
Hit any key to stop autoboot:? 0
reading imx6q-apalis-eval.dtb
54620 bytes read in 18 ms (2.9 MiB/s)
reading initramfs-key.img
4455676 bytes read in 147 ms (28.9 MiB/s)
reading zImage
5483824 bytes read in 163 ms (32.1 MiB/s)
## Loading init Ramdisk from Legacy Image at 12200000 ...
?? Image Name:?? Initial Ram Disk
?? Image Type:?? ARM Linux RAMDisk Image (gzip compressed)
?? Data Size:??? 4455612 Bytes = 4.2 MiB
…
Starting kernel ...
…
[??? 3.918790] Freeing unused kernel memory: 1024K
[??? 4.023894] hub 1-1.1:1.0: USB hub found
[??? 4.028022] hub 1-1.1:1.0: 4 ports detected
[??? 8.736558] EXT4-fs (dm-0): couldn't mount as ext3 due to feature incompatibilities
[??? 8.744787] EXT4-fs (dm-0): couldn't mount as ext2 due to feature incompatibilities
[??? 8.895730] EXT4-fs (dm-0): recovery complete
[??? 8.900834] EXT4-fs (dm-0): mounted filesystem with ordered data mode. Opts: (null)
[??? 9.345988] systemd[1]: System time before build time, advancing clock.
[??? 9.415901] systemd[1]: systemd 234 running in system mode. (+PAM -AUDIT -SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP -LIBCRYPTSETUP -GCRYPT -GN)
[??? 9.437154] systemd[1]: Detected architecture arm.
…
The Angstrom Distribution apalis-imx6 ttymxc0
?
Angstrom v2017.12 - Kernel
?
Apalis-iMX6_LXDE-Image 2.8b6 20190801
?
apalis-imx6 login:
-----------------------
?
?
6). 總結
本文示例了基于ARM嵌入式平臺在嵌入式Linux系統(tǒng)下通過 dm-crypt 來加密磁盤,以便對相關數(shù)據(jù)進行保護。
總結
以上是生活随笔為你收集整理的嵌入式 ARM 平台使用dm-crypt加密磁盘分区的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 全国计算机等级考试二级c真题201903
- 下一篇: cxp文件查看 欧姆龙_cxp格式怎么打