[PATCH][i9100] Encrypted Emulated Internal Storage

Added by Grim Kriegor 7 months ago

Hello gentlemen. I've recently replaced my pocket spy with an awesome i9100 running Replicant and it has been great.
However there were a few things I had to change in order to fully replace the pocket spy with something freer, which include enabling emulated internal storage so that files in /sdcard get encrypted alongside the rest of /data.

I must start by saying that it seems Android 4.2 was on the threshold of some significant changes to how storage gets handled and it is quite the pain the find proper documentation for this particular version of Replicant, forcing me to do quite a bit of trial and error. Feel free to provide feedback on any of these methods.

The process goes something like this:
- Repartition the memory to increasce the size of /data (mmc0blk10) and decreasce that of /emmc (mmc0blk11)
- Build and install Replicant 4.2 with support for emulated internal memory
- Encrypt /data

This was what I managed to stick together:

Repartitioning:

Repartitioning the internal memory can brick your phone, be careful!

I've prepared a partition table that expands /data (mmcblk0p10) as much as possible and shrinks /sdcard (mmcblk0p11) by changing the position of their last and first blocks respectively, resulting in a 14GiB /data partition.

PIT file and signature are avaliable here:
https://github.com/GrimKriegor/Misc/tree/master/Replicant/PartitionTables

Unless you change the coordinates of a partition its contents should be safe, simply flash the partition table using Heimdall:

heimdall flash --repartition --PIT I9100_14GB_grim.pit

Code for emulated storage support:

From 84c5a91a45b059a147921d0ea32367534904b314 Mon Sep 17 00:00:00 2001
From: GrimKriegor <grimkriegor@krutt.org>
Date: Fri, 16 Sep 2016 23:02:43 +0100
Subject: [PATCH] Switching sdcard0 from physical to emulated.

---
 configs/vold.fstab                                 |  2 +-
 .../base/core/res/res/xml/storage_list.xml         | 10 +++++-----
 rootdir/init.smdk4210.rc                           | 22 ++++++++++++++++++----
 3 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/configs/vold.fstab b/configs/vold.fstab
index bc12264..68e37df 100644
--- a/configs/vold.fstab
+++ b/configs/vold.fstab
@@ -13,7 +13,7 @@
 ######################

 # internal sdcard
-dev_mount sdcard0 /storage/sdcard0 11 /devices/platform/dw_mmc/mmc_host/mmc0/mmc0 nonremovable,encryptable
+#dev_mount sdcard0 /storage/sdcard0 11 /devices/platform/dw_mmc/mmc_host/mmc0/mmc0 nonremovable,encryptable

 # external sdcard
 dev_mount sdcard1 /storage/sdcard1 auto /devices/platform/s3c-sdhci.2/mmc_host/mmc1
diff --git a/overlay/frameworks/base/core/res/res/xml/storage_list.xml b/overlay/frameworks/base/core/res/res/xml/storage_list.xml
index 44ed062..214eac8 100644
--- a/overlay/frameworks/base/core/res/res/xml/storage_list.xml
+++ b/overlay/frameworks/base/core/res/res/xml/storage_list.xml
@@ -33,17 +33,17 @@
 -->

 <StorageList xmlns:android="http://schemas.android.com/apk/res/android">
-    <storage android:mountPoint="/storage/sdcard0" 
-             android:storageDescription="@string/storage_internal" 
+    <storage android:storageDescription="@string/storage_internal" 
              android:primary="true" 
-             android:removable="false" 
-             android:allowMassStorage="true" />
+             android:emulated="true" 
+             android:mtpReserve="100" />

     <storage android:mountPoint="/storage/sdcard1" 
              android:storageDescription="@string/storage_sd_card" 
              android:primary="false" 
+             android:emulated="false" 
              android:removable="false" 
-             android:allowMassStorage="true" />
+             android:maxFileSize="4096" />

     <storage android:mountPoint="/storage/usbdisk0" 
              android:storageDescription="@string/storage_usb" 
diff --git a/rootdir/init.smdk4210.rc b/rootdir/init.smdk4210.rc
index dedd393..ed7c90e 100644
--- a/rootdir/init.smdk4210.rc
+++ b/rootdir/init.smdk4210.rc
@@ -2,20 +2,30 @@ import init.smdk4210.usb.rc
 import init.gps.rc

 on init
-    export EXTERNAL_STORAGE /storage/sdcard0
+    export EXTERNAL_STORAGE /storage/emulated/legacy
+    export EMULATED_STORAGE_SOURCE /mnt/shell/emulated
+    export EMULATED_STORAGE_TARGET /storage/emulated
     export SECONDARY_STORAGE /storage/sdcard1
+
     mkdir /storage 0775 system system
-    mkdir /storage/sdcard0 0775 system system
+    mkdir /mnt/media_rw 0775 system system
+    mkdir /mnt/shell/emulated 0700 shell shell
+    mkdir /storage/emulated 0555 root root
+    mkdir /mnt/media_rw/sdcard1 0700 media_rw media_rw
     mkdir /storage/sdcard1 0775 system system
+    mkdir /mnt/media_rw/usbdisk0 0700 media_rw media_rw
     mkdir /storage/usbdisk0 0775 system system
+
     mkdir /efs 0771 radio system
     mkdir /preload 0771 system system
     mkdir /mnt 0775 root system
     mkdir /mnt/.lfs 0755 root root

     # for backwards compatibility
-    symlink /storage/sdcard0 /sdcard
-    symlink /storage/sdcard0 /mnt/sdcard
+    symlink /storage/emulated/legacy /sdcard
+    symlink /storage/emulated/legacy /mnt/sdcard
+    symlink /storage/emulated/legacy /storage/sdcard0
+    symlink /mnt/shell/emulated/0 /storage/emulated/legacy
     symlink /storage/sdcard1 /extSdCard
     symlink /storage/sdcard1 /mnt/extSdCard
     symlink /storage/usbdisk0 /usbdisk0
@@ -25,6 +35,7 @@ on init
     write /sys/block/mmcblk0/queue/iosched/slice_idle 0

 on fs
+    setprop ro.crypto.fuse_sdcard true
     mount_all /fstab.smdk4210

     mkdir /efs/bluetooth
@@ -397,3 +408,6 @@ service bugreport /system/bin/bugmailer.sh -v
     disabled
     oneshot
     keycodes 114 115 116
+
+service sdcard /system/bin/sdcard /data/media /mnt/shell/emulated 1023 1023
+     class late_start

Hope some of you guys find this information useful. Good luck!

Additionally, it may be possible to confortably use this without repartitioning, the primary sdcard (sdcard0) would be quite small inside the 2GiB /data, but another sdcard could be provided by /emmc (sdcard1), in addition to the external card (sdcard2), this way most apps would be provided with an encrypted storage when they try to save things in the internal memory.

EDIT (20160925):
Simpler Heimdall command, turns out you don't need to provide contents for all partitions while repartitioning.


Replies (5)

RE: [PATCH][i9100] Encrypted Emulated Internal Storage - Added by Wolfgang Wiedmeyer about 1 month ago

Have you checked if all of this already works with Replicant 6.0 (except repartitioning) or is a patch still needed?

RE: [PATCH][i9100] Encrypted Emulated Internal Storage - Added by Grim Kriegor about 1 month ago

From the quick and shallow tests I did in early February, with the latest code available at the time, I could not "adopt" the emmc partition as internal storage, like you can with any other sdcard, the option simply wasn't there.

Only by repartitioning and applying these changes was I able to get the desired effect, hide the vestigial emmc and create a virtual sdcard in /data.

diff --git a/rootdir/fstab.smdk4210 b/rootdir/fstab.smdk4210
index 41df278..67976fd 100755
--- a/rootdir/fstab.smdk4210
+++ b/rootdir/fstab.smdk4210
@@ -13,7 +13,7 @@
 /dev/block/mmcblk0p12                       /preload                ext4      noatime,nosuid,nodev,journal_async_commit                 wait

 # vold-managed volumes ("block device" is actually a sysfs devpath)
-/devices/platform/dw_mmc/mmc_host/mmc0/mmc0*                  auto    auto    defaults        wait,voldmanaged=sdcard0:11,noemulatedsd,nonremovable
+#/devices/platform/dw_mmc/mmc_host/mmc0/mmc0*                  auto    auto    defaults        wait,voldmanaged=sdcard0:11,noemulatedsd,nonremovable
 /devices/platform/s3c-sdhci.2/mmc_host/mmc1*                  auto    auto    defaults        wait,voldmanaged=sdcard1:auto,encryptable=userdata
 /devices/platform/s3c_otghcd/usb*                             auto    auto    defaults        voldmanaged=usb:auto

diff --git a/rootdir/init.smdk4210.rc b/rootdir/init.smdk4210.rc
index 4fe4177..91f48c1 100644
--- a/rootdir/init.smdk4210.rc
+++ b/rootdir/init.smdk4210.rc
@@ -13,6 +13,9 @@ on init
 # Disable CFQ slice idle delay
     write /sys/block/mmcblk0/queue/iosched/slice_idle 0

+# Emulated storage
+    setprop ro.vold.primary_physical 0
+
 on fs
     mount_all /fstab.smdk4210
     swapon_all /fstab.smdk4210

Thanks for taking a look, Wolfgang, and keep up the great work!

RE: [PATCH][i9100] Encrypted Emulated Internal Storage - Added by Wolfgang Wiedmeyer about 1 month ago

Ok, thanks for the update! At least these changes would only require recompiling the kernel with a modified initramfs and not a whole Replicant image.

This change might also be interesting: https://review.lineageos.org/#/c/157065/

RE: [PATCH][i9100] Encrypted Emulated Internal Storage - Added by Grim Kriegor about 1 month ago

Oh, this is very interesting indeed. This way we could have both configs on the code and compile whichever we required.

Do you think it would be acceptable to include something similar to this in Replicant?

I think most people would agree having a encrypted emulated storage is quite important. Maybe in the future we could have both builds and instructions on how to repartition on the wiki.

I'd love to help with this, gonna try to borrow a spare device soon. Thanks for your time.

________________________________________________________
ADDENDUM:

Applying the changes by hand results in this following diff. I still wonder why rINanDO sets "ro.vold.primary_physical=1" when "TARGET_USE_EMULATED_STORAGE" is false. Shouldn't it be more proper to set "ro.vold.primary_physical=0" when "TARGET_USE_EMULATED_STORAGE" is true, since primary physical is the default, as specified in "i9100/system.prop" (in both CM13 and LOS 14.1)?

diff --git a/common.mk b/common.mk
index d56effd..60dcf60 100644
--- a/common.mk
+++ b/common.mk
@@ -19,11 +19,20 @@ DEVICE_PACKAGE_OVERLAYS := $(COMMON_PATH)/overlay

 # Rootdir
 PRODUCT_COPY_FILES := \
-    $(COMMON_PATH)/rootdir/fstab.smdk4210:root/fstab.smdk4210 \
     $(COMMON_PATH)/rootdir/init.smdk4210.usb.rc:root/init.smdk4210.usb.rc \
     $(COMMON_PATH)/rootdir/init.smdk4210.rc:root/init.smdk4210.rc \
     $(COMMON_PATH)/rootdir/ueventd.smdk4210.rc:root/ueventd.smdk4210.rc

+ifeq ($(TARGET_USE_EMULATED_STORAGE),true)
+    PRODUCT_COPY_FILES += \
+        $(COMMON_PATH)/rootdir/fstab.smdk4210-emu:root/fstab.smdk4210
+    PRODUCT_PROPERTY_OVERRIDES += \
+        ro.vold.primary_physical=0
+else
+    PRODUCT_COPY_FILES += \
+        $(COMMON_PATH)/rootdir/fstab.smdk4210:root/fstab.smdk4210
+endif
+
 # Recovery rootdir
 PRODUCT_COPY_FILES += \
     $(COMMON_PATH)/rootdir/init.recovery.smdk4210.rc:root/init.recovery.smdk4210.rc
diff --git a/rootdir/fstab.smdk4210-emu b/rootdir/fstab.smdk4210-emu
new file mode 100755
index 0000000..99eeaca
--- /dev/null
+++ b/rootdir/fstab.smdk4210-emu
@@ -0,0 +1,24 @@
+# Android fstab file.
+#<src>                                      <mnt_point>             <type>    <mnt_flags and options>                                   <fs_mgr_flags>
+# The filesystem that contains the filesystem checker binary (typically /system) cannot
+# specify MF_CHECK, and must come before any filesystems that do specify MF_CHECK
+# data partition must be located at the bottom for supporting device encryption
+
+/dev/block/mmcblk0p9                        /system                 ext4      ro,noatime                                                wait
+/dev/block/mmcblk0p7                        /cache                  f2fs      noatime,nosuid,nodev,inline_data,inline_xattr,discard     wait
+/dev/block/mmcblk0p7                        /cache                  ext4      noatime,nosuid,nodev,journal_async_commit,errors=panic    wait,check_spo
+/dev/block/mmcblk0p1                        /efs                    ext4      noatime,nosuid,nodev,journal_async_commit,errors=panic    wait,check_spo
+/dev/block/mmcblk0p10                       /data                   f2fs      noatime,nosuid,nodev,inline_data,inline_xattr,discard     wait,encryptable=footer,length=-16384
+/dev/block/mmcblk0p10                       /data                   ext4      noatime,nosuid,nodev,noauto_da_alloc,journal_async_commit,errors=panic    wait,check_spo,encryptable=footer,length=-16384
+/dev/block/mmcblk0p12                       /preload                ext4      noatime,nosuid,nodev,journal_async_commit                 wait
+
+# vold-managed volumes ("block device" is actually a sysfs devpath)
+/devices/platform/s3c-sdhci.2/mmc_host/mmc1*                  auto    auto    defaults        wait,voldmanaged=sdcard1:auto,encryptable=userdata
+/devices/platform/s3c_otghcd/usb*                             auto    auto    defaults        voldmanaged=usb:auto
+
+# recovery
+/dev/block/mmcblk0p5                        /boot                   emmc      defaults      recoveryonly
+/dev/block/mmcblk0p6                        /recovery               emmc      defaults      recoveryonly
+
+# zRAM
+/dev/block/zram0                            none                    swap      defaults      zramsize=268435456,zramstreams=2

Will test ASAP.

RE: [PATCH][i9100] Encrypted Emulated Internal Storage - Added by Wolfgang Wiedmeyer about 1 month ago

Grim Kriegor wrote:

Do you think it would be acceptable to include something similar to this in Replicant?

I think most people would agree having a encrypted emulated storage is quite important. Maybe in the future we could have both builds and instructions on how to repartition on the wiki.

Indeed, it's definitely worth discussing. I think there is not yet a policy for offering different builds for a device. I guess offering a signed kernel image with instructions would be fine.

Applying the changes by hand results in this following diff. I still wonder why rINanDO sets "ro.vold.primary_physical=1" when "TARGET_USE_EMULATED_STORAGE" is false. Shouldn't it be more proper to set "ro.vold.primary_physical=0" when "TARGET_USE_EMULATED_STORAGE" is true, since primary physical is the default, as specified in "i9100/system.prop" (in both CM13 and LOS 14.1)?

Probably yes. I'd have to take a closer look. Contacting the LineageOS developers could bring some clarity to this. They'd need to be contacted anyway because we need to know what their future plans regarding this are and why this change was abandoned and not merged.

(1-5/5)