crypto: Use system's vold for decryption

  If TWRP crypto fails to decrypt partition, mount the system
  partition and use system's own vold to attempt decryption.
  This provides a fallback for proprietary OEM encryption as well as
  encryption methods which TWRP hasn't been updated for.

  Requirements in device tree:
  * fstab.{ro.hardware} in device/recovery/root
    The fstab does not need to be complete, but it does need the
    data partition and the encryption entries.

  * 'TW_CRYPTO_USE_SYSTEM_VOLD := true' in BoardConfig
  or
  * 'TW_CRYPTO_USE_SYSTEM_VOLD := <list of services>'

  Notes:
  * Setting the flag to 'true' will just use system's vdc+vold
    or
  * Setting the flag with additional services, will also start them
    prior to attempting vdc+vold decryption, eg: for qualcomm based
    devices you usually need 'TW_CRYPTO_USE_SYSTEM_VOLD := qseecomd'

  * For each service listed an additional import will be automatically
    added to the vold_decrypt.rc file in the form of
    init.recovery.vold_decrypt.{service}.rc
    You will need to add any not already existing .rc files in
    your device/recovery/root folder.

  * The service names specified in the vold_decrypt.{service}.rc files
    have to be named 'sys_{service}'
    eg: 'service sys_qseecomd /system/bin/qseecomd'

  * Any service already existing in TWRP as {service} or sbin{service} will
    be stopped and restarted as needed.

  * You can override the default init.recovery.vold_decrypt.rc file(s)
    by placing same named ones in your device/recovery/root folder.
    If you do, you'll need to manually add the needed imports.

  * If /vendor and /firmware folders are temporarily moved and symlinked
    to the folders and files in the system partition, the properties
    'vold_decrypt.symlinked_vendor' and 'vold_decrypt.symlinked_firmware'
    will be set to 1.
    This allows for additional control in the .rc files for any extra
    actions (symlinks, cp files, etc) that may be needed for decryption
    by using: on property:vold_decrypt.symlinked_vendor=1 and/or
    on property:vold_decrypt.symlinked_firmware=1 triggers.

  Debug mode: 'TW_CRYPTO_SYSTEM_VOLD_DEBUG := true' in BoardConfig
  * Specifying this flag, will enable strace on init and vdc, which will
    create separate log files in /tmp for every process created, allowing
    for detailed analysis of which services and files are being accessed.
  * Note that enabling strace will expose the password in the logs!!
  * You need to manually add strace to your build.

Thanks to @Captain_Throwback for co-authoring and testing.

Tested successfully on HTC devices:
M8 (KK through MM), M9 (MM and N), A9 (N), 10 (N), Bolt (N),
Desire 626s (MM), U Ultra (N)

HTC One X9 (MTK device)

And by Nikolay Jeliazkov on: Xiaomi Mi Max

Change-Id: I4d22ab55baf6a2a50adde2e4c1c510c142714227
diff --git a/crypto/vold_decrypt/Android.mk b/crypto/vold_decrypt/Android.mk
new file mode 100644
index 0000000..e371c24
--- /dev/null
+++ b/crypto/vold_decrypt/Android.mk
@@ -0,0 +1,87 @@
+# Copyright (C) 2017 TeamWin Recovery Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+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
+        ifeq ($(TW_CRYPTO_USE_SYSTEM_VOLD),true)
+            # Just enabled, so only vold + vdc
+            services :=
+        else
+            # Additional services needed by vold
+            services := $(TW_CRYPTO_USE_SYSTEM_VOLD)
+        endif
+
+        # List of .rc files for each additional service
+        rc_files := $(foreach item,$(services),init.recovery.vold_decrypt.$(item).rc)
+
+
+        include $(CLEAR_VARS)
+        LOCAL_MODULE := init.recovery.vold_decrypt.rc
+        LOCAL_MODULE_TAGS := eng
+        LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
+
+        # Cannot send to TARGET_RECOVERY_ROOT_OUT since build system wipes init*.rc
+        # during ramdisk creation and only allows init.recovery.*.rc files to be copied
+        # from TARGET_ROOT_OUT thereafter
+        LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
+
+        LOCAL_SRC_FILES := $(LOCAL_MODULE)
+
+        # Add additional .rc files and imports into init.recovery.vold_decrypt.rc
+        # Note: any init.recovery.vold_decrypt.{service}.rc that are not default
+        #       in crypto/vold_decrypt should be in the device tree
+        LOCAL_POST_INSTALL_CMD := $(hide) \
+            $(foreach item, $(rc_files), \
+                sed -i '1iimport \/$(item)' "$(TARGET_ROOT_OUT)/$(LOCAL_MODULE)"; \
+                if [ -f "$(LOCAL_PATH)/$(item)" ]; then \
+                    cp -f "$(LOCAL_PATH)/$(item)" "$(TARGET_ROOT_OUT)"/; \
+                fi; \
+            )
+        include $(BUILD_PREBUILT)
+
+
+        include $(CLEAR_VARS)
+        LOCAL_MODULE := libvolddecrypt
+        LOCAL_MODULE_TAGS := eng optional
+        LOCAL_CFLAGS := -Wall
+        ifeq ($(shell test $(PLATFORM_SDK_VERSION) -lt 23; echo $$?),0)
+            LOCAL_C_INCLUDES += external/stlport/stlport bionic bionic/libstdc++/include
+        endif
+
+        ifneq ($(services),)
+            LOCAL_CFLAGS += -DTW_CRYPTO_SYSTEM_VOLD_SERVICES='"$(services)"'
+        endif
+
+        ifeq ($(TW_CRYPTO_SYSTEM_VOLD_DEBUG),true)
+            # Enabling strace will expose the password in the strace logs!!
+            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