Commit 7d1222a5 authored by nkk71's avatar nkk71 Committed by Dees Troy

vold_decrypt: FDE Keymaster 3.0 support

* HTC U11 Oreo is using keymaster3 FDE encryption which requires
  the new services:
    1- /system/bin/hwservicemanager
    2- /vendor/bin/hw/android.hardware.keymaster@3.0-service
    3- /vendor/bin/qseecomd (instead of /system/bin/qseecomd)
  So in addition to /vendor/lib and /vendor/lib64 also
  symlink /system/vendor/bin to /vendor/bin.

* vold_decrypt services now have separate prefixes:
    1- 'sys_' referring to /system/bin
    2- 'ven_' referring to /vendor/bin

* The additional (hwservicemanager, keymaster-3-0) and modified
  (qseecomd) .rc files have been updated in the vold_decrypt
  directory.
  Comments were added directly in the .rc files, please check
  them.

* /etc/recovery.fstab needs to be temporarily moved since
  vold will use it if it finds the '/sbin/recovery' file
  (refer to fs_mgr for the fstab load code https://goo.gl/8KaZyf).
  Since fs_mgr cannot parse TWRP style fstab, we 'hide' it
  and attempt to create a symlink to /fstab.{ro.hardware}.

Also remove shell dependencies, code cleanup, new error codes:
* Critical sections of vold_decrypt should not rely on the external
  shell (and the available binaries) provided by TWFunc::Exec_Cmd.
  Doing so may lead to failures resulting from different shell
  provided binaries not working properly, especially since busybox
  can be inconsistent across different trees.

  In particular the following functions have been changed:
  * run_vdc() no longer uses daisy chained commands, instead
    it now forks and executes vdc directly including a 30 second
    built in timeout.
  * Symlink_Firmware_Files() no longer relies on the shell 'find'
    command to retrieve the list of firmware/vendor files and instead
    uses a built in function, Find_Firmware_Files(), which traverses
    the system partition to retrieve the list of files.

* The code has also been cleaned up a little for better consistency,
  and vold_decrypt will now return various error codes for the
  different failures, as defined in vold_decrypt.h, which allows the
  gui_msg to be moved back to partitionmanager.cpp.

Notes regarding pre Android 8.0 builds:
* Service names in .rc files cannot exceed 16 characters (including
  the prepended 'sys_' or 'ven_') in Android 7.1 and below, so a
  service name such as 'sys_hwservicemanager' is out of the question
  for 7.1 and below.
* hwservicemanager will check ACLs on 'hwservicemanager' and 'ITokenManager'
  if they are even allowed to run, otherwise the interfaces will fail.
  The policies have only been introduced in 8.0, and although it is possible
  to manually add them to the 7.1 policies it's not recommended.
* Therefore the best course of action is to build in 8.0.

* SIDE NOTE: On the HTC U11 we are actually using omni-7.1 with some changes
  in the device tree to support both Nougat and Oreo decryption, please
  refer to:
    1- https://gerrit.twrp.me/c/2756/ for the necessary sepolicy and
       BoardConfig changes.
    2- The Android.mk file for vold_decrypt was modified to truncate
       greater than 16 character service names (as mentioned therein)

Other changes:
* TW_CRYPTO_SYSTEM_VOLD_DISABLE_TIMEOUT is now deprecated due to built-
  in fork and timeout.
* Output_dmesg_to_recovery_log() is also deprecated so upon a failed
  decryption the recovery.log will no longer append it, instead you can
  just use 'adb shell dmesg' to check it. Nonetheless if a true debug
  build is needed use the original TW_CRYPTO_SYSTEM_VOLD_DEBUG flag as
  outlined in the original commit message (see below).

Usage info:
This is an update to the initial vold_decrypt, for more info refer to
https://github.com/omnirom/android_bootable_recovery/commit/71c6c50d0da1f32dd18a749797e88de2358c5ba1

Change-Id: Id7129d125ae7f5dcba0779489825add718022ba3
parent fefe5915
......@@ -16,7 +16,6 @@ LOCAL_PATH := $(call my-dir)
ifeq ($(TW_INCLUDE_CRYPTO), true)
ifneq ($(TW_CRYPTO_USE_SYSTEM_VOLD),)
ifneq ($(TW_CRYPTO_USE_SYSTEM_VOLD),false)
# Parse TW_CRYPTO_USE_SYSTEM_VOLD
......@@ -54,6 +53,17 @@ ifeq ($(TW_INCLUDE_CRYPTO), true)
cp -f "$(LOCAL_PATH)/$(item)" "$(TARGET_ROOT_OUT)"/; \
fi; \
)
ifeq ($(shell test $(PLATFORM_SDK_VERSION) -lt 26; echo $$?),0)
# Truncate service_name to max 16 characters
LOCAL_POST_INSTALL_CMD += \
$(foreach item, $(rc_files), \
if [ -f "$(TARGET_ROOT_OUT)/$(item)" ]; then \
sed -i 's/\([ \t]*service[ \t]*\)\(.\{16\}\).*\([ \t].*\)/\1\2\3/' "$(TARGET_ROOT_OUT)/$(item)"; \
fi; \
)
endif
include $(BUILD_PREBUILT)
......@@ -66,7 +76,14 @@ ifeq ($(TW_INCLUDE_CRYPTO), true)
endif
ifneq ($(services),)
LOCAL_CFLAGS += -DTW_CRYPTO_SYSTEM_VOLD_SERVICES='"$(services)"'
ifeq ($(shell test $(PLATFORM_SDK_VERSION) -lt 26; echo $$?),0)
# Truncate service_name to max 12 characters due to the 4 character prefix
truncated_services := $(foreach item,$(services),$(shell echo -n "$(item)" | sed 's/\(.\{12\}\).*/\1/'))
LOCAL_CFLAGS += -DTW_CRYPTO_SYSTEM_VOLD_SERVICES='"$(truncated_services)"'
LOCAL_CFLAGS += -D_USING_SHORT_SERVICE_NAMES
else
LOCAL_CFLAGS += -DTW_CRYPTO_SYSTEM_VOLD_SERVICES='"$(services)"'
endif
endif
ifeq ($(TW_CRYPTO_SYSTEM_VOLD_DEBUG),true)
......@@ -74,14 +91,9 @@ ifeq ($(TW_INCLUDE_CRYPTO), true)
LOCAL_CFLAGS += -DTW_CRYPTO_SYSTEM_VOLD_DEBUG
endif
ifeq ($(TW_CRYPTO_SYSTEM_VOLD_DISABLE_TIMEOUT),true)
LOCAL_CFLAGS += -DTW_CRYPTO_SYSTEM_VOLD_DISABLE_TIMEOUT
endif
LOCAL_SRC_FILES = vold_decrypt.cpp
LOCAL_SHARED_LIBRARIES := libcutils
include $(BUILD_STATIC_LIBRARY)
endif
endif
endif
# Service names must be less than 16 characters in android-7.1 and
# below. The makefile will truncate service names if needed in any
# init.recovery.vold_decryp.*.rc file found in the vold_decrypt
# directory.
# It cannot however do this for any .rc file(s) that may be
# overridden by the device tree files!
# The seclabels are not needed when built in Android 8.0 tree
# in 7.1 however the below do not exist, so run them under vold
service sys_hwservicemanager /system/bin/hwservicemanager
user root
group root
setenv PATH /system/bin
setenv LD_LIBRARY_PATH /system/lib64:/system/lib
onrestart setprop hwservicemanager.ready false
disabled
oneshot
seclabel u:r:vold:s0
# Service names must be less than 16 characters in android-7.1 and
# below. The makefile will truncate service names if needed in any
# init.recovery.vold_decryp.*.rc file found in the vold_decrypt
# directory.
# It cannot however do this for any .rc file(s) that may be
# overridden by the device tree files!
# The seclabels are not needed when built in Android 8.0 tree
# in 7.1 however the below do not exist, so run them under vold
service ven_keymaster-3-0 /vendor/bin/hw/android.hardware.keymaster@3.0-service
user root
group root
setenv PATH /vendor/bin:/system/bin
setenv LD_LIBRARY_PATH /vendor/lib64:/system/lib64:/vendor/lib:/system/lib
disabled
oneshot
seclabel u:r:vold:s0
......@@ -5,6 +5,10 @@ on fs
chmod 0664 /dev/ion
chown system system /dev/ion
# Oreo has qseecomd in /vendor/bin so add the additional
# service. Only an existing binary will be started, never both.
service sys_qseecomd /system/bin/qseecomd
user root
group root
......@@ -12,3 +16,11 @@ service sys_qseecomd /system/bin/qseecomd
setenv LD_LIBRARY_PATH /system/lib64:/system/lib
disabled
oneshot
service ven_qseecomd /vendor/bin/qseecomd
user root
group root
setenv PATH /vendor/bin:/system/bin
setenv LD_LIBRARY_PATH /vendor/lib64:/system/lib64:/vendor/lib:/system/lib
disabled
oneshot
This diff is collapsed.
......@@ -21,6 +21,22 @@
#include <string>
int vold_decrypt(std::string Password);
// -_-
enum {
VD_SUCCESS = 0,
VD_ERR_DECRYPTION_FAILED = -1,
VD_ERR_UNABLE_TO_MOUNT_SYSTEM = -2,
VD_ERR_MISSING_VOLD = -3,
VD_ERR_MISSING_VDC = -4,
VD_ERR_VDC_FAILED_TO_CONNECT = -5,
VD_ERR_VOLD_FAILED_TO_START = -6,
VD_ERR_VOLD_UNEXPECTED_RESPONSE = -7,
VD_ERR_VOLD_OPERATION_TIMEDOUT = -8,
VD_ERR_FORK_EXECL_ERROR = -9,
VD_ERR_PASSWORD_EMPTY = -10,
};
int vold_decrypt(const std::string& Password);
#endif // _VOLD_DECRYPT_H
......@@ -1658,6 +1658,16 @@ int TWPartitionManager::Decrypt_Device(string Password) {
#ifdef TW_CRYPTO_USE_SYSTEM_VOLD
if (pwret != 0) {
pwret = vold_decrypt(Password);
switch (pwret) {
case VD_SUCCESS:
break;
case VD_ERR_MISSING_VDC:
gui_msg(Msg(msg::kError, "decrypt_data_vold_os_missing=Missing files needed for vold decrypt: {1}")("/system/bin/vdc"));
break;
case VD_ERR_MISSING_VOLD:
gui_msg(Msg(msg::kError, "decrypt_data_vold_os_missing=Missing files needed for vold decrypt: {1}")("/system/bin/vold"));
break;
}
}
#endif // TW_CRYPTO_USE_SYSTEM_VOLD
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment