device-mapper crypto not working on Volla Phone
-
Hi,
I've been unsuccessfully trying to encrypt parts of the home directory on my phone. It seems that device-mapper crypto is not working on the Volla phone, albeit the kernel looking like having the rudimentary dm-crypt support compiled in.
I started with example commands from this post, and then tried to get to the root of the problem by using lower level APIs. cryptsetup does not work at all. I'm now playing with dmsetup, as that allows more low-level interfacing to the device-mapper.
I would expect, that the following commands would create a very minmal (and unsecure) device-mapper crypto mapping on my volla phone (running this via ssh, sudo -i):
dd if=/dev/zero of=/home/phablet.img bs=1024 count=128 conv=excl LODEV=$(losetup --find --show -r /home/phablet.img) echo "0 128 crypt aes-ecb 0123456789abcdef0123456789abcdef 0 $LODEV 0" | dmsetup create crypt2
However dmsetup fails with error:
device-mapper: reload ioctl on crypt2 failed: Operation not permitted
Using strace to look at the root cause, it fails at ioctl
ioctl(3, DM_TABLE_LOAD, 0x607b2412e0) = -1 EPERM (Operation not permitted)
If I use target "linear" instead of target "crypt", dmsetup does work, so the device-mapper and dmsetup are not totally broken.
The kernel on Volla phone is:
Linux ubuntu-phablet 4.4.146+ #47 SMP PREEMPT Mon Mar 8 05:16:13 CET 2021 aarch64 aarch64 aarch64 GNU/Linux
According to /proc/config.gz, it does have the relevant options enabled:
CONFIG_DM_CRYPT=y CONFIG_CRYPTO_AES=y
What am I missing? The commands above work flawlessly on my Debian desktop PC. Anybody knows what other kernel options are required to make dm-crypt work? Is /proc/config.gz maybe lying about how the kernel was actually compiled? Is this a problem about user-space dmsetup not being compatible with the kernel in question?
cheers,
Dave
-
Replying to myself, I started reading in the original Volla phone kernel sources. Looking at dm-crypt.c it seems that it has patches that add some very specific (and broken) hacks to accommodate Mediatek hardware encryption (everything that depends on CONFIG_MTK_HW_FD which is set on the Volla's phone kernel).
This function seems to be the culprit. It escapes me how anybody could throw this kind of hack into a production kernel:
/* * MTK PATCH: * * Get storage device type (for hw fde on/off decision) * or id (for crypt_config). * * Returns: * 0: Embedded storage, for example: eMMC or UFS. * 1: External storage, for example: SD card. * -1: Unrecognizable storage. */ static int crypt_dev_id(const char *path) { int type = -1; if (strstr(path, "bootdevice")) { /* example: /dev/block/platform/bootdevice/by-name/userdata */ type = 0; } else if (strstr(path, "externdevice") || strstr(path, "vold")) { /* example: /dev/block/vold/private:179,2 */ type = 1; } pr_info("[dm-crypt] dev path: %s, type: %d\n", path, type); return type; }
So whenever you are trying to device-map some block device that does not have any of the substrings "bootdevice" or "vold" or "externdevice" in them, this returns -1, which in turn will break any attempts to use such a device in the device-mapper, thanks to the over-strict check added in crypt_ctr():
cc->id = ret = crypt_dev_id(argv[3]); if (ret < 0) goto bad;
Note how e.g. any loop device /dev/loop* will thus fail. However, this also allows a workaround. We just use a different name (with the same major/minor device numbers) that matches 'externdevice'. This way dmsetup will magically start working:
cp -a "${LODEV}" /dev/externdevice1 echo "0 128 crypt aes-ecb 0123456789abcdef0123456789abcdef 0 /dev/externdevice1 0" | dmsetup create crypt2
However, I am not sure whether this kind of workaround could be applied to 'cryptsetup'.
This really destroys any illusion WRT to code-quality of the kernels that is running the Volla phone.