From 253368a0726120efa57664cdd1d088af099a3d81 Mon Sep 17 00:00:00 2001 From: Ethan Yonker Date: Tue, 25 Nov 2014 15:00:52 -0600 Subject: Reduce libs needed for decrypt and clean up old decypt files Trim cryptfs.c to remove functions that TWRP does not use for decrypt and remove the need for libfs_mgr from cryptfs.c by passing some items to cryptfs.c from the partition manager. Add support for new fstab flags: encryptable and forceencrypt=/path/to/cryptokey For example: flags=forceencrypt=/dev/block/platform/sdhci-tegra.3/by-name/MD1 Note that "footer" is the default, so you do not need to set this flag on devices that use the footer for the crypto key. Also add mounttodecrypt if you need to mount a partition during the decrypt cycle for firmware of proprietary libs. Clean up decrypt and only support one version Android 5.0 lollipop decrypt should be backwards compatible with older versions so we will only support one version, 1.3 that came with 5.0 lollipop. Remove support for Samsung TouchWiz decrypt. It does not work with the latest versions of Samsung encryption anyway and it has not been updated to work with any AOSP decryption higher than 1.1 Change-Id: I2d9c6e31df50268c91ee642c2fa090f901d9d5c9 --- crypto/cryptfs/Android.mk | 54 - crypto/cryptfs/cryptfs.c | 74 - crypto/cryptsettings/Android.mk | 17 - crypto/cryptsettings/cryptsettings.c | 55 - crypto/crypttools/Android.mk | 15 - crypto/crypttools/getfooter.c | 219 -- crypto/fs_mgr/Android.mk | 38 - crypto/fs_mgr/fs_mgr.c | 948 -------- crypto/fs_mgr/fs_mgr_main.c | 114 - crypto/fs_mgr/fs_mgr_priv.h | 85 - crypto/fs_mgr/fs_mgr_priv_verity.h | 17 - crypto/fs_mgr/fs_mgr_verity.c | 410 ---- crypto/fs_mgr/include/fs_mgr.h | 72 - crypto/ics/Android.mk | 25 - crypto/ics/cryptfs.c | 729 ------- crypto/ics/cryptfs.h | 86 - crypto/jb/Android.mk | 17 - crypto/jb/cryptfs.c | 1735 --------------- crypto/jb/cryptfs.h | 157 -- crypto/libcrypt_samsung/Android.mk | 11 - crypto/libcrypt_samsung/include/libcrypt_samsung.h | 144 -- crypto/libcrypt_samsung/libcrypt_samsung.c | 65 - crypto/logwrapper/Android.mk | 34 - crypto/logwrapper/NOTICE | 190 -- crypto/logwrapper/include/logwrap/logwrap.h | 87 - crypto/logwrapper/logwrap.c | 569 ----- crypto/logwrapper/logwrapper.c | 96 - crypto/lollipop/Android.mk | 26 +- crypto/lollipop/cryptfs.c | 2299 +------------------- crypto/lollipop/cryptfs.h | 17 +- crypto/scrypt/Android.mk | 3 +- crypto/scrypt/Scrypt-config.mk | 4 +- crypto/scrypt/tests/Android.mk | 4 +- crypto/scrypt/tests/scrypt_test.cpp | 2 +- 34 files changed, 95 insertions(+), 8323 deletions(-) delete mode 100644 crypto/cryptfs/Android.mk delete mode 100644 crypto/cryptfs/cryptfs.c delete mode 100644 crypto/cryptsettings/Android.mk delete mode 100644 crypto/cryptsettings/cryptsettings.c delete mode 100644 crypto/crypttools/Android.mk delete mode 100644 crypto/crypttools/getfooter.c delete mode 100644 crypto/fs_mgr/Android.mk delete mode 100644 crypto/fs_mgr/fs_mgr.c delete mode 100644 crypto/fs_mgr/fs_mgr_main.c delete mode 100644 crypto/fs_mgr/fs_mgr_priv.h delete mode 100644 crypto/fs_mgr/fs_mgr_priv_verity.h delete mode 100644 crypto/fs_mgr/fs_mgr_verity.c delete mode 100644 crypto/fs_mgr/include/fs_mgr.h delete mode 100644 crypto/ics/Android.mk delete mode 100644 crypto/ics/cryptfs.c delete mode 100644 crypto/ics/cryptfs.h delete mode 100644 crypto/jb/Android.mk delete mode 100644 crypto/jb/cryptfs.c delete mode 100644 crypto/jb/cryptfs.h delete mode 100644 crypto/libcrypt_samsung/Android.mk delete mode 100644 crypto/libcrypt_samsung/include/libcrypt_samsung.h delete mode 100644 crypto/libcrypt_samsung/libcrypt_samsung.c delete mode 100644 crypto/logwrapper/Android.mk delete mode 100644 crypto/logwrapper/NOTICE delete mode 100644 crypto/logwrapper/include/logwrap/logwrap.h delete mode 100644 crypto/logwrapper/logwrap.c delete mode 100644 crypto/logwrapper/logwrapper.c (limited to 'crypto') diff --git a/crypto/cryptfs/Android.mk b/crypto/cryptfs/Android.mk deleted file mode 100644 index f0388c228..000000000 --- a/crypto/cryptfs/Android.mk +++ /dev/null @@ -1,54 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) -ifeq ($(TW_INCLUDE_CRYPTO), true) -LOCAL_SRC_FILES:= \ - cryptfs.c - -LOCAL_CFLAGS:= -g -c -W -I../fs_mgr/include -LOCAL_CFLAGS += -DTW_INCLUDE_CRYPTO -LOCAL_CFLAGS += -DCRYPTO_FS_TYPE=\"$(TW_CRYPTO_FS_TYPE)\" -LOCAL_CFLAGS += -DCRYPTO_REAL_BLKDEV=\"$(TW_CRYPTO_REAL_BLKDEV)\" -LOCAL_CFLAGS += -DCRYPTO_MNT_POINT=\"$(TW_CRYPTO_MNT_POINT)\" -LOCAL_CFLAGS += -DCRYPTO_FS_OPTIONS=\"$(TW_CRYPTO_FS_OPTIONS)\" -LOCAL_CFLAGS += -DCRYPTO_FS_FLAGS=\"$(TW_CRYPTO_FS_FLAGS)\" -LOCAL_CFLAGS += -DCRYPTO_KEY_LOC=\"$(TW_CRYPTO_KEY_LOC)\" -ifdef TW_CRYPTO_SD_REAL_BLKDEV - LOCAL_CFLAGS += -DCRYPTO_SD_REAL_BLKDEV=\"$(TW_CRYPTO_SD_REAL_BLKDEV)\" - LOCAL_CFLAGS += -DCRYPTO_SD_FS_TYPE=\"$(TW_CRYPTO_SD_FS_TYPE)\" -endif -ifneq ($(TW_INTERNAL_STORAGE_PATH),) - LOCAL_CFLAGS += -DTW_INTERNAL_STORAGE_PATH=$(TW_INTERNAL_STORAGE_PATH) -endif -ifneq ($(TW_INTERNAL_STORAGE_MOUNT_POINT),) - LOCAL_CFLAGS += -DTW_INTERNAL_STORAGE_MOUNT_POINT=$(TW_INTERNAL_STORAGE_MOUNT_POINT) -endif -ifneq ($(TW_EXTERNAL_STORAGE_PATH),) - LOCAL_CFLAGS += -DTW_EXTERNAL_STORAGE_PATH=$(TW_EXTERNAL_STORAGE_PATH) -endif -ifneq ($(TW_EXTERNAL_STORAGE_MOUNT_POINT),) - LOCAL_CFLAGS += -DTW_EXTERNAL_STORAGE_MOUNT_POINT=$(TW_EXTERNAL_STORAGE_MOUNT_POINT) -endif - -LOCAL_C_INCLUDES += system/extras/ext4_utils external/openssl/include -LOCAL_MODULE:=cryptfs -LOCAL_MODULE_TAGS:= eng -LOCAL_SHARED_LIBRARIES += libc libcutils -LOCAL_SHARED_LIBRARIES += libcrypto - - -#LOCAL_LDFLAGS += -L$(TARGET_OUT_SHARED_LIBRARIES) -lsec_km -lsec_ecryptfs -ldl -LOCAL_LDFLAGS += -ldl - -LOCAL_STATIC_LIBRARIES += libmtdutils -LOCAL_STATIC_LIBRARIES += libminzip libunz -LOCAL_STATIC_LIBRARIES += libpixelflinger_static libpng libmincrypttwrp -LOCAL_SHARED_LIBRARIES += libz libc libstlport libcutils libstdc++ libext4_utils -LOCAL_STATIC_LIBRARIES += libcrypt_samsung - - -LOCAL_STATIC_LIBRARIES += $(TARGET_RECOVERY_UI_LIB) -#LOCAL_STATIC_LIBRARIES += libfs_mgrtwrp -LOCAL_MODULE_CLASS := UTILITY_EXECUTABLES -LOCAL_MODULE_PATH := $(PRODUCT_OUT)/utilities -include $(BUILD_EXECUTABLE) -endif diff --git a/crypto/cryptfs/cryptfs.c b/crypto/cryptfs/cryptfs.c deleted file mode 100644 index 59e7added..000000000 --- a/crypto/cryptfs/cryptfs.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2013 a3955269 all rights reversed, no rights reserved. - */ - -#define TW_INCLUDE_CRYPTO_SAMSUNG -#include "../ics/cryptfs.c" - -int dm_remove_device(const char *name) -{ - int r; - r = delete_crypto_blk_dev(name); - if(!r) - printf("crypto block device '%s' deleted.\n", name); - else - printf("deleting crypto block device '%s' failed. [%d - %s]\n", name, r, strerror(errno)); - return r; -} - -int ecryptfs_test(const char *pw) -{ - char pwbuf[256]; - int r; - - strcpy(pwbuf, pw); - // 0: building options without file encryption filtering. - // 1: building options with media files filtering. - // 2: building options with all new files filtering. - r = mount_ecryptfs_drive(pwbuf, "/emmc", "/emmc", 0); - printf("mount_ecryptfs_drive: %d\n", r); - r = mount("/dev/block/mmcblk1", "/emmc", "vfat", MS_RDONLY, ""); - printf("mount: %d\n", r); - - r = umount("/emmc");///dev/block/mmcblk1"); - printf("umount: %d\n", r); - - //r = unmount_ecryptfs_drive("/emmc"); - //printf("unmount_ecryptfs_drive: %d\n", r); - - return r; -} - -int main(int argc, char* argv[]) -{ - if(argc < 2) - { - printf("no args!\n"); - return 1; - } - - property_set("ro.crypto.state", "encrypted"); - - property_set("ro.crypto.fs_type", CRYPTO_FS_TYPE); - property_set("ro.crypto.fs_real_blkdev", CRYPTO_REAL_BLKDEV); - property_set("ro.crypto.fs_mnt_point", CRYPTO_MNT_POINT); - property_set("ro.crypto.fs_options", CRYPTO_FS_OPTIONS); - property_set("ro.crypto.fs_flags", CRYPTO_FS_FLAGS); - property_set("ro.crypto.keyfile.userdata", CRYPTO_KEY_LOC); - -#ifdef CRYPTO_SD_FS_TYPE - property_set("ro.crypto.sd_fs_type", CRYPTO_SD_FS_TYPE); - property_set("ro.crypto.sd_fs_real_blkdev", CRYPTO_SD_REAL_BLKDEV); - property_set("ro.crypto.sd_fs_mnt_point", EXPAND(TW_INTERNAL_STORAGE_PATH)); -#endif - - property_set("rw.km_fips_status", "ready"); - - delete_crypto_blk_dev("userdata"); - delete_crypto_blk_dev("sdcard"); - delete_crypto_blk_dev("emmc"); - - cryptfs_check_passwd(argv[1]); - - return 0; -}; diff --git a/crypto/cryptsettings/Android.mk b/crypto/cryptsettings/Android.mk deleted file mode 100644 index 3a5704891..000000000 --- a/crypto/cryptsettings/Android.mk +++ /dev/null @@ -1,17 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) -ifeq ($(TW_INCLUDE_CRYPTO), true) -LOCAL_SRC_FILES:= \ - cryptsettings.c -LOCAL_CFLAGS:= -g -c -W -LOCAL_MODULE:=cryptsettings -LOCAL_MODULE_TAGS:= eng -LOCAL_SHARED_LIBRARIES += libc libcutils -ifeq ($(TW_INCLUDE_JB_CRYPTO), true) -LOCAL_CFLAGS += -DTW_INCLUDE_JB_CRYPTO -LOCAL_STATIC_LIBRARIES += libfs_mgrtwrp -endif -LOCAL_MODULE_CLASS := UTILITY_EXECUTABLES -LOCAL_MODULE_PATH := $(PRODUCT_OUT)/utilities -include $(BUILD_EXECUTABLE) -endif diff --git a/crypto/cryptsettings/cryptsettings.c b/crypto/cryptsettings/cryptsettings.c deleted file mode 100644 index 4fa2b9354..000000000 --- a/crypto/cryptsettings/cryptsettings.c +++ /dev/null @@ -1,55 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#ifdef TW_INCLUDE_JB_CRYPTO -#include "../crypto/fs_mgr/include/fs_mgr.h" -#endif - -#include "cutils/properties.h" - -#ifndef PROPERTY_VALUE_MAX -#define PROPERTY_VALUE_MAX 255 -#endif -#ifndef FSTAB_PREFIX -#define FSTAB_PREFIX "/fstab." -#endif - -int main(void) -{ - char prop[PROPERTY_VALUE_MAX]; - char key_loc[PROPERTY_VALUE_MAX]; - char blk_dev[PROPERTY_VALUE_MAX]; - char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)]; - - printf("This tool will gather the build flags needed for decryption support for TWRP.\n"); - printf("This tool comes with no warranties whatsoever.\n"); - printf("http://teamw.in\n\n"); - property_get("ro.crypto.state", prop, "encrypted"); - if (strcmp(prop, "encrypted") != 0) - printf("Your device is not encrypted, continuing anyway.\n\nTW_INCLUDE_CRYPTO := true\n"); - property_get("ro.crypto.fs_type", prop, "ERROR"); - printf("TW_CRYPTO_FS_TYPE := \"%s\"\n", prop); - property_get("ro.crypto.fs_real_blkdev", prop, "ERROR"); - printf("TW_CRYPTO_REAL_BLKDEV := \"%s\"\n", prop); - property_get("ro.crypto.fs_mnt_point", prop, "ERROR"); - printf("TW_CRYPTO_MNT_POINT := \"%s\"\n", prop); - property_get("ro.crypto.fs_options", prop, "ERROR"); - printf("TW_CRYPTO_FS_OPTIONS := \"%s\"\n", prop); - property_get("ro.crypto.fs_flags", prop, "ERROR"); - printf("TW_CRYPTO_FS_FLAGS := \"%s\"\n", prop); - property_get("ro.crypto.keyfile.userdata", prop, "footer"); - printf("TW_CRYPTO_KEY_LOC := \"%s\"\n", prop); -#ifdef TW_INCLUDE_JB_CRYPTO - printf("\n*** NEW FOR JELLY BEAN:\n"); - strcpy(fstab_filename, FSTAB_PREFIX); - property_get("ro.hardware", fstab_filename + sizeof(FSTAB_PREFIX) - 1, ""); - fs_mgr_get_crypt_info(fstab_filename, key_loc, blk_dev, sizeof(key_loc)); - printf("fstab file location: '%s'\n\nTW_INCLUDE_JB_CRYPTO := true\n", fstab_filename); -#endif - - return 0; -} diff --git a/crypto/crypttools/Android.mk b/crypto/crypttools/Android.mk deleted file mode 100644 index fc62583c4..000000000 --- a/crypto/crypttools/Android.mk +++ /dev/null @@ -1,15 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) -ifeq ($(TW_INCLUDE_JB_CRYPTO), true) -LOCAL_SRC_FILES:= \ - getfooter.c -LOCAL_CFLAGS:= -g -c -W -LOCAL_MODULE:=getfooter -LOCAL_MODULE_TAGS:= eng -LOCAL_STATIC_LIBRARIES += libfs_mgrtwrp libc libcutils -LOCAL_MODULE_CLASS := UTILITY_EXECUTABLES -LOCAL_MODULE_PATH := $(PRODUCT_OUT)/utilities -LOCAL_FORCE_STATIC_EXECUTABLE := true -LOCAL_C_INCLUDES := $(commands_recovery_local_path)/crypto/jb/ -include $(BUILD_EXECUTABLE) -endif \ No newline at end of file diff --git a/crypto/crypttools/getfooter.c b/crypto/crypttools/getfooter.c deleted file mode 100644 index aa7f88e84..000000000 --- a/crypto/crypttools/getfooter.c +++ /dev/null @@ -1,219 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../fs_mgr/include/fs_mgr.h" -#include "cryptfs.h" - -#include "cutils/properties.h" - -#ifndef PROPERTY_VALUE_MAX -#define PROPERTY_VALUE_MAX 255 -#endif -#ifndef FSTAB_PREFIX -#define FSTAB_PREFIX "/fstab." -#endif -#ifndef KEY_IN_FOOTER -#define KEY_IN_FOOTER "footer" -#endif - -struct fstab *fstab; - -static unsigned int get_blkdev_size(int fd) -{ - unsigned int nr_sec; - - if ( (ioctl(fd, BLKGETSIZE, &nr_sec)) == -1) { - nr_sec = 0; - } - - return nr_sec; -} - -int get_crypt_ftr_info(char **metadata_fname, off64_t *off) -{ - static int cached_data = 0; - static off64_t cached_off = 0; - static char cached_metadata_fname[PROPERTY_VALUE_MAX] = ""; - int fd; - char key_loc[PROPERTY_VALUE_MAX]; - char real_blkdev[PROPERTY_VALUE_MAX]; - unsigned int nr_sec; - int rc = -1; - - fs_mgr_get_crypt_info(fstab, key_loc, real_blkdev, sizeof(key_loc)); - - if (!strcmp(key_loc, KEY_IN_FOOTER)) { - if ( (fd = open(real_blkdev, O_RDWR)) < 0) { - printf("Cannot open real block device %s\n", real_blkdev); - return -1; - } - - if ((nr_sec = get_blkdev_size(fd))) { - /* If it's an encrypted Android partition, the last 16 Kbytes contain the - * encryption info footer and key, and plenty of bytes to spare for future - * growth. - */ - strlcpy(cached_metadata_fname, real_blkdev, sizeof(cached_metadata_fname)); - cached_off = ((off64_t)nr_sec * 512) - CRYPT_FOOTER_OFFSET; - cached_data = 1; - } else { - printf("Cannot get size of block device %s\n", real_blkdev); - } - close(fd); - } else { - strlcpy(cached_metadata_fname, key_loc, sizeof(cached_metadata_fname)); - cached_off = 0; - cached_data = 1; - } - - if (cached_data) { - if (metadata_fname) { - *metadata_fname = cached_metadata_fname; - } - if (off) { - *off = cached_off; - } - rc = 0; - } - - return rc; -} - -int get_crypt_ftr_and_key(struct crypt_mnt_ftr *crypt_ftr) -{ - int fd; - unsigned int nr_sec, cnt; - off64_t starting_off; - int rc = -1; - char *fname = NULL; - struct stat statbuf; - - if (get_crypt_ftr_info(&fname, &starting_off)) { - printf("Unable to get crypt_ftr_info\n"); - return -1; - } - if (fname[0] != '/') { - printf("Unexpected value for crypto key location '%s'\n", fname); - //return -1; - } - if ( (fd = open(fname, O_RDWR)) < 0) { - printf("Cannot open footer file %s for get\n", fname); - return -1; - } - - /* Make sure it's 16 Kbytes in length */ - fstat(fd, &statbuf); - if (S_ISREG(statbuf.st_mode) && (statbuf.st_size != 0x4000)) { - printf("footer file %s is not the expected size!\n", fname); - close(fd); - return -1; - } - - /* Seek to the start of the crypt footer */ - if (lseek64(fd, starting_off, SEEK_SET) == -1) { - printf("Cannot seek to real block device footer\n"); - close(fd); - return -1; - } - - if ( (cnt = read(fd, crypt_ftr, sizeof(struct crypt_mnt_ftr))) != sizeof(struct crypt_mnt_ftr)) { - printf("Cannot read real block device footer\n"); - close(fd); - return -1; - } - close(fd); - return 0; -} - -int main(void) -{ - char key_loc[PROPERTY_VALUE_MAX]; - char blk_dev[PROPERTY_VALUE_MAX]; - char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)]; - struct stat st; - struct crypt_mnt_ftr crypt_ftr; - int fdout; - - printf("This tool comes with no warranties whatsoever.\n"); - printf("http://teamw.in\n\n"); - strcpy(fstab_filename, FSTAB_PREFIX); - property_get("ro.hardware", fstab_filename + sizeof(FSTAB_PREFIX) - 1, ""); - - if (stat(fstab_filename, &st) != 0) { - printf("Cannot locate fstab file '%s'\n", fstab_filename); - return -1; - } - - fstab = fs_mgr_read_fstab(fstab_filename); - if (!fstab) { - printf("failed to open %s\n", fstab_filename); - return -1; - } - - fs_mgr_get_crypt_info(fstab, key_loc, blk_dev, sizeof(blk_dev)); - - if (get_crypt_ftr_and_key(&crypt_ftr)) { - printf("Error getting crypt footer and key\n"); - return -1; - } - - if ( (fdout = open("/footerfile", O_WRONLY | O_CREAT, 0644)) < 0) { - printf("Cannot open output file /footerfile\n"); - return -1; - } - if (write(fdout, (void*) &crypt_ftr, sizeof(struct crypt_mnt_ftr)) != sizeof(struct crypt_mnt_ftr)) { - printf("Failed to write footer.\n"); - } - close(fdout); - - if (!strcmp(key_loc, KEY_IN_FOOTER)) { - unsigned int nr_sec, cnt; - off64_t off = 0; - char buffer[CRYPT_FOOTER_OFFSET]; - int fd; - - printf("\n\nDumping footer from '%s'...\n", blk_dev); - if ( (fd = open(blk_dev, O_RDONLY)) < 0) { - printf("Cannot open real block device %s\n", blk_dev); - return -1; - } - - if ((nr_sec = get_blkdev_size(fd))) { - off = ((off64_t)nr_sec * 512) - CRYPT_FOOTER_OFFSET; - } else { - printf("Cannot get size of block device %s\n", blk_dev); - close(fd); - return -1; - } - printf("Size is %llu, offset is %llu\n", ((off64_t)nr_sec * 512), off); - if (lseek64(fd, off, SEEK_SET) == -1) { - printf("Cannot seek to real block device footer\n"); - close(fd); - return -1; - } - - if ( (cnt = read(fd, buffer, sizeof(buffer))) != sizeof(buffer)) { - printf("Cannot read real block device footer\n"); - close(fd); - return -1; - } - close(fd); - if ( (fdout = open("/footerdump", O_WRONLY | O_CREAT, 0644)) < 0) { - printf("Cannot open output file /footerdump\n"); - return -1; - } - if (write(fdout, buffer, sizeof(buffer)) != sizeof(buffer)) { - printf("Failed to write footer.\n"); - } - close(fdout); - } - - return 0; -} diff --git a/crypto/fs_mgr/Android.mk b/crypto/fs_mgr/Android.mk deleted file mode 100644 index 8dd9d4ca2..000000000 --- a/crypto/fs_mgr/Android.mk +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2011 The Android Open Source Project -ifeq ($(TW_INCLUDE_JB_CRYPTO), true) -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= fs_mgr.c fs_mgr_verity.c - -LOCAL_C_INCLUDES := $(LOCAL_PATH)/include - -LOCAL_MODULE:= libfs_mgrtwrp -LOCAL_SHARED_LIBRARIES := libext4_utils -LOCAL_STATIC_LIBRARIES := liblogwraptwrp libmincrypttwrp -LOCAL_C_INCLUDES += \ - system/extras/ext4_utils \ - $(commands_recovery_local_path)/libmincrypt/includes -LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include - -include $(BUILD_STATIC_LIBRARY) - - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= fs_mgr_main.c - -LOCAL_C_INCLUDES := $(LOCAL_PATH)/include - -LOCAL_MODULE:= fs_mgrtwrp - -LOCAL_MODULE_TAGS := optional -LOCAL_FORCE_STATIC_EXECUTABLE := true -LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)/sbin -LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED) - -LOCAL_STATIC_LIBRARIES := libfs_mgrtwrp liblogwraptwrp libcutils liblog libc libmincrypttwrp libext4_utils_static - -include $(BUILD_EXECUTABLE) - -endif diff --git a/crypto/fs_mgr/fs_mgr.c b/crypto/fs_mgr/fs_mgr.c deleted file mode 100644 index 3aa9e6039..000000000 --- a/crypto/fs_mgr/fs_mgr.c +++ /dev/null @@ -1,948 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -//#include -/* XXX These need to be obtained from kernel headers. See b/9336527 */ -#define SWAP_FLAG_PREFER 0x8000 -#define SWAP_FLAG_PRIO_MASK 0x7fff -#define SWAP_FLAG_PRIO_SHIFT 0 -#define SWAP_FLAG_DISCARD 0x10000 - -#include -#include -#include -#include -#include - -#include "mincrypt/rsa.h" -#include "mincrypt/sha.h" -#include "mincrypt/sha256.h" - -#include "fs_mgr_priv.h" -#include "fs_mgr_priv_verity.h" - -#define KEY_LOC_PROP "ro.crypto.keyfile.userdata" -#define KEY_IN_FOOTER "footer" - -#define E2FSCK_BIN "/system/bin/e2fsck" -#define MKSWAP_BIN "/system/bin/mkswap" - -#define FSCK_LOG_FILE "/dev/fscklogs/log" - -#define ZRAM_CONF_DEV "/sys/block/zram0/disksize" - -#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) - -struct flag_list { - const char *name; - unsigned flag; -}; - -static struct flag_list mount_flags[] = { - { "noatime", MS_NOATIME }, - { "noexec", MS_NOEXEC }, - { "nosuid", MS_NOSUID }, - { "nodev", MS_NODEV }, - { "nodiratime", MS_NODIRATIME }, - { "ro", MS_RDONLY }, - { "rw", 0 }, - { "remount", MS_REMOUNT }, - { "bind", MS_BIND }, - { "rec", MS_REC }, - { "unbindable", MS_UNBINDABLE }, - { "private", MS_PRIVATE }, - { "slave", MS_SLAVE }, - { "shared", MS_SHARED }, - { "defaults", 0 }, - { 0, 0 }, -}; - -static struct flag_list fs_mgr_flags[] = { - { "wait", MF_WAIT }, - { "check", MF_CHECK }, - { "encryptable=",MF_CRYPT }, - { "nonremovable",MF_NONREMOVABLE }, - { "voldmanaged=",MF_VOLDMANAGED}, - { "length=", MF_LENGTH }, - { "recoveryonly",MF_RECOVERYONLY }, - { "swapprio=", MF_SWAPPRIO }, - { "zramsize=", MF_ZRAMSIZE }, - { "verify", MF_VERIFY }, - { "noemulatedsd", MF_NOEMULATEDSD }, - { "defaults", 0 }, - { 0, 0 }, -}; - -struct fs_mgr_flag_values { - char *key_loc; - long long part_length; - char *label; - int partnum; - int swap_prio; - unsigned int zram_size; -}; - -/* - * gettime() - returns the time in seconds of the system's monotonic clock or - * zero on error. - */ -static time_t gettime(void) -{ - struct timespec ts; - int ret; - - ret = clock_gettime(CLOCK_MONOTONIC, &ts); - if (ret < 0) { - ERROR("clock_gettime(CLOCK_MONOTONIC) failed: %s\n", strerror(errno)); - return 0; - } - - return ts.tv_sec; -} - -static int wait_for_file(const char *filename, int timeout) -{ - struct stat info; - time_t timeout_time = gettime() + timeout; - int ret = -1; - - while (gettime() < timeout_time && ((ret = stat(filename, &info)) < 0)) - usleep(10000); - - return ret; -} - -static int parse_flags(char *flags, struct flag_list *fl, - struct fs_mgr_flag_values *flag_vals, - char *fs_options, int fs_options_len) -{ - int f = 0; - int i; - char *p; - char *savep; - - /* initialize flag values. If we find a relevant flag, we'll - * update the value */ - if (flag_vals) { - memset(flag_vals, 0, sizeof(*flag_vals)); - flag_vals->partnum = -1; - flag_vals->swap_prio = -1; /* negative means it wasn't specified. */ - } - - /* initialize fs_options to the null string */ - if (fs_options && (fs_options_len > 0)) { - fs_options[0] = '\0'; - } - - p = strtok_r(flags, ",", &savep); - while (p) { - /* Look for the flag "p" in the flag list "fl" - * If not found, the loop exits with fl[i].name being null. - */ - for (i = 0; fl[i].name; i++) { - if (!strncmp(p, fl[i].name, strlen(fl[i].name))) { - f |= fl[i].flag; - if ((fl[i].flag == MF_CRYPT) && flag_vals) { - /* The encryptable flag is followed by an = and the - * location of the keys. Get it and return it. - */ - flag_vals->key_loc = strdup(strchr(p, '=') + 1); - } else if ((fl[i].flag == MF_LENGTH) && flag_vals) { - /* The length flag is followed by an = and the - * size of the partition. Get it and return it. - */ - flag_vals->part_length = strtoll(strchr(p, '=') + 1, NULL, 0); - } else if ((fl[i].flag == MF_VOLDMANAGED) && flag_vals) { - /* The voldmanaged flag is followed by an = and the - * label, a colon and the partition number or the - * word "auto", e.g. - * voldmanaged=sdcard:3 - * Get and return them. - */ - char *label_start; - char *label_end; - char *part_start; - - label_start = strchr(p, '=') + 1; - label_end = strchr(p, ':'); - if (label_end) { - flag_vals->label = strndup(label_start, - (int) (label_end - label_start)); - part_start = strchr(p, ':') + 1; - if (!strcmp(part_start, "auto")) { - flag_vals->partnum = -1; - } else { - flag_vals->partnum = strtol(part_start, NULL, 0); - } - } else { - ERROR("Warning: voldmanaged= flag malformed\n"); - } - } else if ((fl[i].flag == MF_SWAPPRIO) && flag_vals) { - flag_vals->swap_prio = strtoll(strchr(p, '=') + 1, NULL, 0); - } else if ((fl[i].flag == MF_ZRAMSIZE) && flag_vals) { - flag_vals->zram_size = strtoll(strchr(p, '=') + 1, NULL, 0); - } - break; - } - } - - if (!fl[i].name) { - if (fs_options) { - /* It's not a known flag, so it must be a filesystem specific - * option. Add it to fs_options if it was passed in. - */ - strlcat(fs_options, p, fs_options_len); - strlcat(fs_options, ",", fs_options_len); - } else { - /* fs_options was not passed in, so if the flag is unknown - * it's an error. - */ - ERROR("Warning: unknown flag %s\n", p); - } - } - p = strtok_r(NULL, ",", &savep); - } - -out: - if (fs_options && fs_options[0]) { - /* remove the last trailing comma from the list of options */ - fs_options[strlen(fs_options) - 1] = '\0'; - } - - return f; -} - -/* Read a line of text till the next newline character. - * If no newline is found before the buffer is full, continue reading till a new line is seen, - * then return an empty buffer. This effectively ignores lines that are too long. - * On EOF, return null. - */ -static char *fs_getline(char *buf, int size, FILE *file) -{ - int cnt = 0; - int eof = 0; - int eol = 0; - int c; - - if (size < 1) { - return NULL; - } - - while (cnt < (size - 1)) { - c = getc(file); - if (c == EOF) { - eof = 1; - break; - } - - *(buf + cnt) = c; - cnt++; - - if (c == '\n') { - eol = 1; - break; - } - } - - /* Null terminate what we've read */ - *(buf + cnt) = '\0'; - - if (eof) { - if (cnt) { - return buf; - } else { - return NULL; - } - } else if (eol) { - return buf; - } else { - /* The line is too long. Read till a newline or EOF. - * If EOF, return null, if newline, return an empty buffer. - */ - while(1) { - c = getc(file); - if (c == EOF) { - return NULL; - } else if (c == '\n') { - *buf = '\0'; - return buf; - } - } - } -} - -struct fstab *fs_mgr_read_fstab(const char *fstab_path) -{ - FILE *fstab_file; - int cnt, entries; - int len; - char line[256]; - const char *delim = " \t"; - char *save_ptr, *p; - struct fstab *fstab; - struct fstab_rec *recs; - struct fs_mgr_flag_values flag_vals; -#define FS_OPTIONS_LEN 1024 - char tmp_fs_options[FS_OPTIONS_LEN]; - - fstab_file = fopen(fstab_path, "r"); - if (!fstab_file) { - ERROR("Cannot open file %s\n", fstab_path); - return 0; - } - - entries = 0; - while (fs_getline(line, sizeof(line), fstab_file)) { - /* if the last character is a newline, shorten the string by 1 byte */ - len = strlen(line); - if (line[len - 1] == '\n') { - line[len - 1] = '\0'; - } - /* Skip any leading whitespace */ - p = line; - while (isspace(*p)) { - p++; - } - /* ignore comments or empty lines */ - if (*p == '#' || *p == '\0') - continue; - entries++; - } - - if (!entries) { - ERROR("No entries found in fstab\n"); - return 0; - } - - /* Allocate and init the fstab structure */ - fstab = calloc(1, sizeof(struct fstab)); - fstab->num_entries = entries; - fstab->fstab_filename = strdup(fstab_path); - fstab->recs = calloc(fstab->num_entries, sizeof(struct fstab_rec)); - - fseek(fstab_file, 0, SEEK_SET); - - cnt = 0; - while (fs_getline(line, sizeof(line), fstab_file)) { - /* if the last character is a newline, shorten the string by 1 byte */ - len = strlen(line); - if (line[len - 1] == '\n') { - line[len - 1] = '\0'; - } - - /* Skip any leading whitespace */ - p = line; - while (isspace(*p)) { - p++; - } - /* ignore comments or empty lines */ - if (*p == '#' || *p == '\0') - continue; - - /* If a non-comment entry is greater than the size we allocated, give an - * error and quit. This can happen in the unlikely case the file changes - * between the two reads. - */ - if (cnt >= entries) { - ERROR("Tried to process more entries than counted\n"); - break; - } - - if (!(p = strtok_r(line, delim, &save_ptr))) { - ERROR("Error parsing mount source\n"); - return 0; - } - fstab->recs[cnt].blk_device = strdup(p); - - if (!(p = strtok_r(NULL, delim, &save_ptr))) { - ERROR("Error parsing mount_point\n"); - return 0; - } - fstab->recs[cnt].mount_point = strdup(p); - - if (!(p = strtok_r(NULL, delim, &save_ptr))) { - ERROR("Error parsing fs_type\n"); - return 0; - } - fstab->recs[cnt].fs_type = strdup(p); - - if (!(p = strtok_r(NULL, delim, &save_ptr))) { - ERROR("Error parsing mount_flags\n"); - return 0; - } - tmp_fs_options[0] = '\0'; - fstab->recs[cnt].flags = parse_flags(p, mount_flags, NULL, - tmp_fs_options, FS_OPTIONS_LEN); - - /* fs_options are optional */ - if (tmp_fs_options[0]) { - fstab->recs[cnt].fs_options = strdup(tmp_fs_options); - } else { - fstab->recs[cnt].fs_options = NULL; - } - - if (!(p = strtok_r(NULL, delim, &save_ptr))) { - ERROR("Error parsing fs_mgr_options\n"); - return 0; - } - fstab->recs[cnt].fs_mgr_flags = parse_flags(p, fs_mgr_flags, - &flag_vals, NULL, 0); - fstab->recs[cnt].key_loc = flag_vals.key_loc; - fstab->recs[cnt].length = flag_vals.part_length; - fstab->recs[cnt].label = flag_vals.label; - fstab->recs[cnt].partnum = flag_vals.partnum; - fstab->recs[cnt].swap_prio = flag_vals.swap_prio; - fstab->recs[cnt].zram_size = flag_vals.zram_size; - cnt++; - } - fclose(fstab_file); - - return fstab; -} - -void fs_mgr_free_fstab(struct fstab *fstab) -{ - int i; - - if (!fstab) { - return; - } - - for (i = 0; i < fstab->num_entries; i++) { - /* Free the pointers return by strdup(3) */ - free(fstab->recs[i].blk_device); - free(fstab->recs[i].mount_point); - free(fstab->recs[i].fs_type); - free(fstab->recs[i].fs_options); - free(fstab->recs[i].key_loc); - free(fstab->recs[i].label); - i++; - } - - /* Free the fstab_recs array created by calloc(3) */ - free(fstab->recs); - - /* Free the fstab filename */ - free(fstab->fstab_filename); - - /* Free fstab */ - free(fstab); -} - -static void check_fs(char *blk_device, char *fs_type, char *target) -{ - int status; - int ret; - long tmpmnt_flags = MS_NOATIME | MS_NOEXEC | MS_NOSUID; - char *tmpmnt_opts = "nomblk_io_submit,errors=remount-ro"; - char *e2fsck_argv[] = { - E2FSCK_BIN, - "-y", - blk_device - }; - - /* Check for the types of filesystems we know how to check */ - if (!strcmp(fs_type, "ext2") || !strcmp(fs_type, "ext3") || !strcmp(fs_type, "ext4")) { - /* - * First try to mount and unmount the filesystem. We do this because - * the kernel is more efficient than e2fsck in running the journal and - * processing orphaned inodes, and on at least one device with a - * performance issue in the emmc firmware, it can take e2fsck 2.5 minutes - * to do what the kernel does in about a second. - * - * After mounting and unmounting the filesystem, run e2fsck, and if an - * error is recorded in the filesystem superblock, e2fsck will do a full - * check. Otherwise, it does nothing. If the kernel cannot mount the - * filesytsem due to an error, e2fsck is still run to do a full check - * fix the filesystem. - */ - ret = mount(blk_device, target, fs_type, tmpmnt_flags, tmpmnt_opts); - if (!ret) { - umount(target); - } - - INFO("Running %s on %s\n", E2FSCK_BIN, blk_device); - - ret = android_fork_execvp_ext(ARRAY_SIZE(e2fsck_argv), e2fsck_argv, - &status, true, LOG_KLOG | LOG_FILE, - true, FSCK_LOG_FILE); - - if (ret < 0) { - /* No need to check for error in fork, we can't really handle it now */ - ERROR("Failed trying to run %s\n", E2FSCK_BIN); - } - } - - return; -} - -static void remove_trailing_slashes(char *n) -{ - int len; - - len = strlen(n) - 1; - while ((*(n + len) == '/') && len) { - *(n + len) = '\0'; - len--; - } -} - -/* - * Mark the given block device as read-only, using the BLKROSET ioctl. - * Return 0 on success, and -1 on error. - */ -static void fs_set_blk_ro(const char *blockdev) -{ - int fd; - int ON = 1; - - fd = open(blockdev, O_RDONLY); - if (fd < 0) { - // should never happen - return; - } - - ioctl(fd, BLKROSET, &ON); - close(fd); -} - -/* - * __mount(): wrapper around the mount() system call which also - * sets the underlying block device to read-only if the mount is read-only. - * See "man 2 mount" for return values. - */ -static int __mount(const char *source, const char *target, - const char *filesystemtype, unsigned long mountflags, - const void *data) -{ - int ret = mount(source, target, filesystemtype, mountflags, data); - - if ((ret == 0) && (mountflags & MS_RDONLY) != 0) { - fs_set_blk_ro(source); - } - - return ret; -} - -static int fs_match(char *in1, char *in2) -{ - char *n1; - char *n2; - int ret; - - n1 = strdup(in1); - n2 = strdup(in2); - - remove_trailing_slashes(n1); - remove_trailing_slashes(n2); - - ret = !strcmp(n1, n2); - - free(n1); - free(n2); - - return ret; -} - -int fs_mgr_mount_all(struct fstab *fstab) -{ - int i = 0; - int encrypted = 0; - int ret = -1; - int mret; - - if (!fstab) { - return ret; - } - - for (i = 0; i < fstab->num_entries; i++) { - /* Don't mount entries that are managed by vold */ - if (fstab->recs[i].fs_mgr_flags & (MF_VOLDMANAGED | MF_RECOVERYONLY)) { - continue; - } - - /* Skip swap and raw partition entries such as boot, recovery, etc */ - if (!strcmp(fstab->recs[i].fs_type, "swap") || - !strcmp(fstab->recs[i].fs_type, "emmc") || - !strcmp(fstab->recs[i].fs_type, "mtd")) { - continue; - } - - if (fstab->recs[i].fs_mgr_flags & MF_WAIT) { - wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT); - } - - if (fstab->recs[i].fs_mgr_flags & MF_CHECK) { - check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type, - fstab->recs[i].mount_point); - } - - if (fstab->recs[i].fs_mgr_flags & MF_VERIFY) { - if (fs_mgr_setup_verity(&fstab->recs[i]) < 0) { - ERROR("Could not set up verified partition, skipping!"); - continue; - } - } - - mret = __mount(fstab->recs[i].blk_device, fstab->recs[i].mount_point, - fstab->recs[i].fs_type, fstab->recs[i].flags, - fstab->recs[i].fs_options); - - if (!mret) { - /* Success! Go get the next one */ - continue; - } - - /* mount(2) returned an error, check if it's encrypted and deal with it */ - if ((fstab->recs[i].fs_mgr_flags & MF_CRYPT) && - !partition_wiped(fstab->recs[i].blk_device)) { - /* Need to mount a tmpfs at this mountpoint for now, and set - * properties that vold will query later for decrypting - */ - if (mount("tmpfs", fstab->recs[i].mount_point, "tmpfs", - MS_NOATIME | MS_NOSUID | MS_NODEV, CRYPTO_TMPFS_OPTIONS) < 0) { - ERROR("Cannot mount tmpfs filesystem for encrypted fs at %s\n", - fstab->recs[i].mount_point); - goto out; - } - encrypted = 1; - } else { - ERROR("Cannot mount filesystem on %s at %s\n", - fstab->recs[i].blk_device, fstab->recs[i].mount_point); - goto out; - } - } - - if (encrypted) { - ret = 1; - } else { - ret = 0; - } - -out: - return ret; -} - -/* If tmp_mount_point is non-null, mount the filesystem there. This is for the - * tmp mount we do to check the user password - */ -int fs_mgr_do_mount(struct fstab *fstab, char *n_name, char *n_blk_device, - char *tmp_mount_point) -{ - int i = 0; - int ret = -1; - char *m; - - if (!fstab) { - return ret; - } - - for (i = 0; i < fstab->num_entries; i++) { - if (!fs_match(fstab->recs[i].mount_point, n_name)) { - continue; - } - - /* We found our match */ - /* If this swap or a raw partition, report an error */ - if (!strcmp(fstab->recs[i].fs_type, "swap") || - !strcmp(fstab->recs[i].fs_type, "emmc") || - !strcmp(fstab->recs[i].fs_type, "mtd")) { - ERROR("Cannot mount filesystem of type %s on %s\n", - fstab->recs[i].fs_type, n_blk_device); - goto out; - } - - /* First check the filesystem if requested */ - if (fstab->recs[i].fs_mgr_flags & MF_WAIT) { - wait_for_file(n_blk_device, WAIT_TIMEOUT); - } - - if (fstab->recs[i].fs_mgr_flags & MF_CHECK) { - check_fs(n_blk_device, fstab->recs[i].fs_type, - fstab->recs[i].mount_point); - } - - if (fstab->recs[i].fs_mgr_flags & MF_VERIFY) { - if (fs_mgr_setup_verity(&fstab->recs[i]) < 0) { - ERROR("Could not set up verified partition, skipping!"); - continue; - } - } - - /* Now mount it where requested */ - if (tmp_mount_point) { - m = tmp_mount_point; - } else { - m = fstab->recs[i].mount_point; - } - if (__mount(n_blk_device, m, fstab->recs[i].fs_type, - fstab->recs[i].flags, fstab->recs[i].fs_options)) { - ERROR("Cannot mount filesystem on %s at %s\n", - n_blk_device, m); - goto out; - } else { - ret = 0; - goto out; - } - } - - /* We didn't find a match, say so and return an error */ - ERROR("Cannot find mount point %s in fstab\n", fstab->recs[i].mount_point); - -out: - return ret; -} - -/* - * mount a tmpfs filesystem at the given point. - * return 0 on success, non-zero on failure. - */ -int fs_mgr_do_tmpfs_mount(char *n_name) -{ - int ret; - - ret = mount("tmpfs", n_name, "tmpfs", - MS_NOATIME | MS_NOSUID | MS_NODEV, CRYPTO_TMPFS_OPTIONS); - if (ret < 0) { - ERROR("Cannot mount tmpfs filesystem at %s\n", n_name); - return -1; - } - - /* Success */ - return 0; -} - -int fs_mgr_unmount_all(struct fstab *fstab) -{ - int i = 0; - int ret = 0; - - if (!fstab) { - return -1; - } - - while (fstab->recs[i].blk_device) { - if (umount(fstab->recs[i].mount_point)) { - ERROR("Cannot unmount filesystem at %s\n", fstab->recs[i].mount_point); - ret = -1; - } - i++; - } - - return ret; -} - -/* This must be called after mount_all, because the mkswap command needs to be - * available. - */ -int fs_mgr_swapon_all(struct fstab *fstab) -{ - int i = 0; - int flags = 0; - int err = 0; - int ret = 0; - int status; - char *mkswap_argv[2] = { - MKSWAP_BIN, - NULL - }; - - if (!fstab) { - return -1; - } - - for (i = 0; i < fstab->num_entries; i++) { - /* Skip non-swap entries */ - if (strcmp(fstab->recs[i].fs_type, "swap")) { - continue; - } - - if (fstab->recs[i].zram_size > 0) { - /* A zram_size was specified, so we need to configure the - * device. There is no point in having multiple zram devices - * on a system (all the memory comes from the same pool) so - * we can assume the device number is 0. - */ - FILE *zram_fp; - - zram_fp = fopen(ZRAM_CONF_DEV, "r+"); - if (zram_fp == NULL) { - ERROR("Unable to open zram conf device " ZRAM_CONF_DEV); - ret = -1; - continue; - } - fprintf(zram_fp, "%d\n", fstab->recs[i].zram_size); - fclose(zram_fp); - } - - if (fstab->recs[i].fs_mgr_flags & MF_WAIT) { - wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT); - } - - /* Initialize the swap area */ - mkswap_argv[1] = fstab->recs[i].blk_device; - err = android_fork_execvp_ext(ARRAY_SIZE(mkswap_argv), mkswap_argv, - &status, true, LOG_KLOG, false, NULL); - if (err) { - ERROR("mkswap failed for %s\n", fstab->recs[i].blk_device); - ret = -1; - continue; - } - - /* If -1, then no priority was specified in fstab, so don't set - * SWAP_FLAG_PREFER or encode the priority */ - if (fstab->recs[i].swap_prio >= 0) { - flags = (fstab->recs[i].swap_prio << SWAP_FLAG_PRIO_SHIFT) & - SWAP_FLAG_PRIO_MASK; - flags |= SWAP_FLAG_PREFER; - } else { - flags = 0; - } - // requires sys/swap.h which is not available in older trees - // this entire function does not appear to be used for decrypt - err = -1; //swapon(fstab->recs[i].blk_device, flags); - if (err) { - ERROR("swapon failed for %s\n", fstab->recs[i].blk_device); - ret = -1; - } - } - - return ret; -} - -/* - * key_loc must be at least PROPERTY_VALUE_MAX bytes long - * - * real_blk_device must be at least PROPERTY_VALUE_MAX bytes long - */ -int fs_mgr_get_crypt_info(struct fstab *fstab, char *key_loc, char *real_blk_device, int size) -{ - int i = 0; - - if (!fstab) { - return -1; - } - /* Initialize return values to null strings */ - if (key_loc) { - *key_loc = '\0'; - } - if (real_blk_device) { - *real_blk_device = '\0'; - } - - /* Look for the encryptable partition to find the data */ - for (i = 0; i < fstab->num_entries; i++) { - /* Don't deal with vold managed enryptable partitions here */ - if (fstab->recs[i].fs_mgr_flags & MF_VOLDMANAGED) { - continue; - } - if (!(fstab->recs[i].fs_mgr_flags & MF_CRYPT)) { - continue; - } - - /* We found a match */ - if (key_loc) { - strlcpy(key_loc, fstab->recs[i].key_loc, size); - } - if (real_blk_device) { - strlcpy(real_blk_device, fstab->recs[i].blk_device, size); - } - break; - } - - return 0; -} - -/* Add an entry to the fstab, and return 0 on success or -1 on error */ -int fs_mgr_add_entry(struct fstab *fstab, - const char *mount_point, const char *fs_type, - const char *blk_device, long long length) -{ - struct fstab_rec *new_fstab_recs; - int n = fstab->num_entries; - - new_fstab_recs = (struct fstab_rec *) - realloc(fstab->recs, sizeof(struct fstab_rec) * (n + 1)); - - if (!new_fstab_recs) { - return -1; - } - - /* A new entry was added, so initialize it */ - memset(&new_fstab_recs[n], 0, sizeof(struct fstab_rec)); - new_fstab_recs[n].mount_point = strdup(mount_point); - new_fstab_recs[n].fs_type = strdup(fs_type); - new_fstab_recs[n].blk_device = strdup(blk_device); - new_fstab_recs[n].length = 0; - - /* Update the fstab struct */ - fstab->recs = new_fstab_recs; - fstab->num_entries++; - - return 0; -} - -struct fstab_rec *fs_mgr_get_entry_for_mount_point(struct fstab *fstab, const char *path) -{ - int i; - - if (!fstab) { - return NULL; - } - - for (i = 0; i < fstab->num_entries; i++) { - int len = strlen(fstab->recs[i].mount_point); - if (strncmp(path, fstab->recs[i].mount_point, len) == 0 && - (path[len] == '\0' || path[len] == '/')) { - return &fstab->recs[i]; - } - } - - return NULL; -} - -int fs_mgr_is_voldmanaged(struct fstab_rec *fstab) -{ - return fstab->fs_mgr_flags & MF_VOLDMANAGED; -} - -int fs_mgr_is_nonremovable(struct fstab_rec *fstab) -{ - return fstab->fs_mgr_flags & MF_NONREMOVABLE; -} - -int fs_mgr_is_encryptable(struct fstab_rec *fstab) -{ - return fstab->fs_mgr_flags & MF_CRYPT; -} - -int fs_mgr_is_noemulatedsd(struct fstab_rec *fstab) -{ - return fstab->fs_mgr_flags & MF_NOEMULATEDSD; -} diff --git a/crypto/fs_mgr/fs_mgr_main.c b/crypto/fs_mgr/fs_mgr_main.c deleted file mode 100644 index 4bde4a1da..000000000 --- a/crypto/fs_mgr/fs_mgr_main.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source 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. - */ - -#include -#include -#include -#include -#include "fs_mgr_priv.h" - -char *me = ""; - -static void usage(void) -{ - ERROR("%s: usage: %s <-a | -n mnt_point blk_dev | -u> \n", me, me); - exit(1); -} - -/* Parse the command line. If an error is encountered, print an error message - * and exit the program, do not return to the caller. - * Return the number of argv[] entries consumed. - */ -static void parse_options(int argc, char *argv[], int *a_flag, int *u_flag, int *n_flag, - char **n_name, char **n_blk_dev) -{ - me = basename(strdup(argv[0])); - - if (argc <= 1) { - usage(); - } - - if (!strcmp(argv[1], "-a")) { - if (argc != 3) { - usage(); - } - *a_flag = 1; - } - if (!strcmp(argv[1], "-n")) { - if (argc != 5) { - usage(); - } - *n_flag = 1; - *n_name = argv[2]; - *n_blk_dev = argv[3]; - } - if (!strcmp(argv[1], "-u")) { - if (argc != 3) { - usage(); - } - *u_flag = 1; - } - - /* If no flag is specified, it's an error */ - if (!(*a_flag | *n_flag | *u_flag)) { - usage(); - } - - /* If more than one flag is specified, it's an error */ - if ((*a_flag + *n_flag + *u_flag) > 1) { - usage(); - } - - return; -} - -int main(int argc, char *argv[]) -{ - int a_flag=0; - int u_flag=0; - int n_flag=0; - char *n_name; - char *n_blk_dev; - char *fstab_file; - struct fstab *fstab; - - klog_init(); - klog_set_level(6); - - parse_options(argc, argv, &a_flag, &u_flag, &n_flag, &n_name, &n_blk_dev); - - /* The name of the fstab file is last, after the option */ - fstab_file = argv[argc - 1]; - - fstab = fs_mgr_read_fstab(fstab_file); - - if (a_flag) { - return fs_mgr_mount_all(fstab); - } else if (n_flag) { - return fs_mgr_do_mount(fstab, n_name, n_blk_dev, 0); - } else if (u_flag) { - return fs_mgr_unmount_all(fstab); - } else { - ERROR("%s: Internal error, unknown option\n", me); - exit(1); - } - - fs_mgr_free_fstab(fstab); - - /* Should not get here */ - exit(1); -} - diff --git a/crypto/fs_mgr/fs_mgr_priv.h b/crypto/fs_mgr/fs_mgr_priv.h deleted file mode 100644 index 59ffd785c..000000000 --- a/crypto/fs_mgr/fs_mgr_priv.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source 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. - */ - -#ifndef __CORE_FS_MGR_PRIV_H -#define __CORE_FS_MGR_PRIV_H - -#include -#include - -#define INFO(x...) KLOG_INFO("fs_mgr", x) -#define ERROR(x...) KLOG_ERROR("fs_mgr", x) - -#define CRYPTO_TMPFS_OPTIONS "size=128m,mode=0771,uid=1000,gid=1000" - -#define WAIT_TIMEOUT 20 - -/* fstab has the following format: - * - * Any line starting with a # is a comment and ignored - * - * Any blank line is ignored - * - * All other lines must be in this format: - * - * - * is a comma separated list of flags that can be passed to the - * mount command. The list includes noatime, nosuid, nodev, nodiratime, - * ro, rw, remount, defaults. - * - * is a comma separated list of options accepted by the filesystem being - * mounted. It is passed directly to mount without being parsed - * - * is a comma separated list of flags that control the operation of - * the fs_mgr program. The list includes "wait", which will wait till - * the file exists, and "check", which requests that the fs_mgr - * run an fscheck program on the before mounting the filesystem. - * If check is specifed on a read-only filesystem, it is ignored. - * Also, "encryptable" means that filesystem can be encrypted. - * The "encryptable" flag _MUST_ be followed by a = and a string which - * is the location of the encryption keys. It can either be a path - * to a file or partition which contains the keys, or the word "footer" - * which means the keys are in the last 16 Kbytes of the partition - * containing the filesystem. - * - * When the fs_mgr is requested to mount all filesystems, it will first mount all the - * filesystems that do _NOT_ specify check (including filesystems that are read-only and - * specify check, because check is ignored in that case) and then it will check and mount - * filesystem marked with check. - * - */ - -#define MF_WAIT 0x1 -#define MF_CHECK 0x2 -#define MF_CRYPT 0x4 -#define MF_NONREMOVABLE 0x8 -#define MF_VOLDMANAGED 0x10 -#define MF_LENGTH 0x20 -#define MF_RECOVERYONLY 0x40 -#define MF_SWAPPRIO 0x80 -#define MF_ZRAMSIZE 0x100 -#define MF_VERIFY 0x200 -/* - * There is no emulated sdcard daemon running on /data/media on this device, - * so treat the physical SD card as the only external storage device, - * a la the Nexus One. - */ -#define MF_NOEMULATEDSD 0x400 - -#define DM_BUF_SIZE 4096 - -#endif /* __CORE_FS_MGR_PRIV_H */ - diff --git a/crypto/fs_mgr/fs_mgr_priv_verity.h b/crypto/fs_mgr/fs_mgr_priv_verity.h deleted file mode 100644 index 61937849a..000000000 --- a/crypto/fs_mgr/fs_mgr_priv_verity.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source 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. - */ - -int fs_mgr_setup_verity(struct fstab_rec *fstab); \ No newline at end of file diff --git a/crypto/fs_mgr/fs_mgr_verity.c b/crypto/fs_mgr/fs_mgr_verity.c deleted file mode 100644 index 969eab2a0..000000000 --- a/crypto/fs_mgr/fs_mgr_verity.c +++ /dev/null @@ -1,410 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "mincrypt/rsa.h" -#include "mincrypt/sha.h" -#include "mincrypt/sha256.h" - -#include "ext4_utils.h" -#include "ext4.h" - -#include "fs_mgr_priv.h" -#include "fs_mgr_priv_verity.h" - -#define VERITY_METADATA_SIZE 32768 -#define VERITY_METADATA_MAGIC_NUMBER 0xb001b001 -#define VERITY_TABLE_RSA_KEY "/verity_key" - -extern struct fs_info info; - -static RSAPublicKey *load_key(char *path) -{ - FILE *f; - RSAPublicKey *key; - - key = malloc(sizeof(RSAPublicKey)); - if (!key) { - ERROR("Can't malloc key\n"); - return NULL; - } - - f = fopen(path, "r"); - if (!f) { - ERROR("Can't open '%s'\n", path); - free(key); - return NULL; - } - - if (!fread(key, sizeof(*key), 1, f)) { - ERROR("Could not read key!"); - fclose(f); - free(key); - return NULL; - } - - if (key->len != RSANUMWORDS) { - ERROR("Invalid key length %d\n", key->len); - fclose(f); - free(key); - return NULL; - } - - fclose(f); - return key; -} - -static int verify_table(char *signature, char *table, int table_length) -{ - int fd; - RSAPublicKey *key; - uint8_t hash_buf[SHA_DIGEST_SIZE]; - int retval = -1; - - // Hash the table - SHA_hash((uint8_t*)table, table_length, hash_buf); - - // Now get the public key from the keyfile - key = load_key(VERITY_TABLE_RSA_KEY); - if (!key) { - ERROR("Couldn't load verity keys"); - goto out; - } - - // verify the result - if (!RSA_verify(key, - (uint8_t*) signature, - RSANUMBYTES, - (uint8_t*) hash_buf, - SHA_DIGEST_SIZE)) { - ERROR("Couldn't verify table."); - goto out; - } - - retval = 0; - -out: - free(key); - return retval; -} - -static int get_target_device_size(char *blk_device, uint64_t *device_size) -{ - int data_device; - struct ext4_super_block sb; - - data_device = open(blk_device, O_RDONLY); - if (data_device < 0) { - ERROR("Error opening block device (%s)", strerror(errno)); - return -1; - } - - if (lseek64(data_device, 1024, SEEK_SET) < 0) { - ERROR("Error seeking to superblock"); - close(data_device); - return -1; - } - - if (read(data_device, &sb, sizeof(sb)) != sizeof(sb)) { - ERROR("Error reading superblock"); - close(data_device); - return -1; - } - - ext4_parse_sb(&sb); - *device_size = info.len; - - close(data_device); - return 0; -} - -static int read_verity_metadata(char *block_device, char **signature, char **table) -{ - unsigned magic_number; - unsigned table_length; - uint64_t device_length; - int protocol_version; - FILE *device; - int retval = -1; - - device = fopen(block_device, "r"); - if (!device) { - ERROR("Could not open block device %s (%s).\n", block_device, strerror(errno)); - goto out; - } - - // find the start of the verity metadata - if (get_target_device_size(block_device, &device_length) < 0) { - ERROR("Could not get target device size.\n"); - goto out; - } - if (fseek(device, device_length, SEEK_SET) < 0) { - ERROR("Could not seek to start of verity metadata block.\n"); - goto out; - } - - // check the magic number - if (!fread(&magic_number, sizeof(int), 1, device)) { - ERROR("Couldn't read magic number!\n"); - goto out; - } - if (magic_number != VERITY_METADATA_MAGIC_NUMBER) { - ERROR("Couldn't find verity metadata at offset %llu!\n", device_length); - goto out; - } - - // check the protocol version - if (!fread(&protocol_version, sizeof(int), 1, device)) { - ERROR("Couldn't read verity metadata protocol version!\n"); - goto out; - } - if (protocol_version != 0) { - ERROR("Got unknown verity metadata protocol version %d!\n", protocol_version); - goto out; - } - - // get the signature - *signature = (char*) malloc(RSANUMBYTES * sizeof(char)); - if (!*signature) { - ERROR("Couldn't allocate memory for signature!\n"); - goto out; - } - if (!fread(*signature, RSANUMBYTES, 1, device)) { - ERROR("Couldn't read signature from verity metadata!\n"); - free(*signature); - goto out; - } - - // get the size of the table - if (!fread(&table_length, sizeof(int), 1, device)) { - ERROR("Couldn't get the size of the verity table from metadata!\n"); - free(*signature); - goto out; - } - - // get the table + null terminator - table_length += 1; - *table = malloc(table_length); - if(!*table) { - ERROR("Couldn't allocate memory for verity table!\n"); - goto out; - } - if (!fgets(*table, table_length, device)) { - ERROR("Couldn't read the verity table from metadata!\n"); - free(*table); - free(*signature); - goto out; - } - - retval = 0; - -out: - if (device) - fclose(device); - return retval; -} - -static void verity_ioctl_init(struct dm_ioctl *io, char *name, unsigned flags) -{ - memset(io, 0, DM_BUF_SIZE); - io->data_size = DM_BUF_SIZE; - io->data_start = sizeof(struct dm_ioctl); - io->version[0] = 4; - io->version[1] = 0; - io->version[2] = 0; - io->flags = flags | DM_READONLY_FLAG; - if (name) { - strlcpy(io->name, name, sizeof(io->name)); - } -} - -static int create_verity_device(struct dm_ioctl *io, char *name, int fd) -{ - verity_ioctl_init(io, name, 1); - if (ioctl(fd, DM_DEV_CREATE, io)) { - ERROR("Error creating device mapping (%s)", strerror(errno)); - return -1; - } - return 0; -} - -static int get_verity_device_name(struct dm_ioctl *io, char *name, int fd, char **dev_name) -{ - verity_ioctl_init(io, name, 0); - if (ioctl(fd, DM_DEV_STATUS, io)) { - ERROR("Error fetching verity device number (%s)", strerror(errno)); - return -1; - } - int dev_num = (io->dev & 0xff) | ((io->dev >> 12) & 0xfff00); - if (asprintf(dev_name, "/dev/block/dm-%u", dev_num) < 0) { - ERROR("Error getting verity block device name (%s)", strerror(errno)); - return -1; - } - return 0; -} - -static int load_verity_table(struct dm_ioctl *io, char *name, char *blockdev, int fd, char *table) -{ - char *verity_params; - char *buffer = (char*) io; - uint64_t device_size = 0; - - if (get_target_device_size(blockdev, &device_size) < 0) { - return -1; - } - - verity_ioctl_init(io, name, DM_STATUS_TABLE_FLAG); - - struct dm_target_spec *tgt = (struct dm_target_spec *) &buffer[sizeof(struct dm_ioctl)]; - - // set tgt arguments here - io->target_count = 1; - tgt->status=0; - tgt->sector_start=0; - tgt->length=device_size/512; - strcpy(tgt->target_type, "verity"); - - // build the verity params here - verity_params = buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec); - if (sprintf(verity_params, "%s", table) < 0) { - return -1; - } - - // set next target boundary - verity_params += strlen(verity_params) + 1; - verity_params = (char*) (((unsigned long)verity_params + 7) & ~8); - tgt->next = verity_params - buffer; - - // send the ioctl to load the verity table - if (ioctl(fd, DM_TABLE_LOAD, io)) { - ERROR("Error loading verity table (%s)", strerror(errno)); - return -1; - } - - return 0; -} - -static int resume_verity_table(struct dm_ioctl *io, char *name, int fd) -{ - verity_ioctl_init(io, name, 0); - if (ioctl(fd, DM_DEV_SUSPEND, io)) { - ERROR("Error activating verity device (%s)", strerror(errno)); - return -1; - } - return 0; -} - -static int test_access(char *device) { - int tries = 25; - while (tries--) { - if (!access(device, F_OK) || errno != ENOENT) { - return 0; - } - usleep(40 * 1000); - } - return -1; -} - -int fs_mgr_setup_verity(struct fstab_rec *fstab) { - - int retval = -1; - - char *verity_blk_name; - char *verity_table; - char *verity_table_signature; - - char buffer[DM_BUF_SIZE]; - struct dm_ioctl *io = (struct dm_ioctl *) buffer; - char *mount_point = basename(fstab->mount_point); - - // set the dm_ioctl flags - io->flags |= 1; - io->target_count = 1; - - // get the device mapper fd - int fd; - if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) { - ERROR("Error opening device mapper (%s)", strerror(errno)); - return retval; - } - - // create the device - if (create_verity_device(io, mount_point, fd) < 0) { - ERROR("Couldn't create verity device!"); - goto out; - } - - // get the name of the device file - if (get_verity_device_name(io, mount_point, fd, &verity_blk_name) < 0) { - ERROR("Couldn't get verity device number!"); - goto out; - } - - // read the verity block at the end of the block device - if (read_verity_metadata(fstab->blk_device, - &verity_table_signature, - &verity_table) < 0) { - goto out; - } - - // verify the signature on the table - if (verify_table(verity_table_signature, - verity_table, - strlen(verity_table)) < 0) { - goto out; - } - - // load the verity mapping table - if (load_verity_table(io, mount_point, fstab->blk_device, fd, verity_table) < 0) { - goto out; - } - - // activate the device - if (resume_verity_table(io, mount_point, fd) < 0) { - goto out; - } - - // assign the new verity block device as the block device - free(fstab->blk_device); - fstab->blk_device = verity_blk_name; - - // make sure we've set everything up properly - if (test_access(fstab->blk_device) < 0) { - goto out; - } - - retval = 0; - -out: - close(fd); - return retval; -} diff --git a/crypto/fs_mgr/include/fs_mgr.h b/crypto/fs_mgr/include/fs_mgr.h deleted file mode 100644 index 0f90c32f1..000000000 --- a/crypto/fs_mgr/include/fs_mgr.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source 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. - */ - -#ifndef __CORE_FS_MGR_H -#define __CORE_FS_MGR_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct fstab { - int num_entries; - struct fstab_rec *recs; - char *fstab_filename; -}; - -struct fstab_rec { - char *blk_device; - char *mount_point; - char *fs_type; - unsigned long flags; - char *fs_options; - int fs_mgr_flags; - char *key_loc; - char *verity_loc; - long long length; - char *label; - int partnum; - int swap_prio; - unsigned int zram_size; -}; - -struct fstab *fs_mgr_read_fstab(const char *fstab_path); -void fs_mgr_free_fstab(struct fstab *fstab); -int fs_mgr_mount_all(struct fstab *fstab); -int fs_mgr_do_mount(struct fstab *fstab, char *n_name, char *n_blk_device, - char *tmp_mount_point); -int fs_mgr_do_tmpfs_mount(char *n_name); -int fs_mgr_unmount_all(struct fstab *fstab); -int fs_mgr_get_crypt_info(struct fstab *fstab, char *key_loc, - char *real_blk_device, int size); -int fs_mgr_add_entry(struct fstab *fstab, - const char *mount_point, const char *fs_type, - const char *blk_device, long long length); -struct fstab_rec *fs_mgr_get_entry_for_mount_point(struct fstab *fstab, const char *path); -int fs_mgr_is_voldmanaged(struct fstab_rec *fstab); -int fs_mgr_is_nonremovable(struct fstab_rec *fstab); -int fs_mgr_is_encryptable(struct fstab_rec *fstab); -int fs_mgr_is_noemulatedsd(struct fstab_rec *fstab); -int fs_mgr_swapon_all(struct fstab *fstab); -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_FS_MGR_H */ - diff --git a/crypto/ics/Android.mk b/crypto/ics/Android.mk deleted file mode 100644 index 5616c195a..000000000 --- a/crypto/ics/Android.mk +++ /dev/null @@ -1,25 +0,0 @@ -LOCAL_PATH := $(call my-dir) -ifeq ($(TW_INCLUDE_CRYPTO), true) -include $(CLEAR_VARS) - -LOCAL_MODULE := libcryptfsics -LOCAL_MODULE_TAGS := eng optional -LOCAL_CFLAGS := -LOCAL_CFLAGS += -DCRYPTO_FS_TYPE=\"$(TW_CRYPTO_FS_TYPE)\" -ifeq ($(TW_INCLUDE_CRYPTO_SAMSUNG), true) - LOCAL_CFLAGS += -DTW_INCLUDE_CRYPTO_SAMSUNG=\"$(TW_INCLUDE_CRYPTO_SAMSUNG)\" - LOCAL_LDFLAGS += -ldl - LOCAL_STATIC_LIBRARIES += libcrypt_samsung -endif -ifneq ($(TW_INTERNAL_STORAGE_PATH),) - LOCAL_CFLAGS += -DTW_INTERNAL_STORAGE_PATH=$(TW_INTERNAL_STORAGE_PATH) -endif -ifneq ($(TW_EXTERNAL_STORAGE_PATH),) - LOCAL_CFLAGS += -DTW_EXTERNAL_STORAGE_PATH=$(TW_EXTERNAL_STORAGE_PATH) -endif -LOCAL_SRC_FILES = cryptfs.c -LOCAL_C_INCLUDES += system/extras/ext4_utils external/openssl/include -LOCAL_SHARED_LIBRARIES += libc liblog libcutils libcrypto - -include $(BUILD_SHARED_LIBRARY) -endif diff --git a/crypto/ics/cryptfs.c b/crypto/ics/cryptfs.c deleted file mode 100644 index 4f3d5d01a..000000000 --- a/crypto/ics/cryptfs.c +++ /dev/null @@ -1,729 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source 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. - */ - -/* TO DO: - * 1. Perhaps keep several copies of the encrypted key, in case something - * goes horribly wrong? - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "cryptfs.h" -#define LOG_TAG "Cryptfs" -#include "cutils/log.h" -#include "cutils/properties.h" -#include "hardware_legacy/power.h" -//#include "VolumeManager.h" - -#define DM_CRYPT_BUF_SIZE 4096 -#define DATA_MNT_POINT "/data" - -#define HASH_COUNT 2000 -#ifdef TW_INCLUDE_CRYPTO_SAMSUNG -#define KEY_LEN_BYTES_SAMSUNG (sizeof(edk_t)) -#endif -#define KEY_LEN_BYTES 16 -#define IV_LEN_BYTES 16 - -#define KEY_LOC_PROP "ro.crypto.keyfile.userdata" -#define KEY_IN_FOOTER "footer" - -#define EXT4_FS 1 -#define FAT_FS 2 - -#ifndef EXPAND -#define STRINGIFY(x) #x -#define EXPAND(x) STRINGIFY(x) -#endif - -char *me = "cryptfs"; - -static char *saved_data_blkdev; -static char *saved_mount_point; -static int master_key_saved = 0; -#ifdef TW_INCLUDE_CRYPTO_SAMSUNG -static int using_samsung_encryption = 0; -//static edk_t saved_master_key; -static unsigned char saved_master_key[KEY_LEN_BYTES_SAMSUNG]; -edk_payload_t edk_payload; -#else -static unsigned char saved_master_key[KEY_LEN_BYTES]; -#endif - -int cryptfs_setup_volume(const char *label, const char *real_blkdev, char *crypto_blkdev); - - -static void ioctl_init(struct dm_ioctl *io, size_t dataSize, const char *name, unsigned flags) -{ - memset(io, 0, dataSize); - io->data_size = dataSize; - io->data_start = sizeof(struct dm_ioctl); - io->version[0] = 4; - io->version[1] = 0; - io->version[2] = 0; - io->flags = flags; - if (name) { - strncpy(io->name, name, sizeof(io->name)); - } -} - -static unsigned int get_blkdev_size(int fd) -{ - unsigned int nr_sec; - - if ( (ioctl(fd, BLKGETSIZE, &nr_sec)) == -1) { - nr_sec = 0; - } - - return nr_sec; -} - -/* key or salt can be NULL, in which case just skip writing that value. Useful to - * update the failed mount count but not change the key. - */ -static int put_crypt_ftr_and_key(char *real_blk_name, struct crypt_mnt_ftr *crypt_ftr, - unsigned char *key, unsigned char *salt) -{ - // we don't need to update it... - return 0; -} - -static int get_crypt_ftr_and_key(char *real_blk_name, struct crypt_mnt_ftr *crypt_ftr, - unsigned char *key, unsigned char *salt) -{ - int fd; - unsigned int nr_sec, cnt; - off64_t off; - int rc = -1; - char key_loc[PROPERTY_VALUE_MAX]; - char *fname; - struct stat statbuf; - - property_get(KEY_LOC_PROP, key_loc, KEY_IN_FOOTER); - - if (!strcmp(key_loc, KEY_IN_FOOTER)) { - fname = real_blk_name; - if ( (fd = open(fname, O_RDONLY)) < 0) { - printf("Cannot open real block device %s\n", fname); - return -1; - } - - if ( (nr_sec = get_blkdev_size(fd)) == 0) { - SLOGE("Cannot get size of block device %s\n", fname); - goto errout; - } - - /* If it's an encrypted Android partition, the last 16 Kbytes contain the - * encryption info footer and key, and plenty of bytes to spare for future - * growth. - */ - off = ((off64_t)nr_sec * 512) - CRYPT_FOOTER_OFFSET; - - if (lseek64(fd, off, SEEK_SET) == -1) { - printf("Cannot seek to real block device footer\n"); - goto errout; - } - } else if (key_loc[0] == '/') { - fname = key_loc; - if ( (fd = open(fname, O_RDONLY)) < 0) { - printf("Cannot open footer file %s\n", fname); - return -1; - } - - /* Make sure it's 16 Kbytes in length */ - fstat(fd, &statbuf); - if (S_ISREG(statbuf.st_mode) && (statbuf.st_size != 0x4000 -#ifdef TW_INCLUDE_CRYPTO_SAMSUNG - && statbuf.st_size != 0x8000 -#endif - )) { - printf("footer file %s is not the expected size!\n", fname); - goto errout; - } - } else { - printf("Unexpected value for" KEY_LOC_PROP "\n"); - return -1;; - } - - if ( (cnt = read(fd, crypt_ftr, sizeof(struct crypt_mnt_ftr))) != sizeof(struct crypt_mnt_ftr)) { - printf("Cannot read real block device footer\n"); - goto errout; - } - - if (crypt_ftr->magic != CRYPT_MNT_MAGIC) { -#ifdef TW_INCLUDE_CRYPTO_SAMSUNG - if (crypt_ftr->magic != CRYPT_MNT_MAGIC_SAMSUNG) { - printf("Bad magic for real block device %s\n", fname); - goto errout; - } else { - printf("Using Samsung encryption.\n"); - using_samsung_encryption = 1; - if ( (cnt = read(fd, &edk_payload, sizeof(edk_payload_t))) != sizeof(edk_payload_t)) { - printf("Cannot read EDK payload from real block device footer\n"); - goto errout; - } - if (lseek64(fd, sizeof(__le32), SEEK_CUR) == -1) { - printf("Cannot seek past unknown data from real block device footer\n"); - goto errout; - } - memcpy(key, &edk_payload, sizeof(edk_payload_t)); - } -#else - printf("Bad magic for real block device %s\n", fname); - goto errout; -#endif - } - - if (crypt_ftr->major_version != 1) { - printf("Cannot understand major version %d real block device footer\n", - crypt_ftr->major_version); - goto errout; - } - - if (crypt_ftr->minor_version != 0) { - printf("Warning: crypto footer minor version %d, expected 0, continuing...\n", - crypt_ftr->minor_version); - } - - if (crypt_ftr->ftr_size > sizeof(struct crypt_mnt_ftr)) { - /* the footer size is bigger than we expected. - * Skip to it's stated end so we can read the key. - */ - if (lseek64(fd, crypt_ftr->ftr_size - sizeof(struct crypt_mnt_ftr), SEEK_CUR) == -1) { - printf("Cannot seek to start of key\n"); - goto errout; - } - } - - if (crypt_ftr->keysize > sizeof(saved_master_key)) { - printf("Keysize of %d bits not supported for real block device %s\n", - crypt_ftr->keysize * 8, fname); - goto errout; - } - - if ( (cnt = read(fd, key, crypt_ftr->keysize)) != crypt_ftr->keysize) { - printf("Cannot read key for real block device %s\n", fname); - goto errout; - } - - if (lseek64(fd, KEY_TO_SALT_PADDING, SEEK_CUR) == -1) { - printf("Cannot seek to real block device salt\n"); - goto errout; - } - - if ( (cnt = read(fd, salt, SALT_LEN)) != SALT_LEN) { - printf("Cannot read salt for real block device %s\n", fname); - goto errout; - } - - /* Success! */ - rc = 0; - -errout: - close(fd); - return rc; -} - -/* Convert a binary key of specified length into an ascii hex string equivalent, - * without the leading 0x and with null termination - */ -void convert_key_to_hex_ascii(unsigned char *master_key, unsigned int keysize, - char *master_key_ascii) -{ - unsigned int i, a; - unsigned char nibble; - - for (i=0, a=0; i> 4) & 0xf; - master_key_ascii[a] = nibble + (nibble > 9 ? 0x37 : 0x30); - - nibble = master_key[i] & 0xf; - master_key_ascii[a+1] = nibble + (nibble > 9 ? 0x37 : 0x30); - } - - /* Add the null termination */ - master_key_ascii[a] = '\0'; - -} - -static int create_crypto_blk_dev(struct crypt_mnt_ftr *crypt_ftr, unsigned char *master_key, - const char *real_blk_name, char *crypto_blk_name, const char *name) -{ - char buffer[DM_CRYPT_BUF_SIZE]; - char master_key_ascii[129]; /* Large enough to hold 512 bit key and null */ - char *crypt_params; - struct dm_ioctl *io; - struct dm_target_spec *tgt; - unsigned int minor; - int fd; - int retval = -1; - - if ((fd = open("/dev/device-mapper", O_RDWR)) < 0 ) { - printf("Cannot open device-mapper\n"); - goto errout; - } - - io = (struct dm_ioctl *) buffer; - - ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0); - if (ioctl(fd, DM_DEV_CREATE, io)) { - printf("Cannot create dm-crypt device\n"); - goto errout; - } - - /* Get the device status, in particular, the name of it's device file */ - ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0); - if (ioctl(fd, DM_DEV_STATUS, io)) { - printf("Cannot retrieve dm-crypt device status\n"); - goto errout; - } - minor = (io->dev & 0xff) | ((io->dev >> 12) & 0xfff00); - snprintf(crypto_blk_name, MAXPATHLEN, "/dev/block/dm-%u", minor); - - /* Load the mapping table for this device */ - tgt = (struct dm_target_spec *) &buffer[sizeof(struct dm_ioctl)]; - - ioctl_init(io, 4096, name, 0); - io->target_count = 1; - tgt->status = 0; - tgt->sector_start = 0; - tgt->length = crypt_ftr->fs_size; - strcpy(tgt->target_type, "crypt"); - - crypt_params = buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec); - convert_key_to_hex_ascii(master_key, crypt_ftr->keysize, master_key_ascii); - sprintf(crypt_params, "%s %s 0 %s 0", crypt_ftr->crypto_type_name, - master_key_ascii, real_blk_name); - //printf("cryptsetup params: '%s'\n", crypt_params); - crypt_params += strlen(crypt_params) + 1; - crypt_params = (char *) (((unsigned long)crypt_params + 7) & ~8); /* Align to an 8 byte boundary */ - tgt->next = crypt_params - buffer; - - if (ioctl(fd, DM_TABLE_LOAD, io)) { - printf("Cannot load dm-crypt mapping table.\n"); - goto errout; - } - - /* Resume this device to activate it */ - ioctl_init(io, 4096, name, 0); - - if (ioctl(fd, DM_DEV_SUSPEND, io)) { - printf("Cannot resume the dm-crypt device\n"); - goto errout; - } - - /* We made it here with no errors. Woot! */ - retval = 0; - -errout: - close(fd); /* If fd is <0 from a failed open call, it's safe to just ignore the close error */ - - return retval; -} - -static int delete_crypto_blk_dev(const char *name) -{ - int fd; - char buffer[DM_CRYPT_BUF_SIZE]; - struct dm_ioctl *io; - int retval = -1; - - if ((fd = open("/dev/device-mapper", O_RDWR)) < 0 ) { - printf("Cannot open device-mapper\n"); - goto errout; - } - - io = (struct dm_ioctl *) buffer; - - ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0); - if (ioctl(fd, DM_DEV_REMOVE, io)) { - printf("Cannot remove dm-crypt device\n"); - goto errout; - } - - /* We made it here with no errors. Woot! */ - retval = 0; - -errout: - close(fd); /* If fd is <0 from a failed open call, it's safe to just ignore the close error */ - - return retval; - -} - -static void pbkdf2(char *passwd, unsigned char *salt, unsigned char *ikey) -{ - /* Turn the password into a key and IV that can decrypt the master key */ - PKCS5_PBKDF2_HMAC_SHA1(passwd, strlen(passwd), salt, SALT_LEN, - HASH_COUNT, KEY_LEN_BYTES+IV_LEN_BYTES, ikey); -} - -static int decrypt_master_key(char *passwd, unsigned char *salt, - unsigned char *encrypted_master_key, - unsigned char *decrypted_master_key) -{ -#ifdef TW_INCLUDE_CRYPTO_SAMSUNG - if (using_samsung_encryption) { - property_set("rw.km_fips_status", "ready"); - return decrypt_EDK((dek_t*)decrypted_master_key, (edk_payload_t*)encrypted_master_key, passwd); - } -#endif - - unsigned char ikey[32+32] = { 0 }; /* Big enough to hold a 256 bit key and 256 bit IV */ - EVP_CIPHER_CTX d_ctx; - int decrypted_len, final_len; - - /* Turn the password into a key and IV that can decrypt the master key */ - pbkdf2(passwd, salt, ikey); - - /* Initialize the decryption engine */ - if (! EVP_DecryptInit(&d_ctx, EVP_aes_128_cbc(), ikey, ikey+KEY_LEN_BYTES)) { - return -1; - } - EVP_CIPHER_CTX_set_padding(&d_ctx, 0); /* Turn off padding as our data is block aligned */ - /* Decrypt the master key */ - if (! EVP_DecryptUpdate(&d_ctx, decrypted_master_key, &decrypted_len, - encrypted_master_key, KEY_LEN_BYTES)) { - return -1; - } - if (! EVP_DecryptFinal(&d_ctx, decrypted_master_key + decrypted_len, &final_len)) { - return -1; - } - - if (decrypted_len + final_len != KEY_LEN_BYTES) { - return -1; - } else { - return 0; - } -} - -static int get_orig_mount_parms( - const char *mount_point, char *fs_type, char *real_blkdev, - unsigned long *mnt_flags, char *fs_options) -{ - char mount_point2[PROPERTY_VALUE_MAX]; - char fs_flags[PROPERTY_VALUE_MAX]; - - property_get("ro.crypto.fs_type", fs_type, ""); - property_get("ro.crypto.fs_real_blkdev", real_blkdev, ""); - property_get("ro.crypto.fs_mnt_point", mount_point2, ""); - property_get("ro.crypto.fs_options", fs_options, ""); - property_get("ro.crypto.fs_flags", fs_flags, ""); - *mnt_flags = strtol(fs_flags, 0, 0); - - if (strcmp(mount_point, mount_point2)) { - /* Consistency check. These should match. If not, something odd happened. */ - return -1; - } - - return 0; -} - -static int get_orig_mount_parms_sd( - const char *mount_point, char *fs_type, char *real_blkdev) -{ - char mount_point2[PROPERTY_VALUE_MAX]; - - property_get("ro.crypto.sd_fs_type", fs_type, ""); - property_get("ro.crypto.sd_fs_real_blkdev", real_blkdev, ""); - property_get("ro.crypto.sd_fs_mnt_point", mount_point2, ""); - - if (strcmp(mount_point, mount_point2)) { - /* Consistency check. These should match. If not, something odd happened. */ - return -1; - } - - return 0; -} - -static int test_mount_encrypted_fs( - char *passwd, char *mount_point, char *label, char *crypto_blkdev) -{ - struct crypt_mnt_ftr crypt_ftr; - /* Allocate enough space for a 256 bit key, but we may use less */ - unsigned char encrypted_master_key[256], decrypted_master_key[32]; - unsigned char salt[SALT_LEN]; - char real_blkdev[MAXPATHLEN]; - char fs_type[PROPERTY_VALUE_MAX]; - char fs_options[PROPERTY_VALUE_MAX]; - char tmp_mount_point[MAXPATHLEN]; - unsigned long mnt_flags; - unsigned int orig_failed_decrypt_count; - char encrypted_state[PROPERTY_VALUE_MAX]; - int rc; - - property_get("ro.crypto.state", encrypted_state, ""); - if ( master_key_saved || strcmp(encrypted_state, "encrypted") ) { - printf("encrypted fs already validated or not running with encryption, aborting %s\n", encrypted_state); - return -1; - } - - if (get_orig_mount_parms(mount_point, fs_type, real_blkdev, &mnt_flags, fs_options)) { - printf("Error reading original mount parms for mount point %s\n", mount_point); - return -1; - } - - if (get_crypt_ftr_and_key(real_blkdev, &crypt_ftr, encrypted_master_key, salt)) { - printf("Error getting crypt footer and key\n"); - return -1; - } - - //printf("crypt_ftr->fs_size = %lld\n", crypt_ftr.fs_size); - orig_failed_decrypt_count = crypt_ftr.failed_decrypt_count; - - if (! (crypt_ftr.flags & CRYPT_MNT_KEY_UNENCRYPTED) ) { - decrypt_master_key(passwd, salt, encrypted_master_key, decrypted_master_key); - } - - if (create_crypto_blk_dev(&crypt_ftr, decrypted_master_key, real_blkdev, - crypto_blkdev, label)) { - printf("Error creating decrypted block device\n"); - return -1; - } - - /* If init detects an encrypted filesystme, it writes a file for each such - * encrypted fs into the tmpfs /data filesystem, and then the framework finds those - * files and passes that data to me */ - /* Create a tmp mount point to try mounting the decryptd fs - * Since we're here, the mount_point should be a tmpfs filesystem, so make - * a directory in it to test mount the decrypted filesystem. - */ - sprintf(tmp_mount_point, "%s/tmp_mnt", mount_point); - mkdir(tmp_mount_point, 0755); - if ( mount(crypto_blkdev, tmp_mount_point, fs_type, MS_RDONLY, "") ) { - printf("Error temp mounting decrypted block device\n"); - delete_crypto_blk_dev(label); - crypt_ftr.failed_decrypt_count++; - } else { - /* Success, so just umount and we'll mount it properly when we restart - * the framework. - */ - umount(tmp_mount_point); - crypt_ftr.failed_decrypt_count = 0; - } - - rmdir(tmp_mount_point); - - if (crypt_ftr.failed_decrypt_count) { - /* We failed to mount the device, so return an error */ - rc = crypt_ftr.failed_decrypt_count; - - } else { - /* Woot! Success! Save the name of the crypto block device - * so we can mount it when restarting the framework. - */ - property_set("ro.crypto.fs_crypto_blkdev", crypto_blkdev); - - /* Also save a the master key so we can reencrypted the key - * the key when we want to change the password on it. - */ - memcpy(saved_master_key, decrypted_master_key, sizeof(saved_master_key)); - saved_data_blkdev = strdup(real_blkdev); - saved_mount_point = strdup(mount_point); - master_key_saved = 1; - rc = 0; - } - - return rc; -} - -static int test_mount_encrypted_fs_sd( - const char *passwd, const char *mount_point, const char *label) -{ - char real_blkdev[MAXPATHLEN]; - char crypto_blkdev[MAXPATHLEN]; - char tmp_mount_point[MAXPATHLEN]; - char encrypted_state[PROPERTY_VALUE_MAX]; - char fs_type[PROPERTY_VALUE_MAX]; - int rc; - - property_get("ro.crypto.state", encrypted_state, ""); - if ( !master_key_saved || strcmp(encrypted_state, "encrypted") ) { - printf("encrypted fs not yet validated or not running with encryption, aborting\n"); - return -1; - } - - if (get_orig_mount_parms_sd(mount_point, fs_type, real_blkdev)) { - printf("Error reading original mount parms for mount point %s\n", mount_point); - return -1; - } - - rc = cryptfs_setup_volume(label, real_blkdev, crypto_blkdev); - if(rc){ - printf("Error setting up cryptfs volume %s\n", real_blkdev); - return -1; - } - - sprintf(tmp_mount_point, "%s/tmp_mnt", mount_point); - mkdir(tmp_mount_point, 0755); - if ( mount(crypto_blkdev, tmp_mount_point, fs_type, MS_RDONLY, "") ) { - printf("Error temp mounting decrypted block device\n"); - delete_crypto_blk_dev(label); - } else { - /* Success, so just umount and we'll mount it properly when we restart - * the framework. - */ - umount(tmp_mount_point); - - property_set("ro.crypto.sd_fs_crypto_blkdev", crypto_blkdev); - } - - rmdir(tmp_mount_point); - - return rc; -} - -/* - * Called by vold when it's asked to mount an encrypted, nonremovable volume. - * Setup a dm-crypt mapping, use the saved master key from - * setting up the /data mapping, and return the new device path. - */ -int cryptfs_setup_volume(const char *label, const char *real_blkdev, char *crypto_blkdev) -{ - struct crypt_mnt_ftr sd_crypt_ftr; - unsigned char key[256], salt[32]; - struct stat statbuf; - int nr_sec, fd, rc; - - /* Just want the footer, but gotta get it all */ - get_crypt_ftr_and_key(saved_data_blkdev, &sd_crypt_ftr, key, salt); - - /* Update the fs_size field to be the size of the volume */ - fd = open(real_blkdev, O_RDONLY); - nr_sec = get_blkdev_size(fd); - close(fd); - if (nr_sec == 0) { - SLOGE("Cannot get size of volume %s\n", real_blkdev); - return -1; - } - -#ifdef TW_INCLUDE_CRYPTO_SAMSUNG - if(using_samsung_encryption) { - if(!access("/efs/essiv", R_OK)){ - strcpy(sd_crypt_ftr.crypto_type_name, "aes-cbc-plain:sha1"); - } - else if(!access("/efs/cryptprop_essiv", R_OK)){ - strcpy(sd_crypt_ftr.crypto_type_name, "aes-cbc-essiv:sha256"); - } - } -#endif - - sd_crypt_ftr.fs_size = nr_sec; - rc = create_crypto_blk_dev( - &sd_crypt_ftr, saved_master_key, real_blkdev, crypto_blkdev, label); - - stat(crypto_blkdev, &statbuf); - - return rc; -} - -int cryptfs_crypto_complete(void) -{ - return -1; -} - -int cryptfs_check_footer(void) -{ - int rc = -1; - char fs_type[PROPERTY_VALUE_MAX]; - char real_blkdev[MAXPATHLEN]; - char fs_options[PROPERTY_VALUE_MAX]; - unsigned long mnt_flags; - struct crypt_mnt_ftr crypt_ftr; - /* Allocate enough space for a 256 bit key, but we may use less */ - unsigned char encrypted_master_key[256]; - unsigned char salt[SALT_LEN]; - - if (get_orig_mount_parms(DATA_MNT_POINT, fs_type, real_blkdev, &mnt_flags, fs_options)) { - printf("Error reading original mount parms for mount point %s\n", DATA_MNT_POINT); - return rc; - } - - rc = get_crypt_ftr_and_key(real_blkdev, &crypt_ftr, encrypted_master_key, salt); - - return rc; -} - -int cryptfs_check_passwd(const char *passwd) -{ - char pwbuf[256]; - char crypto_blkdev_data[MAXPATHLEN]; - int rc = -1; - - strcpy(pwbuf, passwd); - rc = test_mount_encrypted_fs(pwbuf, DATA_MNT_POINT, "userdata", crypto_blkdev_data); - -#ifdef TW_INCLUDE_CRYPTO_SAMSUNG - if(using_samsung_encryption) { - - int rc2 = 1; -#ifndef RECOVERY_SDCARD_ON_DATA -#ifdef TW_INTERNAL_STORAGE_PATH - // internal storage for non data/media devices - if(!rc) { - strcpy(pwbuf, passwd); - rc2 = test_mount_encrypted_fs_sd( - pwbuf, EXPAND(TW_INTERNAL_STORAGE_PATH), - EXPAND(TW_INTERNAL_STORAGE_MOUNT_POINT)); - } -#endif -#endif -#ifdef TW_EXTERNAL_STORAGE_PATH - printf("Temp mounting /data\n"); - // mount data so mount_ecryptfs_drive can access edk in /data/system/ - rc2 = mount(crypto_blkdev_data, DATA_MNT_POINT, CRYPTO_FS_TYPE, MS_RDONLY, ""); - // external sd - char decrypt_external[256], external_blkdev[256]; - property_get("ro.crypto.external_encrypted", decrypt_external, "0"); - // Mount the external storage as ecryptfs so that ecryptfs can act as a pass-through - if (!rc2 && strcmp(decrypt_external, "1") == 0) { - printf("Mounting external with ecryptfs...\n"); - strcpy(pwbuf, passwd); - rc2 = mount_ecryptfs_drive( - pwbuf, EXPAND(TW_EXTERNAL_STORAGE_PATH), - EXPAND(TW_EXTERNAL_STORAGE_PATH), 0); - if (rc2 == 0) - property_set("ro.crypto.external_use_ecryptfs", "1"); - else - property_set("ro.crypto.external_use_ecryptfs", "0"); - } else { - printf("Unable to mount external storage with ecryptfs.\n"); - umount(EXPAND(TW_EXTERNAL_STORAGE_PATH)); - } - umount(DATA_MNT_POINT); - } -#endif // #ifdef TW_EXTERNAL_STORAGE_PATH -#endif // #ifdef TW_INCLUDE_CRYPTO_SAMSUNG - return rc; -} diff --git a/crypto/ics/cryptfs.h b/crypto/ics/cryptfs.h deleted file mode 100644 index 8c8037659..000000000 --- a/crypto/ics/cryptfs.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source 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. - */ - -/* This structure starts 16,384 bytes before the end of a hardware - * partition that is encrypted. - * Immediately following this structure is the encrypted key. - * The keysize field tells how long the key is, in bytes. - * Then there is 32 bytes of padding, - * Finally there is the salt used with the user password. - * The salt is fixed at 16 bytes long. - * Obviously, the filesystem does not include the last 16 kbytes - * of the partition. - */ - -#ifndef __CRYPTFS_H__ -#define __CRYPTFS_H__ - -#ifdef TW_INCLUDE_CRYPTO_SAMSUNG -#include "../libcrypt_samsung/include/libcrypt_samsung.h" -#endif - -#define CRYPT_FOOTER_OFFSET 0x4000 - -#define MAX_CRYPTO_TYPE_NAME_LEN 64 - -#define SALT_LEN 16 -#define KEY_TO_SALT_PADDING 32 - -/* definitions of flags in the structure below */ -#define CRYPT_MNT_KEY_UNENCRYPTED 0x1 /* The key for the partition is not encrypted. */ -#define CRYPT_ENCRYPTION_IN_PROGRESS 0x2 /* Set when starting encryption, - * clear when done before rebooting */ - -#ifdef TW_INCLUDE_CRYPTO_SAMSUNG -#define CRYPT_MNT_MAGIC_SAMSUNG 0xD0B5B1C5 -#endif -#define CRYPT_MNT_MAGIC 0xD0B5B1C4 - -#define __le32 unsigned int -#define __le16 unsigned short int - -#pragma pack(1) - -struct crypt_mnt_ftr { - __le32 magic; /* See above */ - __le16 major_version; - __le16 minor_version; - __le32 ftr_size; /* in bytes, not including key following */ - __le32 flags; /* See above */ - __le32 keysize; /* in bytes */ - __le32 spare1; /* ignored */ - __le64 fs_size; /* Size of the encrypted fs, in 512 byte sectors */ - __le32 failed_decrypt_count; /* count of # of failed attempts to decrypt and - mount, set to 0 on successful mount */ - char crypto_type_name[MAX_CRYPTO_TYPE_NAME_LEN]; /* The type of encryption - needed to decrypt this - partition, null terminated */ -}; - -#pragma pack() - - -#ifdef __cplusplus -extern "C" { -#endif - int cryptfs_check_footer(void); - int cryptfs_check_passwd(const char *pw); -#ifdef __cplusplus -} -#endif - -#endif // __CRYPTFS_H__ - diff --git a/crypto/jb/Android.mk b/crypto/jb/Android.mk deleted file mode 100644 index 90321d67e..000000000 --- a/crypto/jb/Android.mk +++ /dev/null @@ -1,17 +0,0 @@ -LOCAL_PATH := $(call my-dir) -ifeq ($(TW_INCLUDE_JB_CRYPTO), true) -include $(CLEAR_VARS) - -LOCAL_MODULE := libcryptfsjb -LOCAL_MODULE_TAGS := eng optional -LOCAL_CFLAGS := -LOCAL_SRC_FILES = cryptfs.c -LOCAL_C_INCLUDES += \ - system/extras/ext4_utils \ - external/openssl/include \ - $(commands_recovery_local_path)/crypto/scrypt/lib/crypto -LOCAL_SHARED_LIBRARIES += libc liblog libcutils libcrypto libext4_utils -LOCAL_STATIC_LIBRARIES += libfs_mgrtwrp libscrypttwrp_static liblogwraptwrp libmincrypttwrp - -include $(BUILD_SHARED_LIBRARY) -endif diff --git a/crypto/jb/cryptfs.c b/crypto/jb/cryptfs.c deleted file mode 100644 index f9c0d7489..000000000 --- a/crypto/jb/cryptfs.c +++ /dev/null @@ -1,1735 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source 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. - */ - -/* TO DO: - * 1. Perhaps keep several copies of the encrypted key, in case something - * goes horribly wrong? - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "cryptfs.h" -#define LOG_TAG "Cryptfs" -#include "cutils/log.h" -#include "cutils/properties.h" -#include "cutils/android_reboot.h" -#include "hardware_legacy/power.h" -/*#include -#include "VolumeManager.h" -#include "VoldUtil.h"*/ -#include "crypto_scrypt.h" - -#define DM_CRYPT_BUF_SIZE 4096 -#define DATA_MNT_POINT "/data" - -#define HASH_COUNT 2000 -#define KEY_LEN_BYTES 16 -#define IV_LEN_BYTES 16 - -#define KEY_IN_FOOTER "footer" - -#define EXT4_FS 1 -#define FAT_FS 2 - -#define TABLE_LOAD_RETRIES 10 - -char *me = "cryptfs"; - -static unsigned char saved_master_key[KEY_LEN_BYTES]; -static char *saved_mount_point; -static int master_key_saved = 0; -static struct crypt_persist_data *persist_data = NULL; - -struct fstab *fstab; - -static void cryptfs_reboot(int recovery) -{ - /*if (recovery) { - property_set(ANDROID_RB_PROPERTY, "reboot,recovery"); - } else { - property_set(ANDROID_RB_PROPERTY, "reboot"); - } - sleep(20);*/ - - /* Shouldn't get here, reboot should happen before sleep times out */ - return; -} - -static void ioctl_init(struct dm_ioctl *io, size_t dataSize, const char *name, unsigned flags) -{ - memset(io, 0, dataSize); - io->data_size = dataSize; - io->data_start = sizeof(struct dm_ioctl); - io->version[0] = 4; - io->version[1] = 0; - io->version[2] = 0; - io->flags = flags; - if (name) { - strncpy(io->name, name, sizeof(io->name)); - } -} - -/** - * Gets the default device scrypt parameters for key derivation time tuning. - * The parameters should lead to about one second derivation time for the - * given device. - */ -static void get_device_scrypt_params(struct crypt_mnt_ftr *ftr) { - const int default_params[] = SCRYPT_DEFAULTS; - int params[] = SCRYPT_DEFAULTS; - char paramstr[PROPERTY_VALUE_MAX]; - char *token; - char *saveptr; - int i; - - property_get(SCRYPT_PROP, paramstr, ""); - if (paramstr[0] != '\0') { - /* - * The token we're looking for should be three integers separated by - * colons (e.g., "12:8:1"). Scan the property to make sure it matches. - */ - for (i = 0, token = strtok_r(paramstr, ":", &saveptr); - token != NULL && i < 3; - i++, token = strtok_r(NULL, ":", &saveptr)) { - char *endptr; - params[i] = strtol(token, &endptr, 10); - - /* - * Check that there was a valid number and it's 8-bit. If not, - * break out and the end check will take the default values. - */ - if ((*token == '\0') || (*endptr != '\0') || params[i] < 0 || params[i] > 255) { - break; - } - } - - /* - * If there were not enough tokens or a token was malformed (not an - * integer), it will end up here and the default parameters can be - * taken. - */ - if ((i != 3) || (token != NULL)) { - printf("bad scrypt parameters '%s' should be like '12:8:1'; using defaults", paramstr); - memcpy(params, default_params, sizeof(params)); - } - } - - ftr->N_factor = params[0]; - ftr->r_factor = params[1]; - ftr->p_factor = params[2]; -} - -static unsigned int get_fs_size(char *dev) -{ - int fd, block_size; - struct ext4_super_block sb; - off64_t len; - - if ((fd = open(dev, O_RDONLY)) < 0) { - printf("Cannot open device to get filesystem size "); - return 0; - } - - if (lseek64(fd, 1024, SEEK_SET) < 0) { - printf("Cannot seek to superblock"); - return 0; - } - - if (read(fd, &sb, sizeof(sb)) != sizeof(sb)) { - printf("Cannot read superblock"); - return 0; - } - - close(fd); - - block_size = 1024 << sb.s_log_block_size; - /* compute length in bytes */ - len = ( ((off64_t)sb.s_blocks_count_hi << 32) + sb.s_blocks_count_lo) * block_size; - - /* return length in sectors */ - return (unsigned int) (len / 512); -} - -static unsigned int get_blkdev_size(int fd) -{ - unsigned int nr_sec; - - if ( (ioctl(fd, BLKGETSIZE, &nr_sec)) == -1) { - nr_sec = 0; - } - - return nr_sec; -} - -static int get_crypt_ftr_info(char **metadata_fname, off64_t *off) -{ - static int cached_data = 0; - static off64_t cached_off = 0; - static char cached_metadata_fname[PROPERTY_VALUE_MAX] = ""; - int fd; - char key_loc[PROPERTY_VALUE_MAX]; - char real_blkdev[PROPERTY_VALUE_MAX]; - unsigned int nr_sec; - int rc = -1; - - if (!cached_data) { - fs_mgr_get_crypt_info(fstab, key_loc, real_blkdev, sizeof(key_loc)); - - if (!strcmp(key_loc, KEY_IN_FOOTER)) { - if ( (fd = open(real_blkdev, O_RDWR)) < 0) { - printf("Cannot open real block device %s\n", real_blkdev); - return -1; - } - - if ((nr_sec = get_blkdev_size(fd))) { - /* If it's an encrypted Android partition, the last 16 Kbytes contain the - * encryption info footer and key, and plenty of bytes to spare for future - * growth. - */ - strlcpy(cached_metadata_fname, real_blkdev, sizeof(cached_metadata_fname)); - cached_off = ((off64_t)nr_sec * 512) - CRYPT_FOOTER_OFFSET; - cached_data = 1; - } else { - printf("Cannot get size of block device %s\n", real_blkdev); - } - close(fd); - } else { - strlcpy(cached_metadata_fname, key_loc, sizeof(cached_metadata_fname)); - cached_off = 0; - cached_data = 1; - } - } - - if (cached_data) { - if (metadata_fname) { - *metadata_fname = cached_metadata_fname; - } - if (off) { - *off = cached_off; - } - rc = 0; - } - - return rc; -} - -/* key or salt can be NULL, in which case just skip writing that value. Useful to - * update the failed mount count but not change the key. - */ -static int put_crypt_ftr_and_key(struct crypt_mnt_ftr *crypt_ftr) -{ - int fd; - unsigned int nr_sec, cnt; - /* starting_off is set to the SEEK_SET offset - * where the crypto structure starts - */ - off64_t starting_off; - int rc = -1; - char *fname = NULL; - struct stat statbuf; - - if (get_crypt_ftr_info(&fname, &starting_off)) { - printf("Unable to get crypt_ftr_info\n"); - return -1; - } - if (fname[0] != '/') { - printf("Unexpected value for crypto key location\n"); - return -1; - } - if ( (fd = open(fname, O_RDWR | O_CREAT, 0600)) < 0) { - printf("Cannot open footer file %s for put\n", fname); - return -1; - } - - /* Seek to the start of the crypt footer */ - if (lseek64(fd, starting_off, SEEK_SET) == -1) { - printf("Cannot seek to real block device footer\n"); - goto errout; - } - - if ((cnt = write(fd, crypt_ftr, sizeof(struct crypt_mnt_ftr))) != sizeof(struct crypt_mnt_ftr)) { - printf("Cannot write real block device footer\n"); - goto errout; - } - - fstat(fd, &statbuf); - /* If the keys are kept on a raw block device, do not try to truncate it. */ - if (S_ISREG(statbuf.st_mode)) { - if (ftruncate(fd, 0x4000)) { - printf("Cannot set footer file size\n", fname); - goto errout; - } - } - - /* Success! */ - rc = 0; - -errout: - close(fd); - return rc; - -} - -static inline int unix_read(int fd, void* buff, int len) -{ - return TEMP_FAILURE_RETRY(read(fd, buff, len)); -} - -static inline int unix_write(int fd, const void* buff, int len) -{ - return TEMP_FAILURE_RETRY(write(fd, buff, len)); -} - -static void init_empty_persist_data(struct crypt_persist_data *pdata, int len) -{ - memset(pdata, 0, len); - pdata->persist_magic = PERSIST_DATA_MAGIC; - pdata->persist_valid_entries = 0; -} - -/* A routine to update the passed in crypt_ftr to the lastest version. - * fd is open read/write on the device that holds the crypto footer and persistent - * data, crypt_ftr is a pointer to the struct to be updated, and offset is the - * absolute offset to the start of the crypt_mnt_ftr on the passed in fd. - */ -static void upgrade_crypt_ftr(int fd, struct crypt_mnt_ftr *crypt_ftr, off64_t offset) -{ - int orig_major = crypt_ftr->major_version; - int orig_minor = crypt_ftr->minor_version; - return; // in recovery we don't want to upgrade - if ((crypt_ftr->major_version == 1) && (crypt_ftr->minor_version == 0)) { - struct crypt_persist_data *pdata; - off64_t pdata_offset = offset + CRYPT_FOOTER_TO_PERSIST_OFFSET; - - printf("upgrading crypto footer to 1.1"); - - pdata = malloc(CRYPT_PERSIST_DATA_SIZE); - if (pdata == NULL) { - printf("Cannot allocate persisent data\n"); - return; - } - memset(pdata, 0, CRYPT_PERSIST_DATA_SIZE); - - /* Need to initialize the persistent data area */ - if (lseek64(fd, pdata_offset, SEEK_SET) == -1) { - printf("Cannot seek to persisent data offset\n"); - return; - } - /* Write all zeros to the first copy, making it invalid */ - unix_write(fd, pdata, CRYPT_PERSIST_DATA_SIZE); - - /* Write a valid but empty structure to the second copy */ - init_empty_persist_data(pdata, CRYPT_PERSIST_DATA_SIZE); - unix_write(fd, pdata, CRYPT_PERSIST_DATA_SIZE); - - /* Update the footer */ - crypt_ftr->persist_data_size = CRYPT_PERSIST_DATA_SIZE; - crypt_ftr->persist_data_offset[0] = pdata_offset; - crypt_ftr->persist_data_offset[1] = pdata_offset + CRYPT_PERSIST_DATA_SIZE; - crypt_ftr->minor_version = 1; - } - - if ((crypt_ftr->major_version == 1) && (crypt_ftr->minor_version)) { - printf("upgrading crypto footer to 1.2"); - crypt_ftr->kdf_type = KDF_PBKDF2; - get_device_scrypt_params(crypt_ftr); - crypt_ftr->minor_version = 2; - } - - if ((orig_major != crypt_ftr->major_version) || (orig_minor != crypt_ftr->minor_version)) { - if (lseek64(fd, offset, SEEK_SET) == -1) { - printf("Cannot seek to crypt footer\n"); - return; - } - unix_write(fd, crypt_ftr, sizeof(struct crypt_mnt_ftr)); - } -} - - -static int get_crypt_ftr_and_key(struct crypt_mnt_ftr *crypt_ftr) -{ - int fd; - unsigned int nr_sec, cnt; - off64_t starting_off; - int rc = -1; - char *fname = NULL; - struct stat statbuf; - - if (get_crypt_ftr_info(&fname, &starting_off)) { - printf("Unable to get crypt_ftr_info\n"); - return -1; - } - if (fname[0] != '/') { - printf("Unexpected value for crypto key location\n"); - return -1; - } - if ( (fd = open(fname, O_RDWR)) < 0) { - printf("Cannot open footer file %s for get\n", fname); - return -1; - } - - /* Make sure it's 16 Kbytes in length */ - fstat(fd, &statbuf); - if (S_ISREG(statbuf.st_mode) && (statbuf.st_size != 0x4000)) { - printf("footer file %s is not the expected size!\n", fname); - goto errout; - } - - /* Seek to the start of the crypt footer */ - if (lseek64(fd, starting_off, SEEK_SET) == -1) { - printf("Cannot seek to real block device footer\n"); - goto errout; - } - - if ( (cnt = read(fd, crypt_ftr, sizeof(struct crypt_mnt_ftr))) != sizeof(struct crypt_mnt_ftr)) { - printf("Cannot read real block device footer\n"); - goto errout; - } - - if (crypt_ftr->magic != CRYPT_MNT_MAGIC) { - printf("Bad magic for real block device %s\n", fname); - goto errout; - } - - if (crypt_ftr->major_version != CURRENT_MAJOR_VERSION) { - printf("Cannot understand major version %d real block device footer; expected %d\n", - crypt_ftr->major_version, CURRENT_MAJOR_VERSION); - goto errout; - } - - if (crypt_ftr->minor_version > CURRENT_MINOR_VERSION) { - printf("Warning: crypto footer minor version %d, expected <= %d, continuing...\n", - crypt_ftr->minor_version, CURRENT_MINOR_VERSION); - } - - /* If this is a verion 1.0 crypt_ftr, make it a 1.1 crypt footer, and update the - * copy on disk before returning. - */ - /*if (crypt_ftr->minor_version < CURRENT_MINOR_VERSION) { - upgrade_crypt_ftr(fd, crypt_ftr, starting_off); - }*/ - - /* Success! */ - rc = 0; - -errout: - close(fd); - return rc; -} - -static int validate_persistent_data_storage(struct crypt_mnt_ftr *crypt_ftr) -{ - if (crypt_ftr->persist_data_offset[0] + crypt_ftr->persist_data_size > - crypt_ftr->persist_data_offset[1]) { - printf("Crypt_ftr persist data regions overlap"); - return -1; - } - - if (crypt_ftr->persist_data_offset[0] >= crypt_ftr->persist_data_offset[1]) { - printf("Crypt_ftr persist data region 0 starts after region 1"); - return -1; - } - - if (((crypt_ftr->persist_data_offset[1] + crypt_ftr->persist_data_size) - - (crypt_ftr->persist_data_offset[0] - CRYPT_FOOTER_TO_PERSIST_OFFSET)) > - CRYPT_FOOTER_OFFSET) { - printf("Persistent data extends past crypto footer"); - return -1; - } - - return 0; -} - -static int load_persistent_data(void) -{ - struct crypt_mnt_ftr crypt_ftr; - struct crypt_persist_data *pdata = NULL; - char encrypted_state[PROPERTY_VALUE_MAX]; - char *fname; - int found = 0; - int fd; - int ret; - int i; - - if (persist_data) { - /* Nothing to do, we've already loaded or initialized it */ - return 0; - } - - - /* If not encrypted, just allocate an empty table and initialize it */ - property_get("ro.crypto.state", encrypted_state, ""); - if (strcmp(encrypted_state, "encrypted") ) { - pdata = malloc(CRYPT_PERSIST_DATA_SIZE); - if (pdata) { - init_empty_persist_data(pdata, CRYPT_PERSIST_DATA_SIZE); - persist_data = pdata; - return 0; - } - return -1; - } - - if(get_crypt_ftr_and_key(&crypt_ftr)) { - return -1; - } - - if ((crypt_ftr.major_version != 1) || (crypt_ftr.minor_version != 1)) { - printf("Crypt_ftr version doesn't support persistent data"); - return -1; - } - - if (get_crypt_ftr_info(&fname, NULL)) { - return -1; - } - - ret = validate_persistent_data_storage(&crypt_ftr); - if (ret) { - return -1; - } - - fd = open(fname, O_RDONLY); - if (fd < 0) { - printf("Cannot open %s metadata file", fname); - return -1; - } - - if (persist_data == NULL) { - pdata = malloc(crypt_ftr.persist_data_size); - if (pdata == NULL) { - printf("Cannot allocate memory for persistent data"); - goto err; - } - } - - for (i = 0; i < 2; i++) { - if (lseek64(fd, crypt_ftr.persist_data_offset[i], SEEK_SET) < 0) { - printf("Cannot seek to read persistent data on %s", fname); - goto err2; - } - if (unix_read(fd, pdata, crypt_ftr.persist_data_size) < 0){ - printf("Error reading persistent data on iteration %d", i); - goto err2; - } - if (pdata->persist_magic == PERSIST_DATA_MAGIC) { - found = 1; - break; - } - } - - if (!found) { - printf("Could not find valid persistent data, creating"); - init_empty_persist_data(pdata, crypt_ftr.persist_data_size); - } - - /* Success */ - persist_data = pdata; - close(fd); - return 0; - -err2: - free(pdata); - -err: - close(fd); - return -1; -} - -static int save_persistent_data(void) -{ - struct crypt_mnt_ftr crypt_ftr; - struct crypt_persist_data *pdata; - char *fname; - off64_t write_offset; - off64_t erase_offset; - int found = 0; - int fd; - int ret; - - if (persist_data == NULL) { - printf("No persistent data to save"); - return -1; - } - - if(get_crypt_ftr_and_key(&crypt_ftr)) { - return -1; - } - - if ((crypt_ftr.major_version != 1) || (crypt_ftr.minor_version != 1)) { - printf("Crypt_ftr version doesn't support persistent data"); - return -1; - } - - ret = validate_persistent_data_storage(&crypt_ftr); - if (ret) { - return -1; - } - - if (get_crypt_ftr_info(&fname, NULL)) { - return -1; - } - - fd = open(fname, O_RDWR); - if (fd < 0) { - printf("Cannot open %s metadata file", fname); - return -1; - } - - pdata = malloc(crypt_ftr.persist_data_size); - if (pdata == NULL) { - printf("Cannot allocate persistant data"); - goto err; - } - - if (lseek64(fd, crypt_ftr.persist_data_offset[0], SEEK_SET) < 0) { - printf("Cannot seek to read persistent data on %s", fname); - goto err2; - } - - if (unix_read(fd, pdata, crypt_ftr.persist_data_size) < 0) { - printf("Error reading persistent data before save"); - goto err2; - } - - if (pdata->persist_magic == PERSIST_DATA_MAGIC) { - /* The first copy is the curent valid copy, so write to - * the second copy and erase this one */ - write_offset = crypt_ftr.persist_data_offset[1]; - erase_offset = crypt_ftr.persist_data_offset[0]; - } else { - /* The second copy must be the valid copy, so write to - * the first copy, and erase the second */ - write_offset = crypt_ftr.persist_data_offset[0]; - erase_offset = crypt_ftr.persist_data_offset[1]; - } - - /* Write the new copy first, if successful, then erase the old copy */ - if (lseek(fd, write_offset, SEEK_SET) < 0) { - printf("Cannot seek to write persistent data"); - goto err2; - } - if (unix_write(fd, persist_data, crypt_ftr.persist_data_size) == - (int) crypt_ftr.persist_data_size) { - if (lseek(fd, erase_offset, SEEK_SET) < 0) { - printf("Cannot seek to erase previous persistent data"); - goto err2; - } - fsync(fd); - memset(pdata, 0, crypt_ftr.persist_data_size); - if (unix_write(fd, pdata, crypt_ftr.persist_data_size) != - (int) crypt_ftr.persist_data_size) { - printf("Cannot write to erase previous persistent data"); - goto err2; - } - fsync(fd); - } else { - printf("Cannot write to save persistent data"); - goto err2; - } - - /* Success */ - free(pdata); - close(fd); - return 0; - -err2: - free(pdata); -err: - close(fd); - return -1; -} - -/* Convert a binary key of specified length into an ascii hex string equivalent, - * without the leading 0x and with null termination - */ -void convert_key_to_hex_ascii(unsigned char *master_key, unsigned int keysize, - char *master_key_ascii) -{ - unsigned int i, a; - unsigned char nibble; - - for (i=0, a=0; i> 4) & 0xf; - master_key_ascii[a] = nibble + (nibble > 9 ? 0x37 : 0x30); - - nibble = master_key[i] & 0xf; - master_key_ascii[a+1] = nibble + (nibble > 9 ? 0x37 : 0x30); - } - - /* Add the null termination */ - master_key_ascii[a] = '\0'; - -} - -static int load_crypto_mapping_table(struct crypt_mnt_ftr *crypt_ftr, unsigned char *master_key, - char *real_blk_name, const char *name, int fd, - char *extra_params) -{ - char buffer[DM_CRYPT_BUF_SIZE]; - struct dm_ioctl *io; - struct dm_target_spec *tgt; - char *crypt_params; - char master_key_ascii[129]; /* Large enough to hold 512 bit key and null */ - int i; - - io = (struct dm_ioctl *) buffer; - - /* Load the mapping table for this device */ - tgt = (struct dm_target_spec *) &buffer[sizeof(struct dm_ioctl)]; - - ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0); - io->target_count = 1; - tgt->status = 0; - tgt->sector_start = 0; - tgt->length = crypt_ftr->fs_size; - strcpy(tgt->target_type, "crypt"); - - crypt_params = buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec); - convert_key_to_hex_ascii(master_key, crypt_ftr->keysize, master_key_ascii); - sprintf(crypt_params, "%s %s 0 %s 0 %s", crypt_ftr->crypto_type_name, - master_key_ascii, real_blk_name, extra_params); - crypt_params += strlen(crypt_params) + 1; - crypt_params = (char *) (((unsigned long)crypt_params + 7) & ~8); /* Align to an 8 byte boundary */ - tgt->next = crypt_params - buffer; - - for (i = 0; i < TABLE_LOAD_RETRIES; i++) { - if (! ioctl(fd, DM_TABLE_LOAD, io)) { - break; - } - usleep(500000); - } - - if (i == TABLE_LOAD_RETRIES) { - /* We failed to load the table, return an error */ - return -1; - } else { - return i + 1; - } -} - - -static int get_dm_crypt_version(int fd, const char *name, int *version) -{ - char buffer[DM_CRYPT_BUF_SIZE]; - struct dm_ioctl *io; - struct dm_target_versions *v; - int i; - - io = (struct dm_ioctl *) buffer; - - ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0); - - if (ioctl(fd, DM_LIST_VERSIONS, io)) { - return -1; - } - - /* Iterate over the returned versions, looking for name of "crypt". - * When found, get and return the version. - */ - v = (struct dm_target_versions *) &buffer[sizeof(struct dm_ioctl)]; - while (v->next) { - if (! strcmp(v->name, "crypt")) { - /* We found the crypt driver, return the version, and get out */ - version[0] = v->version[0]; - version[1] = v->version[1]; - version[2] = v->version[2]; - return 0; - } - v = (struct dm_target_versions *)(((char *)v) + v->next); - } - - return -1; -} - -static int create_crypto_blk_dev(struct crypt_mnt_ftr *crypt_ftr, unsigned char *master_key, - char *real_blk_name, char *crypto_blk_name, const char *name) -{ - char buffer[DM_CRYPT_BUF_SIZE]; - char master_key_ascii[129]; /* Large enough to hold 512 bit key and null */ - char *crypt_params; - struct dm_ioctl *io; - struct dm_target_spec *tgt; - unsigned int minor; - int fd; - int i; - int retval = -1; - int version[3]; - char *extra_params; - int load_count; - - if ((fd = open("/dev/device-mapper", O_RDWR)) < 0 ) { - printf("Cannot open device-mapper\n"); - goto errout; - } - - io = (struct dm_ioctl *) buffer; - - ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0); - if (ioctl(fd, DM_DEV_CREATE, io)) { - printf("Cannot create dm-crypt device\n"); - goto errout; - } - - /* Get the device status, in particular, the name of it's device file */ - ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0); - if (ioctl(fd, DM_DEV_STATUS, io)) { - printf("Cannot retrieve dm-crypt device status\n"); - goto errout; - } - minor = (io->dev & 0xff) | ((io->dev >> 12) & 0xfff00); - snprintf(crypto_blk_name, MAXPATHLEN, "/dev/block/dm-%u", minor); - - extra_params = ""; - if (! get_dm_crypt_version(fd, name, version)) { - /* Support for allow_discards was added in version 1.11.0 */ - if ((version[0] >= 2) || - ((version[0] == 1) && (version[1] >= 11))) { - extra_params = "1 allow_discards"; - printf("Enabling support for allow_discards in dmcrypt.\n"); - } - } - - load_count = load_crypto_mapping_table(crypt_ftr, master_key, real_blk_name, name, - fd, extra_params); - if (load_count < 0) { - printf("Cannot load dm-crypt mapping table.\n"); - goto errout; - } else if (load_count > 1) { - printf("Took %d tries to load dmcrypt table.\n", load_count); - } - - /* Resume this device to activate it */ - ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0); - - if (ioctl(fd, DM_DEV_SUSPEND, io)) { - printf("Cannot resume the dm-crypt device\n"); - goto errout; - } - - /* We made it here with no errors. Woot! */ - retval = 0; - -errout: - close(fd); /* If fd is <0 from a failed open call, it's safe to just ignore the close error */ - - return retval; -} - -static int delete_crypto_blk_dev(char *name) -{ - int fd; - char buffer[DM_CRYPT_BUF_SIZE]; - struct dm_ioctl *io; - int retval = -1; - - if ((fd = open("/dev/device-mapper", O_RDWR)) < 0 ) { - printf("Cannot open device-mapper\n"); - goto errout; - } - - io = (struct dm_ioctl *) buffer; - - ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0); - if (ioctl(fd, DM_DEV_REMOVE, io)) { - printf("Cannot remove dm-crypt device\n"); - goto errout; - } - - /* We made it here with no errors. Woot! */ - retval = 0; - -errout: - close(fd); /* If fd is <0 from a failed open call, it's safe to just ignore the close error */ - - return retval; - -} - -static void pbkdf2(char *passwd, unsigned char *salt, unsigned char *ikey, void *params) { - /* Turn the password into a key and IV that can decrypt the master key */ - PKCS5_PBKDF2_HMAC_SHA1(passwd, strlen(passwd), salt, SALT_LEN, - HASH_COUNT, KEY_LEN_BYTES+IV_LEN_BYTES, ikey); -} - -static void scrypt(char *passwd, unsigned char *salt, unsigned char *ikey, void *params) { - struct crypt_mnt_ftr *ftr = (struct crypt_mnt_ftr *) params; - - int N = 1 << ftr->N_factor; - int r = 1 << ftr->r_factor; - int p = 1 << ftr->p_factor; - - /* Turn the password into a key and IV that can decrypt the master key */ - crypto_scrypt((unsigned char *) passwd, strlen(passwd), salt, SALT_LEN, N, r, p, ikey, - KEY_LEN_BYTES + IV_LEN_BYTES); -} - -static int encrypt_master_key(char *passwd, unsigned char *salt, - unsigned char *decrypted_master_key, - unsigned char *encrypted_master_key, - struct crypt_mnt_ftr *crypt_ftr) -{ - unsigned char ikey[32+32] = { 0 }; /* Big enough to hold a 256 bit key and 256 bit IV */ - EVP_CIPHER_CTX e_ctx; - int encrypted_len, final_len; - - /* Turn the password into a key and IV that can decrypt the master key */ - get_device_scrypt_params(crypt_ftr); - scrypt(passwd, salt, ikey, crypt_ftr); - - /* Initialize the decryption engine */ - if (! EVP_EncryptInit(&e_ctx, EVP_aes_128_cbc(), ikey, ikey+KEY_LEN_BYTES)) { - printf("EVP_EncryptInit failed\n"); - return -1; - } - EVP_CIPHER_CTX_set_padding(&e_ctx, 0); /* Turn off padding as our data is block aligned */ - - /* Encrypt the master key */ - if (! EVP_EncryptUpdate(&e_ctx, encrypted_master_key, &encrypted_len, - decrypted_master_key, KEY_LEN_BYTES)) { - printf("EVP_EncryptUpdate failed\n"); - return -1; - } - if (! EVP_EncryptFinal(&e_ctx, encrypted_master_key + encrypted_len, &final_len)) { - printf("EVP_EncryptFinal failed\n"); - return -1; - } - - if (encrypted_len + final_len != KEY_LEN_BYTES) { - printf("EVP_Encryption length check failed with %d, %d bytes\n", encrypted_len, final_len); - return -1; - } else { - return 0; - } -} - -static int decrypt_master_key(char *passwd, unsigned char *salt, - unsigned char *encrypted_master_key, - unsigned char *decrypted_master_key, - kdf_func kdf, void *kdf_params) -{ - unsigned char ikey[32+32] = { 0 }; /* Big enough to hold a 256 bit key and 256 bit IV */ - EVP_CIPHER_CTX d_ctx; - int decrypted_len, final_len; - - /* Turn the password into a key and IV that can decrypt the master key */ - kdf(passwd, salt, ikey, kdf_params); - - /* Initialize the decryption engine */ - if (! EVP_DecryptInit(&d_ctx, EVP_aes_128_cbc(), ikey, ikey+KEY_LEN_BYTES)) { - return -1; - } - EVP_CIPHER_CTX_set_padding(&d_ctx, 0); /* Turn off padding as our data is block aligned */ - /* Decrypt the master key */ - if (! EVP_DecryptUpdate(&d_ctx, decrypted_master_key, &decrypted_len, - encrypted_master_key, KEY_LEN_BYTES)) { - return -1; - } - if (! EVP_DecryptFinal(&d_ctx, decrypted_master_key + decrypted_len, &final_len)) { - return -1; - } - - if (decrypted_len + final_len != KEY_LEN_BYTES) { - return -1; - } else { - return 0; - } -} - -static void get_kdf_func(struct crypt_mnt_ftr *ftr, kdf_func *kdf, void** kdf_params) -{ - if (ftr->kdf_type == KDF_SCRYPT) { - *kdf = scrypt; - *kdf_params = ftr; - } else { - *kdf = pbkdf2; - *kdf_params = NULL; - } -} - -static int decrypt_master_key_and_upgrade(char *passwd, unsigned char *decrypted_master_key, - struct crypt_mnt_ftr *crypt_ftr) -{ - kdf_func kdf; - void *kdf_params; - int ret; - - get_kdf_func(crypt_ftr, &kdf, &kdf_params); - ret = decrypt_master_key(passwd, crypt_ftr->salt, crypt_ftr->master_key, decrypted_master_key, kdf, - kdf_params); - if (ret != 0) { - printf("failure decrypting master key"); - return ret; - } - - /* - * Upgrade if we're not using the latest KDF. - */ - /*if (crypt_ftr->kdf_type != KDF_SCRYPT) { - crypt_ftr->kdf_type = KDF_SCRYPT; - encrypt_master_key(passwd, crypt_ftr->salt, decrypted_master_key, crypt_ftr->master_key, - crypt_ftr); - put_crypt_ftr_and_key(crypt_ftr); - }*/ - - return ret; -} - -static int create_encrypted_random_key(char *passwd, unsigned char *master_key, unsigned char *salt, - struct crypt_mnt_ftr *crypt_ftr) { - int fd; - unsigned char key_buf[KEY_LEN_BYTES]; - EVP_CIPHER_CTX e_ctx; - int encrypted_len, final_len; - - /* Get some random bits for a key */ - fd = open("/dev/urandom", O_RDONLY); - read(fd, key_buf, sizeof(key_buf)); - read(fd, salt, SALT_LEN); - close(fd); - - /* Now encrypt it with the password */ - return encrypt_master_key(passwd, salt, key_buf, master_key, crypt_ftr); -} - -static int wait_and_unmount(char *mountpoint) -{ - int i, rc; -#define WAIT_UNMOUNT_COUNT 20 - - /* Now umount the tmpfs filesystem */ - for (i=0; ifs_size = %lld\n", crypt_ftr.fs_size); - orig_failed_decrypt_count = crypt_ftr.failed_decrypt_count; - - if (! (crypt_ftr.flags & CRYPT_MNT_KEY_UNENCRYPTED) ) { - decrypt_master_key_and_upgrade(passwd, decrypted_master_key, &crypt_ftr); - } - - if (create_crypto_blk_dev(&crypt_ftr, decrypted_master_key, - real_blkdev, crypto_blkdev, label)) { - printf("Error creating decrypted block device\n"); - return -1; - } - - /* If init detects an encrypted filesystem, it writes a file for each such - * encrypted fs into the tmpfs /data filesystem, and then the framework finds those - * files and passes that data to me */ - /* Create a tmp mount point to try mounting the decryptd fs - * Since we're here, the mount_point should be a tmpfs filesystem, so make - * a directory in it to test mount the decrypted filesystem. - */ - sprintf(tmp_mount_point, "%s/tmp_mnt", mount_point); - mkdir(tmp_mount_point, 0755); - if (fs_mgr_do_mount(fstab, DATA_MNT_POINT, crypto_blkdev, tmp_mount_point)) { - printf("Error temp mounting decrypted block device\n"); - delete_crypto_blk_dev(label); - crypt_ftr.failed_decrypt_count++; - } else { - /* Success, so just umount and we'll mount it properly when we restart - * the framework. - */ - umount(tmp_mount_point); - crypt_ftr.failed_decrypt_count = 0; - } - - if (orig_failed_decrypt_count != crypt_ftr.failed_decrypt_count) { - put_crypt_ftr_and_key(&crypt_ftr); - } - - if (crypt_ftr.failed_decrypt_count) { - /* We failed to mount the device, so return an error */ - rc = crypt_ftr.failed_decrypt_count; - - } else { - /* Woot! Success! Save the name of the crypto block device - * so we can mount it when restarting the framework. - */ - property_set("ro.crypto.fs_crypto_blkdev", crypto_blkdev); - - /* Also save a the master key so we can reencrypted the key - * the key when we want to change the password on it. - */ - memcpy(saved_master_key, decrypted_master_key, KEY_LEN_BYTES); - saved_mount_point = strdup(mount_point); - master_key_saved = 1; - rc = 0; - } - - return rc; -} - -/* Called by vold when it wants to undo the crypto mapping of a volume it - * manages. This is usually in response to a factory reset, when we want - * to undo the crypto mapping so the volume is formatted in the clear. - */ -int cryptfs_revert_volume(const char *label) -{ - return delete_crypto_blk_dev((char *)label); -} - -/* - * Called by vold when it's asked to mount an encrypted, nonremovable volume. - * Setup a dm-crypt mapping, use the saved master key from - * setting up the /data mapping, and return the new device path. - */ -int cryptfs_setup_volume(const char *label, int major, int minor, - char *crypto_sys_path, unsigned int max_path, - int *new_major, int *new_minor) -{ - char real_blkdev[MAXPATHLEN], crypto_blkdev[MAXPATHLEN]; - struct crypt_mnt_ftr sd_crypt_ftr; - struct stat statbuf; - int nr_sec, fd; - - sprintf(real_blkdev, "/dev/block/vold/%d:%d", major, minor); - - get_crypt_ftr_and_key(&sd_crypt_ftr); - - /* Update the fs_size field to be the size of the volume */ - fd = open(real_blkdev, O_RDONLY); - nr_sec = get_blkdev_size(fd); - close(fd); - if (nr_sec == 0) { - printf("Cannot get size of volume %s\n", real_blkdev); - return -1; - } - - sd_crypt_ftr.fs_size = nr_sec; - create_crypto_blk_dev(&sd_crypt_ftr, saved_master_key, real_blkdev, - crypto_blkdev, label); - - stat(crypto_blkdev, &statbuf); - *new_major = MAJOR(statbuf.st_rdev); - *new_minor = MINOR(statbuf.st_rdev); - - /* Create path to sys entry for this block device */ - snprintf(crypto_sys_path, max_path, "/devices/virtual/block/%s", strrchr(crypto_blkdev, '/')+1); - - return 0; -} - -int cryptfs_crypto_complete(void) -{ - return do_crypto_complete("/data"); -} - -#define FSTAB_PREFIX "/fstab." - -int cryptfs_check_footer(void) -{ - int rc = -1; - char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)]; - char propbuf[PROPERTY_VALUE_MAX]; - struct crypt_mnt_ftr crypt_ftr; - - property_get("ro.hardware", propbuf, ""); - snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf); - - fstab = fs_mgr_read_fstab(fstab_filename); - if (!fstab) { - printf("failed to open %s\n", fstab_filename); - return -1; - } - - rc = get_crypt_ftr_and_key(&crypt_ftr); - - return rc; -} - -int cryptfs_check_passwd(char *passwd) -{ - int rc = -1; - char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)]; - char propbuf[PROPERTY_VALUE_MAX]; - - property_get("ro.hardware", propbuf, ""); - snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf); - - fstab = fs_mgr_read_fstab(fstab_filename); - if (!fstab) { - printf("failed to open %s\n", fstab_filename); - return -1; - } - - rc = test_mount_encrypted_fs(passwd, DATA_MNT_POINT, "userdata"); - - return rc; -} - -int cryptfs_verify_passwd(char *passwd) -{ - struct crypt_mnt_ftr crypt_ftr; - /* Allocate enough space for a 256 bit key, but we may use less */ - unsigned char decrypted_master_key[32]; - char encrypted_state[PROPERTY_VALUE_MAX]; - int rc; - - property_get("ro.crypto.state", encrypted_state, ""); - if (strcmp(encrypted_state, "encrypted") ) { - printf("device not encrypted, aborting"); - return -2; - } - - if (!master_key_saved) { - printf("encrypted fs not yet mounted, aborting"); - return -1; - } - - if (!saved_mount_point) { - printf("encrypted fs failed to save mount point, aborting"); - return -1; - } - - if (get_crypt_ftr_and_key(&crypt_ftr)) { - printf("Error getting crypt footer and key\n"); - return -1; - } - - if (crypt_ftr.flags & CRYPT_MNT_KEY_UNENCRYPTED) { - /* If the device has no password, then just say the password is valid */ - rc = 0; - } else { - decrypt_master_key_and_upgrade(passwd, decrypted_master_key, &crypt_ftr); - if (!memcmp(decrypted_master_key, saved_master_key, crypt_ftr.keysize)) { - /* They match, the password is correct */ - rc = 0; - } else { - /* If incorrect, sleep for a bit to prevent dictionary attacks */ - sleep(1); - rc = 1; - } - } - - return rc; -} - -/* Initialize a crypt_mnt_ftr structure. The keysize is - * defaulted to 16 bytes, and the filesystem size to 0. - * Presumably, at a minimum, the caller will update the - * filesystem size and crypto_type_name after calling this function. - */ -static void cryptfs_init_crypt_mnt_ftr(struct crypt_mnt_ftr *ftr) -{ - off64_t off; - - memset(ftr, 0, sizeof(struct crypt_mnt_ftr)); - ftr->magic = CRYPT_MNT_MAGIC; - ftr->major_version = CURRENT_MAJOR_VERSION; - ftr->minor_version = CURRENT_MINOR_VERSION; - ftr->ftr_size = sizeof(struct crypt_mnt_ftr); - ftr->keysize = KEY_LEN_BYTES; - - ftr->kdf_type = KDF_SCRYPT; - get_device_scrypt_params(ftr); - - ftr->persist_data_size = CRYPT_PERSIST_DATA_SIZE; - if (get_crypt_ftr_info(NULL, &off) == 0) { - ftr->persist_data_offset[0] = off + CRYPT_FOOTER_TO_PERSIST_OFFSET; - ftr->persist_data_offset[1] = off + CRYPT_FOOTER_TO_PERSIST_OFFSET + - ftr->persist_data_size; - } -} - -static int cryptfs_enable_wipe(char *crypto_blkdev, off64_t size, int type) -{ - return -1; -} - -#define CRYPT_INPLACE_BUFSIZE 4096 -#define CRYPT_SECTORS_PER_BUFSIZE (CRYPT_INPLACE_BUFSIZE / 512) -static int cryptfs_enable_inplace(char *crypto_blkdev, char *real_blkdev, off64_t size, - off64_t *size_already_done, off64_t tot_size) -{ - int realfd, cryptofd; - char *buf[CRYPT_INPLACE_BUFSIZE]; - int rc = -1; - off64_t numblocks, i, remainder; - off64_t one_pct, cur_pct, new_pct; - off64_t blocks_already_done, tot_numblocks; - - if ( (realfd = open(real_blkdev, O_RDONLY)) < 0) { - printf("Error opening real_blkdev %s for inplace encrypt\n", real_blkdev); - return -1; - } - - if ( (cryptofd = open(crypto_blkdev, O_WRONLY)) < 0) { - printf("Error opening crypto_blkdev %s for inplace encrypt\n", crypto_blkdev); - close(realfd); - return -1; - } - - /* This is pretty much a simple loop of reading 4K, and writing 4K. - * The size passed in is the number of 512 byte sectors in the filesystem. - * So compute the number of whole 4K blocks we should read/write, - * and the remainder. - */ - numblocks = size / CRYPT_SECTORS_PER_BUFSIZE; - remainder = size % CRYPT_SECTORS_PER_BUFSIZE; - tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE; - blocks_already_done = *size_already_done / CRYPT_SECTORS_PER_BUFSIZE; - - printf("Encrypting filesystem in place..."); - - one_pct = tot_numblocks / 100; - cur_pct = 0; - /* process the majority of the filesystem in blocks */ - for (i=0; i cur_pct) { - char buf[8]; - - cur_pct = new_pct; - snprintf(buf, sizeof(buf), "%lld", cur_pct); - property_set("vold.encrypt_progress", buf); - } - if (unix_read(realfd, buf, CRYPT_INPLACE_BUFSIZE) <= 0) { - printf("Error reading real_blkdev %s for inplace encrypt\n", crypto_blkdev); - goto errout; - } - if (unix_write(cryptofd, buf, CRYPT_INPLACE_BUFSIZE) <= 0) { - printf("Error writing crypto_blkdev %s for inplace encrypt\n", crypto_blkdev); - goto errout; - } - } - - /* Do any remaining sectors */ - for (i=0; iflags & (VOL_ENCRYPTABLE | VOL_NONREMOVABLE)) == - (VOL_ENCRYPTABLE | VOL_NONREMOVABLE); -} - -int cryptfs_enable(char *howarg, char *passwd) -{ - return -1; -} - -int cryptfs_changepw(char *newpw) -{ - struct crypt_mnt_ftr crypt_ftr; - unsigned char decrypted_master_key[KEY_LEN_BYTES]; - - /* This is only allowed after we've successfully decrypted the master key */ - if (! master_key_saved) { - printf("Key not saved, aborting"); - return -1; - } - - /* get key */ - if (get_crypt_ftr_and_key(&crypt_ftr)) { - printf("Error getting crypt footer and key"); - return -1; - } - - encrypt_master_key(newpw, crypt_ftr.salt, saved_master_key, crypt_ftr.master_key, &crypt_ftr); - - /* save the key */ - put_crypt_ftr_and_key(&crypt_ftr); - - return 0; -} - -static int persist_get_key(char *fieldname, char *value) -{ - unsigned int i; - - if (persist_data == NULL) { - return -1; - } - for (i = 0; i < persist_data->persist_valid_entries; i++) { - if (!strncmp(persist_data->persist_entry[i].key, fieldname, PROPERTY_KEY_MAX)) { - /* We found it! */ - strlcpy(value, persist_data->persist_entry[i].val, PROPERTY_VALUE_MAX); - return 0; - } - } - - return -1; -} - -static int persist_set_key(char *fieldname, char *value, int encrypted) -{ - unsigned int i; - unsigned int num; - struct crypt_mnt_ftr crypt_ftr; - unsigned int max_persistent_entries; - unsigned int dsize; - - if (persist_data == NULL) { - return -1; - } - - /* If encrypted, use the values from the crypt_ftr, otherwise - * use the values for the current spec. - */ - if (encrypted) { - if(get_crypt_ftr_and_key(&crypt_ftr)) { - return -1; - } - dsize = crypt_ftr.persist_data_size; - } else { - dsize = CRYPT_PERSIST_DATA_SIZE; - } - max_persistent_entries = (dsize - sizeof(struct crypt_persist_data)) / - sizeof(struct crypt_persist_entry); - - num = persist_data->persist_valid_entries; - - for (i = 0; i < num; i++) { - if (!strncmp(persist_data->persist_entry[i].key, fieldname, PROPERTY_KEY_MAX)) { - /* We found an existing entry, update it! */ - memset(persist_data->persist_entry[i].val, 0, PROPERTY_VALUE_MAX); - strlcpy(persist_data->persist_entry[i].val, value, PROPERTY_VALUE_MAX); - return 0; - } - } - - /* We didn't find it, add it to the end, if there is room */ - if (persist_data->persist_valid_entries < max_persistent_entries) { - memset(&persist_data->persist_entry[num], 0, sizeof(struct crypt_persist_entry)); - strlcpy(persist_data->persist_entry[num].key, fieldname, PROPERTY_KEY_MAX); - strlcpy(persist_data->persist_entry[num].val, value, PROPERTY_VALUE_MAX); - persist_data->persist_valid_entries++; - return 0; - } - - return -1; -} - -/* Return the value of the specified field. */ -int cryptfs_getfield(char *fieldname, char *value, int len) -{ - char temp_value[PROPERTY_VALUE_MAX]; - char real_blkdev[MAXPATHLEN]; - /* 0 is success, 1 is not encrypted, - * -1 is value not set, -2 is any other error - */ - int rc = -2; - - if (persist_data == NULL) { - load_persistent_data(); - if (persist_data == NULL) { - printf("Getfield error, cannot load persistent data"); - goto out; - } - } - - if (!persist_get_key(fieldname, temp_value)) { - /* We found it, copy it to the caller's buffer and return */ - strlcpy(value, temp_value, len); - rc = 0; - } else { - /* Sadness, it's not there. Return the error */ - rc = -1; - } - -out: - return rc; -} - -/* Set the value of the specified field. */ -int cryptfs_setfield(char *fieldname, char *value) -{ - struct crypt_persist_data stored_pdata; - struct crypt_persist_data *pdata_p; - struct crypt_mnt_ftr crypt_ftr; - char encrypted_state[PROPERTY_VALUE_MAX]; - /* 0 is success, -1 is an error */ - int rc = -1; - int encrypted = 0; - - if (persist_data == NULL) { - load_persistent_data(); - if (persist_data == NULL) { - printf("Setfield error, cannot load persistent data"); - goto out; - } - } - - property_get("ro.crypto.state", encrypted_state, ""); - if (!strcmp(encrypted_state, "encrypted") ) { - encrypted = 1; - } - - if (persist_set_key(fieldname, value, encrypted)) { - goto out; - } - - /* If we are running encrypted, save the persistent data now */ - if (encrypted) { - if (save_persistent_data()) { - printf("Setfield error, cannot save persistent data"); - goto out; - } - } - - rc = 0; - -out: - return rc; -} diff --git a/crypto/jb/cryptfs.h b/crypto/jb/cryptfs.h deleted file mode 100644 index d815814d3..000000000 --- a/crypto/jb/cryptfs.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source 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. - */ - -/* This structure starts 16,384 bytes before the end of a hardware - * partition that is encrypted, or in a separate partition. It's location - * is specified by a property set in init..rc. - * The structure allocates 48 bytes for a key, but the real key size is - * specified in the struct. Currently, the code is hardcoded to use 128 - * bit keys. - * The fields after salt are only valid in rev 1.1 and later stuctures. - * Obviously, the filesystem does not include the last 16 kbytes - * of the partition if the crypt_mnt_ftr lives at the end of the - * partition. - */ - -#include - -/* The current cryptfs version */ -#define CURRENT_MAJOR_VERSION 1 -#define CURRENT_MINOR_VERSION 2 - -#define CRYPT_FOOTER_OFFSET 0x4000 -#define CRYPT_FOOTER_TO_PERSIST_OFFSET 0x1000 -#define CRYPT_PERSIST_DATA_SIZE 0x1000 - -#define MAX_CRYPTO_TYPE_NAME_LEN 64 - -#define MAX_KEY_LEN 48 -#define SALT_LEN 16 - -/* definitions of flags in the structure below */ -#define CRYPT_MNT_KEY_UNENCRYPTED 0x1 /* The key for the partition is not encrypted. */ -#define CRYPT_ENCRYPTION_IN_PROGRESS 0x2 /* Set when starting encryption, - * clear when done before rebooting */ - -#define CRYPT_MNT_MAGIC 0xD0B5B1C4 -#define PERSIST_DATA_MAGIC 0xE950CD44 - -#define SCRYPT_PROP "ro.crypto.scrypt_params" -#define SCRYPT_DEFAULTS { 15, 3, 1 } - -/* Key Derivation Function algorithms */ -#define KDF_PBKDF2 1 -#define KDF_SCRYPT 2 - -#define __le32 unsigned int -#define __le16 unsigned short int -#define __le8 unsigned char - -struct crypt_mnt_ftr { - __le32 magic; /* See above */ - __le16 major_version; - __le16 minor_version; - __le32 ftr_size; /* in bytes, not including key following */ - __le32 flags; /* See above */ - __le32 keysize; /* in bytes */ - __le32 spare1; /* ignored */ - __le64 fs_size; /* Size of the encrypted fs, in 512 byte sectors */ - __le32 failed_decrypt_count; /* count of # of failed attempts to decrypt and - mount, set to 0 on successful mount */ - unsigned char crypto_type_name[MAX_CRYPTO_TYPE_NAME_LEN]; /* The type of encryption - needed to decrypt this - partition, null terminated */ - __le32 spare2; /* ignored */ - unsigned char master_key[MAX_KEY_LEN]; /* The encrypted key for decrypting the filesystem */ - unsigned char salt[SALT_LEN]; /* The salt used for this encryption */ - __le64 persist_data_offset[2]; /* Absolute offset to both copies of crypt_persist_data - * on device with that info, either the footer of the - * real_blkdevice or the metadata partition. */ - - __le32 persist_data_size; /* The number of bytes allocated to each copy of the - * persistent data table*/ - - __le8 kdf_type; /* The key derivation function used. */ - - /* scrypt parameters. See www.tarsnap.com/scrypt/scrypt.pdf */ - __le8 N_factor; /* (1 << N) */ - __le8 r_factor; /* (1 << r) */ - __le8 p_factor; /* (1 << p) */ -}; - -/* Persistant data that should be available before decryption. - * Things like airplane mode, locale and timezone are kept - * here and can be retrieved by the CryptKeeper UI to properly - * configure the phone before asking for the password - * This is only valid if the major and minor version above - * is set to 1.1 or higher. - * - * This is a 4K structure. There are 2 copies, and the code alternates - * writing one and then clearing the previous one. The reading - * code reads the first valid copy it finds, based on the magic number. - * The absolute offset to the first of the two copies is kept in rev 1.1 - * and higher crypt_mnt_ftr structures. - */ -struct crypt_persist_entry { - char key[PROPERTY_KEY_MAX]; - char val[PROPERTY_VALUE_MAX]; -}; - -/* Should be exactly 4K in size */ -struct crypt_persist_data { - __le32 persist_magic; - __le32 persist_valid_entries; - __le32 persist_spare[30]; - struct crypt_persist_entry persist_entry[0]; -}; - -struct volume_info { - unsigned int size; - unsigned int flags; - struct crypt_mnt_ftr crypt_ftr; - char mnt_point[256]; - char blk_dev[256]; - char crypto_blkdev[256]; - char label[256]; -}; -#define VOL_NONREMOVABLE 0x1 -#define VOL_ENCRYPTABLE 0x2 -#define VOL_PRIMARY 0x4 -#define VOL_PROVIDES_ASEC 0x8 - -#ifdef __cplusplus -extern "C" { -#endif - - typedef void (*kdf_func)(char *passwd, unsigned char *salt, unsigned char *ikey, void *params); - - int cryptfs_crypto_complete(void); - int cryptfs_check_footer(void); - int cryptfs_check_passwd(char *pw); - int cryptfs_verify_passwd(char *newpw); - int cryptfs_restart(void); - int cryptfs_enable(char *flag, char *passwd); - int cryptfs_changepw(char *newpw); - int cryptfs_setup_volume(const char *label, int major, int minor, - char *crypto_dev_path, unsigned int max_pathlen, - int *new_major, int *new_minor); - int cryptfs_revert_volume(const char *label); - int cryptfs_getfield(char *fieldname, char *value, int len); - int cryptfs_setfield(char *fieldname, char *value); -#ifdef __cplusplus -} -#endif - diff --git a/crypto/libcrypt_samsung/Android.mk b/crypto/libcrypt_samsung/Android.mk deleted file mode 100644 index 6e0e86903..000000000 --- a/crypto/libcrypt_samsung/Android.mk +++ /dev/null @@ -1,11 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -ifneq ($(TARGET_SIMULATOR),true) - -include $(CLEAR_VARS) -LOCAL_MODULE := libcrypt_samsung -LOCAL_SRC_FILES := $(LOCAL_MODULE).c -LOCAL_MODULE_TAGS := eng -include $(BUILD_STATIC_LIBRARY) - -endif diff --git a/crypto/libcrypt_samsung/include/libcrypt_samsung.h b/crypto/libcrypt_samsung/include/libcrypt_samsung.h deleted file mode 100644 index 2fb6f2c4f..000000000 --- a/crypto/libcrypt_samsung/include/libcrypt_samsung.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2013 a3955269 all rights reversed, no rights reserved. - */ - -#ifndef __LIBCRYPT_SAMSUNG_H__ -#define __LIBCRYPT_SAMSUNG_H__ - -////////////////////////////////////////////////////////////////////////////// -// Name Address Ordinal -// ---- ------- ------- -// SECKM_AES_set_encrypt_key 000010D8 -// SECKM_AES_set_decrypt_key 00001464 -// SECKM_AES_encrypt 00001600 -// SECKM_AES_decrypt 00001A10 -// SECKM_aes_selftest 00001D94 -// verify_EDK 00001F7C -// encrypt_dek 00001FC8 -// decrypt_EDK 000020D4 -// change_EDK 0000218C -// generate_dek_salt 000022A4 -// create_EDK 000023A0 -// free_DEK 000024DC -// alloc_DEK 000024F4 -// SECKM_HMAC_SHA256 00002500 -// SECKM_HMAC_SHA256_selftest 00002690 -// pbkdf 000026FC -// pbkdf_selftest 00002898 -// _SECKM_PRNG_get16 00002958 -// SECKM_PRNG_get16 00002C48 -// _SECKM_PRNG_init 00002C54 -// SECKM_PRNG_selftest 00002F38 -// SECKM_PRNG_set_seed 00002FF0 -// SECKM_PRNG_init 00002FF8 -// SECKM_SHA256_Transform 00003004 -// SECKM_SHA256_Final 000031D8 -// SECKM_SHA256_Update 00003330 -// SECKM_SHA256_Init 000033FC -// SECKM_SHA2_selftest 00003430 -// integrity_check 00003488 -// update_system_property 00003580 -// setsec_km_fips_status 00003630 -// _all_checks 00003684 -// get_fips_status 000036D4 - - -// EDK Payload is defined as: -// Encrypted DEK – EDK itself -// HMAC of EDK (32 bytes ???) -// Salt 16 bytes - -#define EDK_MAGIC 0x1001e4b1 - -#pragma pack(1) - -typedef struct { - unsigned int magic; // EDK_MAGIC - unsigned int flags; // 2 - unsigned int zeros[6]; -} dek_t; - -typedef struct { - unsigned char data[32]; -} edk_t; - - -// size 0x70 -> 112 -typedef struct { - dek_t dek; - edk_t edk; - unsigned char hmac[32]; - unsigned char salt[16]; -} edk_payload_t; - -#pragma pack() - -////////////////////////////////////////////////////////////////////////////// - -int decrypt_EDK( - dek_t *dek, const edk_payload_t *edk, /*const*/ char *passwd); - -typedef int (*decrypt_EDK_t)( - dek_t *dek, const edk_payload_t *edk, /*const*/ char *passwd); - - -int verify_EDK(const edk_payload_t *edk, const char *passwd); -//change_EDK() -//create_EDK() - -// internally just mallocs 32 bytes -dek_t *alloc_DEK(); -void free_DEK(dek_t *dek); -//encrypt_dek() -//generate_dek_salt() - -//pbkdf(_buf_, "passwordPASSWORDpassword", 0x18, "saltSALTsaltSALTsaltSALTsaltSALTsalt", 0x24, 0x1000, 0x140); -int pbkdf( - void *buf, void *pw, int pwlen, void *salt, int saltlen, int hashcnt, - int keylen); - -// getprop("rw.km_fips_status") -// "ready, undefined, error_selftest, error_integrity" -int get_fips_status(); - -////////////////////////////////////////////////////////////////////////////// -// -// libsec_ecryptfs.so (internally uses libkeyutils.so) -// -// Name Address Ordinal -// ---- ------- ------- -// unmount_ecryptfs_drive 00000A78 -// mount_ecryptfs_drive 00000B48 -// fips_read_edk 00000E44 -// fips_save_edk 00000EA4 -// fips_create_edk 00000F20 -// fips_change_password 00001018 -// fips_delete_edk 00001124 -// - -// might depend on /data beeing mounted for reading /data/system/edk_p_sd -// -// filter -// 0: building options without file encryption filtering. -// 1: building options with media files filtering. -// 2: building options with all new files filtering. - -int mount_ecryptfs_drive( - const char *passwd, const char *source, const char *target, int filter); - -typedef int (*mount_ecryptfs_drive_t)( - const char *passwd, const char *source, const char *target, int filter); - -// calls 2 times umount2(source, MNT_EXPIRE) -int unmount_ecryptfs_drive( - const char *source); - -typedef int (*unmount_ecryptfs_drive_t)( - const char *source); - -////////////////////////////////////////////////////////////////////////////// - -#endif // #ifndef __LIBCRYPT_SAMSUNG_H__ - -////////////////////////////////////////////////////////////////////////////// - diff --git a/crypto/libcrypt_samsung/libcrypt_samsung.c b/crypto/libcrypt_samsung/libcrypt_samsung.c deleted file mode 100644 index cd3a17804..000000000 --- a/crypto/libcrypt_samsung/libcrypt_samsung.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2013 a3955269 all rights reversed, no rights reserved. - */ - -////////////////////////////////////////////////////////////////////////////// - -#include -#include -#include - -#include "include/libcrypt_samsung.h" - -////////////////////////////////////////////////////////////////////////////// - -int decrypt_EDK( - dek_t *dek, const edk_payload_t *edk, /*const*/ char *passwd) -{ - void *lib = dlopen("libsec_km.so", RTLD_LAZY); - - if(!lib) - return -100; - - int r = -101; - decrypt_EDK_t sym = (decrypt_EDK_t)dlsym(lib, "decrypt_EDK"); - if(sym) - r = sym(dek, edk, passwd); - - dlclose(lib); - - return r; -} - -int mount_ecryptfs_drive( - const char *passwd, const char *source, const char *target, int filter) -{ - void *lib = dlopen("libsec_ecryptfs.so", RTLD_LAZY); - if(!lib) - return -100; - - int r = -101; - mount_ecryptfs_drive_t sym = (mount_ecryptfs_drive_t)dlsym(lib, "mount_ecryptfs_drive"); - if(sym) - r = sym(passwd, source, target, filter); - - dlclose(lib); - - return r; -} - -int unmount_ecryptfs_drive( - const char *source) -{ - void *lib = dlopen("libsec_ecryptfs.so", RTLD_LAZY); - if(!lib) - return -100; - - int r = -101; - unmount_ecryptfs_drive_t sym = (unmount_ecryptfs_drive_t)dlsym(lib, "unmount_ecryptfs_drive"); - if(sym) - r = sym(source); - - dlclose(lib); - - return r; -} \ No newline at end of file diff --git a/crypto/logwrapper/Android.mk b/crypto/logwrapper/Android.mk deleted file mode 100644 index 01b61930d..000000000 --- a/crypto/logwrapper/Android.mk +++ /dev/null @@ -1,34 +0,0 @@ -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) - -# ======================================================== -# Static library -# ======================================================== -include $(CLEAR_VARS) -LOCAL_MODULE := liblogwraptwrp -LOCAL_SRC_FILES := logwrap.c -LOCAL_SHARED_LIBRARIES := libcutils liblog -LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include -LOCAL_C_INCLUDES := $(LOCAL_PATH)/include -include $(BUILD_STATIC_LIBRARY) - -# ======================================================== -# Shared library -# ======================================================== -#include $(CLEAR_VARS) -#LOCAL_MODULE := liblogwrap -#LOCAL_SHARED_LIBRARIES := libcutils liblog -#LOCAL_WHOLE_STATIC_LIBRARIES := liblogwrap -#LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include -#LOCAL_C_INCLUDES := $(LOCAL_PATH)/include -#include $(BUILD_SHARED_LIBRARY) - -# ======================================================== -# Executable -# ======================================================== -#include $(CLEAR_VARS) -#LOCAL_SRC_FILES:= logwrapper.c -#LOCAL_MODULE := logwrapper -#LOCAL_STATIC_LIBRARIES := liblog liblogwrap libcutils -#include $(BUILD_EXECUTABLE) diff --git a/crypto/logwrapper/NOTICE b/crypto/logwrapper/NOTICE deleted file mode 100644 index c5b1efa7a..000000000 --- a/crypto/logwrapper/NOTICE +++ /dev/null @@ -1,190 +0,0 @@ - - Copyright (c) 2005-2008, The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - - 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. - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - diff --git a/crypto/logwrapper/include/logwrap/logwrap.h b/crypto/logwrapper/include/logwrap/logwrap.h deleted file mode 100644 index 4307a3055..000000000 --- a/crypto/logwrapper/include/logwrap/logwrap.h +++ /dev/null @@ -1,87 +0,0 @@ -/* system/core/include/logwrap/logwrap.h - * - * Copyright 2013, The Android Open Source 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. - */ - -#ifndef __LIBS_LOGWRAP_H -#define __LIBS_LOGWRAP_H - -#include - -__BEGIN_DECLS - -/* - * Run a command while logging its stdout and stderr - * - * WARNING: while this function is running it will clear all SIGCHLD handlers - * if you rely on SIGCHLD in the caller there is a chance zombies will be - * created if you're not calling waitpid after calling this. This function will - * log a warning when it clears SIGCHLD for processes other than the child it - * created. - * - * Arguments: - * argc: the number of elements in argv - * argv: an array of strings containing the command to be executed and its - * arguments as separate strings. argv does not need to be - * NULL-terminated - * status: the equivalent child status as populated by wait(status). This - * value is only valid when logwrap successfully completes. If NULL - * the return value of the child will be the function's return value. - * ignore_int_quit: set to true if you want to completely ignore SIGINT and - * SIGQUIT while logwrap is running. This may force the end-user to - * send a signal twice to signal the caller (once for the child, and - * once for the caller) - * log_target: Specify where to log the output of the child, either LOG_NONE, - * LOG_ALOG (for the Android system log), LOG_KLOG (for the kernel - * log), or LOG_FILE (and you need to specify a pathname in the - * file_path argument, otherwise pass NULL). These are bit fields, - * and can be OR'ed together to log to multiple places. - * abbreviated: If true, capture up to the first 100 lines and last 4K of - * output from the child. The abbreviated output is not dumped to - * the specified log until the child has exited. - * file_path: if log_target has the LOG_FILE bit set, then this parameter - * must be set to the pathname of the file to log to. - * - * Return value: - * 0 when logwrap successfully run the child process and captured its status - * -1 when an internal error occurred - * -ECHILD if status is NULL and the child didn't exit properly - * the return value of the child if it exited properly and status is NULL - * - */ - -/* Values for the log_target parameter android_fork_execvp_ext() */ -#define LOG_NONE 0 -#define LOG_ALOG 1 -#define LOG_KLOG 2 -#define LOG_FILE 4 - -int android_fork_execvp_ext(int argc, char* argv[], int *status, bool ignore_int_quit, - int log_target, bool abbreviated, char *file_path); - -/* Similar to above, except abbreviated logging is not available, and if logwrap - * is true, logging is to the Android system log, and if false, there is no - * logging. - */ -static inline int android_fork_execvp(int argc, char* argv[], int *status, - bool ignore_int_quit, bool logwrap) -{ - return android_fork_execvp_ext(argc, argv, status, ignore_int_quit, - (logwrap ? LOG_ALOG : LOG_NONE), false, NULL); -} - -__END_DECLS - -#endif /* __LIBS_LOGWRAP_H */ diff --git a/crypto/logwrapper/logwrap.c b/crypto/logwrapper/logwrap.c deleted file mode 100644 index 4ca1db4c8..000000000 --- a/crypto/logwrapper/logwrap.c +++ /dev/null @@ -1,569 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "private/android_filesystem_config.h" -#include "cutils/log.h" -#include - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) -#define MIN(a,b) (((a)<(b))?(a):(b)) - -static pthread_mutex_t fd_mutex = PTHREAD_MUTEX_INITIALIZER; - -#define ERROR(fmt, args...) \ -do { \ - fprintf(stderr, fmt, ## args); \ - ALOG(LOG_ERROR, "logwrapper", fmt, ## args); \ -} while(0) - -#define FATAL_CHILD(fmt, args...) \ -do { \ - ERROR(fmt, ## args); \ - _exit(-1); \ -} while(0) - -#define MAX_KLOG_TAG 16 - -/* This is a simple buffer that holds up to the first beginning_buf->buf_size - * bytes of output from a command. - */ -#define BEGINNING_BUF_SIZE 0x1000 -struct beginning_buf { - char *buf; - size_t alloc_len; - /* buf_size is the usable space, which is one less than the allocated size */ - size_t buf_size; - size_t used_len; -}; - -/* This is a circular buf that holds up to the last ending_buf->buf_size bytes - * of output from a command after the first beginning_buf->buf_size bytes - * (which are held in beginning_buf above). - */ -#define ENDING_BUF_SIZE 0x1000 -struct ending_buf { - char *buf; - ssize_t alloc_len; - /* buf_size is the usable space, which is one less than the allocated size */ - ssize_t buf_size; - ssize_t used_len; - /* read and write offsets into the circular buffer */ - int read; - int write; -}; - - /* A structure to hold all the abbreviated buf data */ -struct abbr_buf { - struct beginning_buf b_buf; - struct ending_buf e_buf; - int beginning_buf_full; -}; - -/* Collect all the various bits of info needed for logging in one place. */ -struct log_info { - int log_target; - char klog_fmt[MAX_KLOG_TAG * 2]; - char *btag; - bool abbreviated; - FILE *fp; - struct abbr_buf a_buf; -}; - -/* Forware declaration */ -static void add_line_to_abbr_buf(struct abbr_buf *a_buf, char *linebuf, int linelen); - -/* Return 0 on success, and 1 when full */ -static int add_line_to_linear_buf(struct beginning_buf *b_buf, - char *line, ssize_t line_len) -{ - size_t new_len; - char *new_buf; - int full = 0; - - if ((line_len + b_buf->used_len) > b_buf->buf_size) { - full = 1; - } else { - /* Add to the end of the buf */ - memcpy(b_buf->buf + b_buf->used_len, line, line_len); - b_buf->used_len += line_len; - } - - return full; -} - -static void add_line_to_circular_buf(struct ending_buf *e_buf, - char *line, ssize_t line_len) -{ - ssize_t free_len; - ssize_t needed_space; - char *new_buf; - int cnt; - - if (e_buf->buf == NULL) { - return; - } - - if (line_len > e_buf->buf_size) { - return; - } - - free_len = e_buf->buf_size - e_buf->used_len; - - if (line_len > free_len) { - /* remove oldest entries at read, and move read to make - * room for the new string */ - needed_space = line_len - free_len; - e_buf->read = (e_buf->read + needed_space) % e_buf->buf_size; - e_buf->used_len -= needed_space; - } - - /* Copy the line into the circular buffer, dealing with possible - * wraparound. - */ - cnt = MIN(line_len, e_buf->buf_size - e_buf->write); - memcpy(e_buf->buf + e_buf->write, line, cnt); - if (cnt < line_len) { - memcpy(e_buf->buf, line + cnt, line_len - cnt); - } - e_buf->used_len += line_len; - e_buf->write = (e_buf->write + line_len) % e_buf->buf_size; -} - -/* Log directly to the specified log */ -static void do_log_line(struct log_info *log_info, char *line) { - if (log_info->log_target & LOG_KLOG) { - klog_write(6, log_info->klog_fmt, line); - } - if (log_info->log_target & LOG_ALOG) { - ALOG(LOG_INFO, log_info->btag, "%s", line); - } - if (log_info->log_target & LOG_FILE) { - fprintf(log_info->fp, "%s\n", line); - } -} - -/* Log to either the abbreviated buf, or directly to the specified log - * via do_log_line() above. - */ -static void log_line(struct log_info *log_info, char *line, int len) { - if (log_info->abbreviated) { - add_line_to_abbr_buf(&log_info->a_buf, line, len); - } else { - do_log_line(log_info, line); - } -} - -/* - * The kernel will take a maximum of 1024 bytes in any single write to - * the kernel logging device file, so find and print each line one at - * a time. The allocated size for buf should be at least 1 byte larger - * than buf_size (the usable size of the buffer) to make sure there is - * room to temporarily stuff a null byte to terminate a line for logging. - */ -static void print_buf_lines(struct log_info *log_info, char *buf, int buf_size) -{ - char *line_start; - char c; - int line_len; - int i; - - line_start = buf; - for (i = 0; i < buf_size; i++) { - if (*(buf + i) == '\n') { - /* Found a line ending, print the line and compute new line_start */ - /* Save the next char and replace with \0 */ - c = *(buf + i + 1); - *(buf + i + 1) = '\0'; - do_log_line(log_info, line_start); - /* Restore the saved char */ - *(buf + i + 1) = c; - line_start = buf + i + 1; - } else if (*(buf + i) == '\0') { - /* The end of the buffer, print the last bit */ - do_log_line(log_info, line_start); - break; - } - } - /* If the buffer was completely full, and didn't end with a newline, just - * ignore the partial last line. - */ -} - -static void init_abbr_buf(struct abbr_buf *a_buf) { - char *new_buf; - - memset(a_buf, 0, sizeof(struct abbr_buf)); - new_buf = malloc(BEGINNING_BUF_SIZE); - if (new_buf) { - a_buf->b_buf.buf = new_buf; - a_buf->b_buf.alloc_len = BEGINNING_BUF_SIZE; - a_buf->b_buf.buf_size = BEGINNING_BUF_SIZE - 1; - } - new_buf = malloc(ENDING_BUF_SIZE); - if (new_buf) { - a_buf->e_buf.buf = new_buf; - a_buf->e_buf.alloc_len = ENDING_BUF_SIZE; - a_buf->e_buf.buf_size = ENDING_BUF_SIZE - 1; - } -} - -static void free_abbr_buf(struct abbr_buf *a_buf) { - free(a_buf->b_buf.buf); - free(a_buf->e_buf.buf); -} - -static void add_line_to_abbr_buf(struct abbr_buf *a_buf, char *linebuf, int linelen) { - if (!a_buf->beginning_buf_full) { - a_buf->beginning_buf_full = - add_line_to_linear_buf(&a_buf->b_buf, linebuf, linelen); - } - if (a_buf->beginning_buf_full) { - add_line_to_circular_buf(&a_buf->e_buf, linebuf, linelen); - } -} - -static void print_abbr_buf(struct log_info *log_info) { - struct abbr_buf *a_buf = &log_info->a_buf; - - /* Add the abbreviated output to the kernel log */ - if (a_buf->b_buf.alloc_len) { - print_buf_lines(log_info, a_buf->b_buf.buf, a_buf->b_buf.used_len); - } - - /* Print an ellipsis to indicate that the buffer has wrapped or - * is full, and some data was not logged. - */ - if (a_buf->e_buf.used_len == a_buf->e_buf.buf_size) { - do_log_line(log_info, "...\n"); - } - - if (a_buf->e_buf.used_len == 0) { - return; - } - - /* Simplest way to print the circular buffer is allocate a second buf - * of the same size, and memcpy it so it's a simple linear buffer, - * and then cal print_buf_lines on it */ - if (a_buf->e_buf.read < a_buf->e_buf.write) { - /* no wrap around, just print it */ - print_buf_lines(log_info, a_buf->e_buf.buf + a_buf->e_buf.read, - a_buf->e_buf.used_len); - } else { - /* The circular buffer will always have at least 1 byte unused, - * so by allocating alloc_len here we will have at least - * 1 byte of space available as required by print_buf_lines(). - */ - char * nbuf = malloc(a_buf->e_buf.alloc_len); - if (!nbuf) { - return; - } - int first_chunk_len = a_buf->e_buf.buf_size - a_buf->e_buf.read; - memcpy(nbuf, a_buf->e_buf.buf + a_buf->e_buf.read, first_chunk_len); - /* copy second chunk */ - memcpy(nbuf + first_chunk_len, a_buf->e_buf.buf, a_buf->e_buf.write); - print_buf_lines(log_info, nbuf, first_chunk_len + a_buf->e_buf.write); - free(nbuf); - } -} - -static int parent(const char *tag, int parent_read, pid_t pid, - int *chld_sts, int log_target, bool abbreviated, char *file_path) { - int status = 0; - char buffer[4096]; - struct pollfd poll_fds[] = { - [0] = { - .fd = parent_read, - .events = POLLIN, - }, - }; - int rc = 0; - int fd; - - struct log_info log_info; - - int a = 0; // start index of unprocessed data - int b = 0; // end index of unprocessed data - int sz; - bool found_child = false; - char tmpbuf[256]; - - log_info.btag = basename(tag); - if (!log_info.btag) { - log_info.btag = (char*) tag; - } - - if (abbreviated && (log_target == LOG_NONE)) { - abbreviated = 0; - } - if (abbreviated) { - init_abbr_buf(&log_info.a_buf); - } - - if (log_target & LOG_KLOG) { - snprintf(log_info.klog_fmt, sizeof(log_info.klog_fmt), - "<6>%.*s: %%s", MAX_KLOG_TAG, log_info.btag); - } - - if ((log_target & LOG_FILE) && !file_path) { - /* No file_path specified, clear the LOG_FILE bit */ - log_target &= ~LOG_FILE; - } - - if (log_target & LOG_FILE) { - fd = open(file_path, O_WRONLY | O_CREAT, 0664); - if (fd < 0) { - ERROR("Cannot log to file %s\n", file_path); - log_target &= ~LOG_FILE; - } else { - lseek(fd, 0, SEEK_END); - log_info.fp = fdopen(fd, "a"); - } - } - - log_info.log_target = log_target; - log_info.abbreviated = abbreviated; - - while (!found_child) { - if (TEMP_FAILURE_RETRY(poll(poll_fds, ARRAY_SIZE(poll_fds), -1)) < 0) { - ERROR("poll failed\n"); - rc = -1; - goto err_poll; - } - - if (poll_fds[0].revents & POLLIN) { - sz = read(parent_read, &buffer[b], sizeof(buffer) - 1 - b); - - sz += b; - // Log one line at a time - for (b = 0; b < sz; b++) { - if (buffer[b] == '\r') { - if (abbreviated) { - /* The abbreviated logging code uses newline as - * the line separator. Lucikly, the pty layer - * helpfully cooks the output of the command - * being run and inserts a CR before NL. So - * I just change it to NL here when doing - * abbreviated logging. - */ - buffer[b] = '\n'; - } else { - buffer[b] = '\0'; - } - } else if (buffer[b] == '\n') { - buffer[b] = '\0'; - log_line(&log_info, &buffer[a], b - a); - a = b + 1; - } - } - - if (a == 0 && b == sizeof(buffer) - 1) { - // buffer is full, flush - buffer[b] = '\0'; - log_line(&log_info, &buffer[a], b - a); - b = 0; - } else if (a != b) { - // Keep left-overs - b -= a; - memmove(buffer, &buffer[a], b); - a = 0; - } else { - a = 0; - b = 0; - } - } - - if (poll_fds[0].revents & POLLHUP) { - int ret; - - ret = waitpid(pid, &status, WNOHANG); - if (ret < 0) { - rc = errno; - ALOG(LOG_ERROR, "logwrap", "waitpid failed with %s\n", strerror(errno)); - goto err_waitpid; - } - if (ret > 0) { - found_child = true; - } - } - } - - if (chld_sts != NULL) { - *chld_sts = status; - } else { - if (WIFEXITED(status)) - rc = WEXITSTATUS(status); - else - rc = -ECHILD; - } - - // Flush remaining data - if (a != b) { - buffer[b] = '\0'; - log_line(&log_info, &buffer[a], b - a); - } - - /* All the output has been processed, time to dump the abbreviated output */ - if (abbreviated) { - print_abbr_buf(&log_info); - } - - if (WIFEXITED(status)) { - if (WEXITSTATUS(status)) { - snprintf(tmpbuf, sizeof(tmpbuf), - "%s terminated by exit(%d)\n", log_info.btag, WEXITSTATUS(status)); - do_log_line(&log_info, tmpbuf); - } - } else { - if (WIFSIGNALED(status)) { - snprintf(tmpbuf, sizeof(tmpbuf), - "%s terminated by signal %d\n", log_info.btag, WTERMSIG(status)); - do_log_line(&log_info, tmpbuf); - } else if (WIFSTOPPED(status)) { - snprintf(tmpbuf, sizeof(tmpbuf), - "%s stopped by signal %d\n", log_info.btag, WSTOPSIG(status)); - do_log_line(&log_info, tmpbuf); - } - } - -err_waitpid: -err_poll: - if (log_target & LOG_FILE) { - fclose(log_info.fp); /* Also closes underlying fd */ - } - if (abbreviated) { - free_abbr_buf(&log_info.a_buf); - } - return rc; -} - -static void child(int argc, char* argv[]) { - // create null terminated argv_child array - char* argv_child[argc + 1]; - memcpy(argv_child, argv, argc * sizeof(char *)); - argv_child[argc] = NULL; - - if (execvp(argv_child[0], argv_child)) { - FATAL_CHILD("executing %s failed: %s\n", argv_child[0], - strerror(errno)); - } -} - -int android_fork_execvp_ext(int argc, char* argv[], int *status, bool ignore_int_quit, - int log_target, bool abbreviated, char *file_path) { - pid_t pid; - int parent_ptty; - int child_ptty; - char *child_devname = NULL; - struct sigaction intact; - struct sigaction quitact; - sigset_t blockset; - sigset_t oldset; - int rc = 0; - - rc = pthread_mutex_lock(&fd_mutex); - if (rc) { - ERROR("failed to lock signal_fd mutex\n"); - goto err_lock; - } - - /* Use ptty instead of socketpair so that STDOUT is not buffered */ - parent_ptty = open("/dev/ptmx", O_RDWR); - if (parent_ptty < 0) { - ERROR("Cannot create parent ptty\n"); - rc = -1; - goto err_open; - } - - if (grantpt(parent_ptty) || unlockpt(parent_ptty) || - ((child_devname = (char*)ptsname(parent_ptty)) == 0)) { - ERROR("Problem with /dev/ptmx\n"); - rc = -1; - goto err_ptty; - } - - child_ptty = open(child_devname, O_RDWR); - if (child_ptty < 0) { - ERROR("Cannot open child_ptty\n"); - rc = -1; - goto err_child_ptty; - } - - sigemptyset(&blockset); - sigaddset(&blockset, SIGINT); - sigaddset(&blockset, SIGQUIT); - pthread_sigmask(SIG_BLOCK, &blockset, &oldset); - - pid = fork(); - if (pid < 0) { - close(child_ptty); - ERROR("Failed to fork\n"); - rc = -1; - goto err_fork; - } else if (pid == 0) { - pthread_mutex_unlock(&fd_mutex); - pthread_sigmask(SIG_SETMASK, &oldset, NULL); - close(parent_ptty); - - // redirect stdout and stderr - dup2(child_ptty, 1); - dup2(child_ptty, 2); - close(child_ptty); - - child(argc, argv); - } else { - close(child_ptty); - if (ignore_int_quit) { - struct sigaction ignact; - - memset(&ignact, 0, sizeof(ignact)); - ignact.sa_handler = SIG_IGN; - sigaction(SIGINT, &ignact, &intact); - sigaction(SIGQUIT, &ignact, &quitact); - } - - rc = parent(argv[0], parent_ptty, pid, status, log_target, - abbreviated, file_path); - } - - if (ignore_int_quit) { - sigaction(SIGINT, &intact, NULL); - sigaction(SIGQUIT, &quitact, NULL); - } -err_fork: - pthread_sigmask(SIG_SETMASK, &oldset, NULL); -err_child_ptty: -err_ptty: - close(parent_ptty); -err_open: - pthread_mutex_unlock(&fd_mutex); -err_lock: - return rc; -} diff --git a/crypto/logwrapper/logwrapper.c b/crypto/logwrapper/logwrapper.c deleted file mode 100644 index d0d8d1471..000000000 --- a/crypto/logwrapper/logwrapper.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source 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. - */ - -#include -#include -#include -#include - -#include -#include - -#include "cutils/log.h" - -void fatal(const char *msg) { - fprintf(stderr, "%s", msg); - ALOG(LOG_ERROR, "logwrapper", "%s", msg); - exit(-1); -} - -void usage() { - fatal( - "Usage: logwrapper [-a] [-d] [-k] BINARY [ARGS ...]\n" - "\n" - "Forks and executes BINARY ARGS, redirecting stdout and stderr to\n" - "the Android logging system. Tag is set to BINARY, priority is\n" - "always LOG_INFO.\n" - "\n" - "-a: Causes logwrapper to do abbreviated logging.\n" - " This logs up to the first 4K and last 4K of the command\n" - " being run, and logs the output when the command exits\n" - "-d: Causes logwrapper to SIGSEGV when BINARY terminates\n" - " fault address is set to the status of wait()\n" - "-k: Causes logwrapper to log to the kernel log instead of\n" - " the Android system log\n"); -} - -int main(int argc, char* argv[]) { - int seg_fault_on_exit = 0; - int log_target = LOG_ALOG; - bool abbreviated = false; - int ch; - int status = 0xAAAA; - int rc; - - while ((ch = getopt(argc, argv, "adk")) != -1) { - switch (ch) { - case 'a': - abbreviated = true; - break; - case 'd': - seg_fault_on_exit = 1; - break; - case 'k': - log_target = LOG_KLOG; - klog_set_level(6); - break; - case '?': - default: - usage(); - } - } - argc -= optind; - argv += optind; - - if (argc < 1) { - usage(); - } - - rc = android_fork_execvp_ext(argc, &argv[0], &status, true, - log_target, abbreviated, NULL); - if (!rc) { - if (WIFEXITED(status)) - rc = WEXITSTATUS(status); - else - rc = -ECHILD; - } - - if (seg_fault_on_exit) { - *(int *)status = 0; // causes SIGSEGV with fault_address = status - } - - return rc; -} diff --git a/crypto/lollipop/Android.mk b/crypto/lollipop/Android.mk index 40b4d5f95..da25eac30 100644 --- a/crypto/lollipop/Android.mk +++ b/crypto/lollipop/Android.mk @@ -21,16 +21,17 @@ common_shared_libraries := \ libcutils \ liblog \ libdiskconfig \ - libhardware_legacy \ liblogwrap \ libext4_utils \ libf2fs_sparseblock \ libcrypto \ libselinux \ libutils \ - libhardware \ + libminhardware \ libsoftkeymaster +common_shared_libraries := libcrypto libselinux libhardware libsoftkeymaster libcutils + LOCAL_MODULE := libcryptfslollipop LOCAL_MODULE_TAGS := eng optional LOCAL_CFLAGS := @@ -44,9 +45,26 @@ LOCAL_SRC_FILES = cryptfs.c # hardware/libhardware/include/hardware \ # system/security/softkeymaster/include/keymaster #LOCAL_SHARED_LIBRARIES += libc liblog libcutils libcrypto libext4_utils -LOCAL_SHARED_LIBRARIES := $(common_shared_libraries) libmincrypttwrp liblogwrap +LOCAL_SHARED_LIBRARIES := $(common_shared_libraries) libmincrypttwrp LOCAL_C_INCLUDES := external/openssl/include $(common_c_includes) -LOCAL_WHOLE_STATIC_LIBRARIES += libfs_mgr libscrypt_static +LOCAL_WHOLE_STATIC_LIBRARIES += libscrypttwrp_static + +include $(BUILD_SHARED_LIBRARY) + +include $(CLEAR_VARS) + +LOCAL_SHARED_LIBRARIES := libcutils liblog + +LOCAL_INCLUDES += $(LOCAL_PATH) $(LOCAL_PATH)\libminhardware + +LOCAL_CFLAGS += -DQEMU_HARDWARE +QEMU_HARDWARE := true + +LOCAL_SHARED_LIBRARIES += libdl + +LOCAL_SRC_FILES += libminhardware/hardware.c + +LOCAL_MODULE:= libminhardware include $(BUILD_SHARED_LIBRARY) endif diff --git a/crypto/lollipop/cryptfs.c b/crypto/lollipop/cryptfs.c index 0277c78ef..90f1523d3 100644 --- a/crypto/lollipop/cryptfs.c +++ b/crypto/lollipop/cryptfs.c @@ -37,27 +37,17 @@ #include #include #include -#include #include -#include #include #include "cryptfs.h" -#define LOG_TAG "Cryptfs" -#include "cutils/log.h" #include "cutils/properties.h" -#include "cutils/android_reboot.h" -#include "hardware_legacy/power.h" -#include -//#include "VolumeManager.h" -//#include "VoldUtil.h" #include "crypto_scrypt.h" -#include "ext4_utils.h" -#include "f2fs_sparseblock.h" -//#include "CheckBattery.h" -//#include "Process.h" - #include +#ifndef min /* already defined by windows.h */ +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + #define UNUSED __attribute__((unused)) #define UNUSED __attribute__((unused)) @@ -91,6 +81,16 @@ static unsigned char saved_master_key[KEY_LEN_BYTES]; static char *saved_mount_point; static int master_key_saved = 0; static struct crypt_persist_data *persist_data = NULL; +static char key_fname[PROPERTY_VALUE_MAX] = ""; +static char real_blkdev[PROPERTY_VALUE_MAX] = ""; +static char file_system[PROPERTY_VALUE_MAX] = ""; + +void set_partition_data(const char* block_device, const char* key_location, const char* fs) +{ + strcpy(key_fname, key_location); + strcpy(real_blkdev, block_device); + strcpy(file_system, fs); +} static int keymaster_init(keymaster_device_t **keymaster_dev) { @@ -291,31 +291,6 @@ static char* password = 0; static int password_expiry_time = 0; static const int password_max_age_seconds = 60; -struct fstab *fstab; - -enum RebootType {reboot, recovery, shutdown}; -static void cryptfs_reboot(enum RebootType rt) -{ - switch(rt) { - case reboot: - property_set(ANDROID_RB_PROPERTY, "reboot"); - break; - - case recovery: - property_set(ANDROID_RB_PROPERTY, "reboot,recovery"); - break; - - case shutdown: - property_set(ANDROID_RB_PROPERTY, "shutdown"); - break; - } - - sleep(20); - - /* Shouldn't get here, reboot should happen before sleep times out */ - return; -} - static void ioctl_init(struct dm_ioctl *io, size_t dataSize, const char *name, unsigned flags) { memset(io, 0, dataSize); @@ -380,41 +355,6 @@ static void get_device_scrypt_params(struct crypt_mnt_ftr *ftr) { ftr->p_factor = params[2]; } -static unsigned int get_fs_size(char *dev) -{ - int fd, block_size; - struct ext4_super_block sb; - off64_t len; - - if ((fd = open(dev, O_RDONLY)) < 0) { - printf("Cannot open device to get filesystem size "); - return 0; - } - - if (lseek64(fd, 1024, SEEK_SET) < 0) { - printf("Cannot seek to superblock"); - return 0; - } - - if (read(fd, &sb, sizeof(sb)) != sizeof(sb)) { - printf("Cannot read superblock"); - return 0; - } - - close(fd); - - if (le32_to_cpu(sb.s_magic) != EXT4_SUPER_MAGIC) { - printf("Not a valid ext4 superblock"); - return 0; - } - block_size = 1024 << sb.s_log_block_size; - /* compute length in bytes */ - len = ( ((off64_t)sb.s_blocks_count_hi << 32) + sb.s_blocks_count_lo) * block_size; - - /* return length in sectors */ - return (unsigned int) (len / 512); -} - static unsigned int get_blkdev_size(int fd) { unsigned int nr_sec; @@ -432,15 +372,12 @@ static int get_crypt_ftr_info(char **metadata_fname, off64_t *off) static off64_t cached_off = 0; static char cached_metadata_fname[PROPERTY_VALUE_MAX] = ""; int fd; - char key_loc[PROPERTY_VALUE_MAX]; - char real_blkdev[PROPERTY_VALUE_MAX]; unsigned int nr_sec; int rc = -1; if (!cached_data) { - fs_mgr_get_crypt_info(fstab, key_loc, real_blkdev, sizeof(key_loc)); - printf("get_crypt_ftr_info crypto key location: '%s'\n", key_loc); - if (!strcmp(key_loc, KEY_IN_FOOTER)) { + printf("get_crypt_ftr_info crypto key location: '%s'\n", key_fname); + if (!strcmp(key_fname, KEY_IN_FOOTER)) { if ( (fd = open(real_blkdev, O_RDWR)) < 0) { printf("Cannot open real block device %s\n", real_blkdev); return -1; @@ -459,7 +396,7 @@ static int get_crypt_ftr_info(char **metadata_fname, off64_t *off) } close(fd); } else { - strlcpy(cached_metadata_fname, key_loc, sizeof(cached_metadata_fname)); + strlcpy(cached_metadata_fname, key_fname, sizeof(cached_metadata_fname)); cached_off = 0; cached_data = 1; } @@ -478,65 +415,6 @@ static int get_crypt_ftr_info(char **metadata_fname, off64_t *off) return rc; } -/* key or salt can be NULL, in which case just skip writing that value. Useful to - * update the failed mount count but not change the key. - */ -static int put_crypt_ftr_and_key(struct crypt_mnt_ftr *crypt_ftr) -{ - printf("TWRP NOT putting crypt footer and key\n"); - return 0; - int fd; - unsigned int nr_sec, cnt; - /* starting_off is set to the SEEK_SET offset - * where the crypto structure starts - */ - off64_t starting_off; - int rc = -1; - char *fname = NULL; - struct stat statbuf; - - if (get_crypt_ftr_info(&fname, &starting_off)) { - printf("Unable to get crypt_ftr_info\n"); - return -1; - } - if (fname[0] != '/') { - printf("Unexpected value for crypto key location\n"); - return -1; - } - if ( (fd = open(fname, O_RDWR | O_CREAT, 0600)) < 0) { - printf("Cannot open footer file %s for put\n", fname); - return -1; - } - - /* Seek to the start of the crypt footer */ - if (lseek64(fd, starting_off, SEEK_SET) == -1) { - printf("Cannot seek to real block device footer\n"); - goto errout; - } - - if ((cnt = write(fd, crypt_ftr, sizeof(struct crypt_mnt_ftr))) != sizeof(struct crypt_mnt_ftr)) { - printf("Cannot write real block device footer\n"); - goto errout; - } - - fstat(fd, &statbuf); - /* If the keys are kept on a raw block device, do not try to truncate it. */ - if (S_ISREG(statbuf.st_mode)) { - if (ftruncate(fd, 0x4000)) { - printf("Cannot set footer file size\n"); - goto errout; - } - } - - /* Success! */ - rc = 0; - -errout: - close(fd); - return rc; - -} - static inline int unix_read(int fd, void* buff, int len) { return TEMP_FAILURE_RETRY(read(fd, buff, len)); @@ -554,75 +432,6 @@ static void init_empty_persist_data(struct crypt_persist_data *pdata, int len) pdata->persist_valid_entries = 0; } -/* A routine to update the passed in crypt_ftr to the lastest version. - * fd is open read/write on the device that holds the crypto footer and persistent - * data, crypt_ftr is a pointer to the struct to be updated, and offset is the - * absolute offset to the start of the crypt_mnt_ftr on the passed in fd. - */ -static void upgrade_crypt_ftr(int fd, struct crypt_mnt_ftr *crypt_ftr, off64_t offset) -{ - int orig_major = crypt_ftr->major_version; - int orig_minor = crypt_ftr->minor_version; -printf("TWRP NOT upgrading crypto footer\n"); -return; // do not upgrade in recovery - if ((crypt_ftr->major_version == 1) && (crypt_ftr->minor_version == 0)) { - struct crypt_persist_data *pdata; - off64_t pdata_offset = offset + CRYPT_FOOTER_TO_PERSIST_OFFSET; - - printf("upgrading crypto footer to 1.1"); - - pdata = malloc(CRYPT_PERSIST_DATA_SIZE); - if (pdata == NULL) { - printf("Cannot allocate persisent data\n"); - return; - } - memset(pdata, 0, CRYPT_PERSIST_DATA_SIZE); - - /* Need to initialize the persistent data area */ - if (lseek64(fd, pdata_offset, SEEK_SET) == -1) { - printf("Cannot seek to persisent data offset\n"); - return; - } - /* Write all zeros to the first copy, making it invalid */ - unix_write(fd, pdata, CRYPT_PERSIST_DATA_SIZE); - - /* Write a valid but empty structure to the second copy */ - init_empty_persist_data(pdata, CRYPT_PERSIST_DATA_SIZE); - unix_write(fd, pdata, CRYPT_PERSIST_DATA_SIZE); - - /* Update the footer */ - crypt_ftr->persist_data_size = CRYPT_PERSIST_DATA_SIZE; - crypt_ftr->persist_data_offset[0] = pdata_offset; - crypt_ftr->persist_data_offset[1] = pdata_offset + CRYPT_PERSIST_DATA_SIZE; - crypt_ftr->minor_version = 1; - } - - if ((crypt_ftr->major_version == 1) && (crypt_ftr->minor_version == 1)) { - printf("upgrading crypto footer to 1.2"); - /* But keep the old kdf_type. - * It will get updated later to KDF_SCRYPT after the password has been verified. - */ - crypt_ftr->kdf_type = KDF_PBKDF2; - get_device_scrypt_params(crypt_ftr); - crypt_ftr->minor_version = 2; - } - - if ((crypt_ftr->major_version == 1) && (crypt_ftr->minor_version == 2)) { - printf("upgrading crypto footer to 1.3"); - crypt_ftr->crypt_type = CRYPT_TYPE_PASSWORD; - crypt_ftr->minor_version = 3; - } - - if ((orig_major != crypt_ftr->major_version) || (orig_minor != crypt_ftr->minor_version)) { - if (lseek64(fd, offset, SEEK_SET) == -1) { - printf("Cannot seek to crypt footer\n"); - return; - } - unix_write(fd, crypt_ftr, sizeof(struct crypt_mnt_ftr)); - } -} - - static int get_crypt_ftr_and_key(struct crypt_mnt_ftr *crypt_ftr) { int fd; @@ -682,9 +491,9 @@ static int get_crypt_ftr_and_key(struct crypt_mnt_ftr *crypt_ftr) /* If this is a verion 1.0 crypt_ftr, make it a 1.1 crypt footer, and update the * copy on disk before returning. */ - if (crypt_ftr->minor_version < CURRENT_MINOR_VERSION) { + /*if (crypt_ftr->minor_version < CURRENT_MINOR_VERSION) { upgrade_crypt_ftr(fd, crypt_ftr, starting_off); - } + }*/ /* Success! */ rc = 0; @@ -694,229 +503,6 @@ errout: return rc; } -static int validate_persistent_data_storage(struct crypt_mnt_ftr *crypt_ftr) -{ - if (crypt_ftr->persist_data_offset[0] + crypt_ftr->persist_data_size > - crypt_ftr->persist_data_offset[1]) { - printf("Crypt_ftr persist data regions overlap"); - return -1; - } - - if (crypt_ftr->persist_data_offset[0] >= crypt_ftr->persist_data_offset[1]) { - printf("Crypt_ftr persist data region 0 starts after region 1"); - return -1; - } - - if (((crypt_ftr->persist_data_offset[1] + crypt_ftr->persist_data_size) - - (crypt_ftr->persist_data_offset[0] - CRYPT_FOOTER_TO_PERSIST_OFFSET)) > - CRYPT_FOOTER_OFFSET) { - printf("Persistent data extends past crypto footer"); - return -1; - } - - return 0; -} - -static int load_persistent_data(void) -{ - struct crypt_mnt_ftr crypt_ftr; - struct crypt_persist_data *pdata = NULL; - char encrypted_state[PROPERTY_VALUE_MAX]; - char *fname; - int found = 0; - int fd; - int ret; - int i; - - if (persist_data) { - /* Nothing to do, we've already loaded or initialized it */ - return 0; - } - - - /* If not encrypted, just allocate an empty table and initialize it */ - property_get("ro.crypto.state", encrypted_state, ""); - if (strcmp(encrypted_state, "encrypted") ) { - pdata = malloc(CRYPT_PERSIST_DATA_SIZE); - if (pdata) { - init_empty_persist_data(pdata, CRYPT_PERSIST_DATA_SIZE); - persist_data = pdata; - return 0; - } - return -1; - } - - if(get_crypt_ftr_and_key(&crypt_ftr)) { - return -1; - } - - if ((crypt_ftr.major_version < 1) - || (crypt_ftr.major_version == 1 && crypt_ftr.minor_version < 1)) { - printf("Crypt_ftr version doesn't support persistent data"); - return -1; - } - - if (get_crypt_ftr_info(&fname, NULL)) { - return -1; - } - - ret = validate_persistent_data_storage(&crypt_ftr); - if (ret) { - return -1; - } - - fd = open(fname, O_RDONLY); - if (fd < 0) { - printf("Cannot open %s metadata file", fname); - return -1; - } - - if (persist_data == NULL) { - pdata = malloc(crypt_ftr.persist_data_size); - if (pdata == NULL) { - printf("Cannot allocate memory for persistent data"); - goto err; - } - } - - for (i = 0; i < 2; i++) { - if (lseek64(fd, crypt_ftr.persist_data_offset[i], SEEK_SET) < 0) { - printf("Cannot seek to read persistent data on %s", fname); - goto err2; - } - if (unix_read(fd, pdata, crypt_ftr.persist_data_size) < 0){ - printf("Error reading persistent data on iteration %d", i); - goto err2; - } - if (pdata->persist_magic == PERSIST_DATA_MAGIC) { - found = 1; - break; - } - } - - if (!found) { - printf("Could not find valid persistent data, creating"); - init_empty_persist_data(pdata, crypt_ftr.persist_data_size); - } - - /* Success */ - persist_data = pdata; - close(fd); - return 0; - -err2: - free(pdata); - -err: - close(fd); - return -1; -} - -static int save_persistent_data(void) -{ - struct crypt_mnt_ftr crypt_ftr; - struct crypt_persist_data *pdata; - char *fname; - off64_t write_offset; - off64_t erase_offset; - int found = 0; - int fd; - int ret; - - if (persist_data == NULL) { - printf("No persistent data to save"); - return -1; - } - - if(get_crypt_ftr_and_key(&crypt_ftr)) { - return -1; - } - - if ((crypt_ftr.major_version < 1) - || (crypt_ftr.major_version == 1 && crypt_ftr.minor_version < 1)) { - printf("Crypt_ftr version doesn't support persistent data"); - return -1; - } - - ret = validate_persistent_data_storage(&crypt_ftr); - if (ret) { - return -1; - } - - if (get_crypt_ftr_info(&fname, NULL)) { - return -1; - } - - fd = open(fname, O_RDWR); - if (fd < 0) { - printf("Cannot open %s metadata file", fname); - return -1; - } - - pdata = malloc(crypt_ftr.persist_data_size); - if (pdata == NULL) { - printf("Cannot allocate persistant data"); - goto err; - } - - if (lseek64(fd, crypt_ftr.persist_data_offset[0], SEEK_SET) < 0) { - printf("Cannot seek to read persistent data on %s", fname); - goto err2; - } - - if (unix_read(fd, pdata, crypt_ftr.persist_data_size) < 0) { - printf("Error reading persistent data before save"); - goto err2; - } - - if (pdata->persist_magic == PERSIST_DATA_MAGIC) { - /* The first copy is the curent valid copy, so write to - * the second copy and erase this one */ - write_offset = crypt_ftr.persist_data_offset[1]; - erase_offset = crypt_ftr.persist_data_offset[0]; - } else { - /* The second copy must be the valid copy, so write to - * the first copy, and erase the second */ - write_offset = crypt_ftr.persist_data_offset[0]; - erase_offset = crypt_ftr.persist_data_offset[1]; - } - - /* Write the new copy first, if successful, then erase the old copy */ - if (lseek(fd, write_offset, SEEK_SET) < 0) { - printf("Cannot seek to write persistent data"); - goto err2; - } - if (unix_write(fd, persist_data, crypt_ftr.persist_data_size) == - (int) crypt_ftr.persist_data_size) { - if (lseek(fd, erase_offset, SEEK_SET) < 0) { - printf("Cannot seek to erase previous persistent data"); - goto err2; - } - fsync(fd); - memset(pdata, 0, crypt_ftr.persist_data_size); - if (unix_write(fd, pdata, crypt_ftr.persist_data_size) != - (int) crypt_ftr.persist_data_size) { - printf("Cannot write to erase previous persistent data"); - goto err2; - } - fsync(fd); - } else { - printf("Cannot write to save persistent data"); - goto err2; - } - - /* Success */ - free(pdata); - close(fd); - return 0; - -err2: - free(pdata); -err: - close(fd); - return -1; -} - static int hexdigit (char c) { if (c >= '0' && c <= '9') return c - '0'; @@ -1424,360 +1010,49 @@ static int decrypt_master_key(char *passwd, unsigned char *decrypted_master_key, return ret; } -static int create_encrypted_random_key(char *passwd, unsigned char *master_key, unsigned char *salt, - struct crypt_mnt_ftr *crypt_ftr) { - int fd; - unsigned char key_buf[KEY_LEN_BYTES]; - EVP_CIPHER_CTX e_ctx; - int encrypted_len, final_len; - - /* Get some random bits for a key */ - fd = open("/dev/urandom", O_RDONLY); - read(fd, key_buf, sizeof(key_buf)); - read(fd, salt, SALT_LEN); - close(fd); - - /* Now encrypt it with the password */ - return encrypt_master_key(passwd, salt, key_buf, master_key, crypt_ftr); -} - -static int wait_and_unmount(char *mountpoint, bool kill) +static int test_mount_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr, + char *passwd, char *mount_point, char *label) { - int i, err, rc; -#define WAIT_UNMOUNT_COUNT 20 - - /* Now umount the tmpfs filesystem */ - for (i=0; ifs_size = %lld\n", crypt_ftr->fs_size); + orig_failed_decrypt_count = crypt_ftr->failed_decrypt_count; - if (i < WAIT_UNMOUNT_COUNT) { - printf("unmounting %s succeeded\n", mountpoint); - rc = 0; - } else { - //vold_killProcessesWithOpenFiles(mountpoint, 0); - printf("unmounting %s failed: %s\n", mountpoint, strerror(err)); + if (! (crypt_ftr->flags & CRYPT_MNT_KEY_UNENCRYPTED) ) { + if (decrypt_master_key(passwd, decrypted_master_key, crypt_ftr, + &intermediate_key, &intermediate_key_size)) { + printf("Failed to decrypt master key\n"); rc = -1; + goto errout; } + } - return rc; -} + // Create crypto block device - all (non fatal) code paths + // need it + if (create_crypto_blk_dev(crypt_ftr, decrypted_master_key, + real_blkdev, crypto_blkdev, label)) { + printf("Error creating decrypted block device\n"); + rc = -1; + goto errout; + } -#define DATA_PREP_TIMEOUT 200 -static int prep_data_fs(void) -{ - int i; - - /* Do the prep of the /data filesystem */ - property_set("vold.post_fs_data_done", "0"); - property_set("vold.decrypt", "trigger_post_fs_data"); - printf("Just triggered post_fs_data\n"); - - /* Wait a max of 50 seconds, hopefully it takes much less */ - for (i=0; i 0 && atoi(ro_prop)) { - struct fstab_rec* rec = fs_mgr_get_entry_for_mount_point(fstab, DATA_MNT_POINT); - rec->flags |= MS_RDONLY; - } - - /* If that succeeded, then mount the decrypted filesystem */ - int retries = RETRY_MOUNT_ATTEMPTS; - int mount_rc; - while ((mount_rc = fs_mgr_do_mount(fstab, DATA_MNT_POINT, - crypto_blkdev, 0)) - != 0) { - if (mount_rc == FS_MGR_DOMNT_BUSY) { - /* TODO: invoke something similar to - Process::killProcessWithOpenFiles(DATA_MNT_POINT, - retries > RETRY_MOUNT_ATTEMPT/2 ? 1 : 2 ) */ - printf("Failed to mount %s because it is busy - waiting", - crypto_blkdev); - if (--retries) { - sleep(RETRY_MOUNT_DELAY_SECONDS); - } else { - /* Let's hope that a reboot clears away whatever is keeping - the mount busy */ - cryptfs_reboot(reboot); - } - } else { - printf("Failed to mount decrypted data"); - cryptfs_set_corrupt(); - cryptfs_trigger_restart_min_framework(); - printf("Started framework to offer wipe"); - return -1; - } - } - - property_set("vold.decrypt", "trigger_load_persist_props"); - /* Create necessary paths on /data */ - if (prep_data_fs()) { - return -1; - } - - /* startup service classes main and late_start */ - property_set("vold.decrypt", "trigger_restart_framework"); - printf("Just triggered restart_framework\n"); - - /* Give it a few moments to get started */ - sleep(1); - } - - if (rc == 0) { - restart_successful = 1; - } - - return rc; -} - -int cryptfs_restart(void) -{ - /* Call internal implementation forcing a restart of main service group */ - return cryptfs_restart_internal(1); -} - -static int do_crypto_complete(char *mount_point UNUSED) -{ - struct crypt_mnt_ftr crypt_ftr; - char encrypted_state[PROPERTY_VALUE_MAX]; - char key_loc[PROPERTY_VALUE_MAX]; - - property_get("ro.crypto.state", encrypted_state, ""); - if (strcmp(encrypted_state, "encrypted") ) { - printf("not running with encryption, aborting"); - return CRYPTO_COMPLETE_NOT_ENCRYPTED; - } - - if (get_crypt_ftr_and_key(&crypt_ftr)) { - fs_mgr_get_crypt_info(fstab, key_loc, 0, sizeof(key_loc)); - - /* - * Only report this error if key_loc is a file and it exists. - * If the device was never encrypted, and /data is not mountable for - * some reason, returning 1 should prevent the UI from presenting the - * a "enter password" screen, or worse, a "press button to wipe the - * device" screen. - */ - if ((key_loc[0] == '/') && (access("key_loc", F_OK) == -1)) { - printf("master key file does not exist, aborting"); - return CRYPTO_COMPLETE_NOT_ENCRYPTED; - } else { - printf("Error getting crypt footer and key\n"); - return CRYPTO_COMPLETE_BAD_METADATA; - } - } - - // Test for possible error flags - if (crypt_ftr.flags & CRYPT_ENCRYPTION_IN_PROGRESS){ - printf("Encryption process is partway completed\n"); - return CRYPTO_COMPLETE_PARTIAL; - } - - if (crypt_ftr.flags & CRYPT_INCONSISTENT_STATE){ - printf("Encryption process was interrupted but cannot continue\n"); - return CRYPTO_COMPLETE_INCONSISTENT; - } - - if (crypt_ftr.flags & CRYPT_DATA_CORRUPT){ - printf("Encryption is successful but data is corrupt\n"); - return CRYPTO_COMPLETE_CORRUPT; - } - - /* We passed the test! We shall diminish, and return to the west */ - return CRYPTO_COMPLETE_ENCRYPTED; -} - -static int test_mount_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr, - char *passwd, char *mount_point, char *label) -{ - /* Allocate enough space for a 256 bit key, but we may use less */ - unsigned char decrypted_master_key[32]; - char crypto_blkdev[MAXPATHLEN]; - char real_blkdev[MAXPATHLEN]; - char tmp_mount_point[64]; - unsigned int orig_failed_decrypt_count; - int rc; - kdf_func kdf; - void *kdf_params; - int use_keymaster = 0; - int upgrade = 0; - unsigned char* intermediate_key = 0; - size_t intermediate_key_size = 0; - - printf("crypt_ftr->fs_size = %lld\n", crypt_ftr->fs_size); - orig_failed_decrypt_count = crypt_ftr->failed_decrypt_count; - - if (! (crypt_ftr->flags & CRYPT_MNT_KEY_UNENCRYPTED) ) { - if (decrypt_master_key(passwd, decrypted_master_key, crypt_ftr, - &intermediate_key, &intermediate_key_size)) { - printf("Failed to decrypt master key\n"); - rc = -1; - goto errout; - } - } - - fs_mgr_get_crypt_info(fstab, 0, real_blkdev, sizeof(real_blkdev)); - - // Create crypto block device - all (non fatal) code paths - // need it - if (create_crypto_blk_dev(crypt_ftr, decrypted_master_key, - real_blkdev, crypto_blkdev, label)) { - printf("Error creating decrypted block device\n"); - rc = -1; - goto errout; - } - - /* Work out if the problem is the password or the data */ - unsigned char scrypted_intermediate_key[sizeof(crypt_ftr-> - scrypted_intermediate_key)]; - int N = 1 << crypt_ftr->N_factor; - int r = 1 << crypt_ftr->r_factor; - int p = 1 << crypt_ftr->p_factor; + /* Work out if the problem is the password or the data */ + unsigned char scrypted_intermediate_key[sizeof(crypt_ftr-> + scrypted_intermediate_key)]; + int N = 1 << crypt_ftr->N_factor; + int r = 1 << crypt_ftr->r_factor; + int p = 1 << crypt_ftr->p_factor; rc = crypto_scrypt(intermediate_key, intermediate_key_size, crypt_ftr->salt, sizeof(crypt_ftr->salt), @@ -1795,7 +1070,7 @@ static int test_mount_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr, * the footer, not the key. */ sprintf(tmp_mount_point, "%s/tmp_mnt", mount_point); mkdir(tmp_mount_point, 0755); - if (fs_mgr_do_mount(fstab, DATA_MNT_POINT, crypto_blkdev, tmp_mount_point)) { + if (mount(crypto_blkdev, tmp_mount_point, file_system, NULL, NULL) != 0) { printf("Error temp mounting decrypted block device '%s'\n", crypto_blkdev); delete_crypto_blk_dev(label); @@ -1877,52 +1152,6 @@ int cryptfs_revert_volume(const char *label) return delete_crypto_blk_dev((char *)label); } -/* - * Called by vold when it's asked to mount an encrypted, nonremovable volume. - * Setup a dm-crypt mapping, use the saved master key from - * setting up the /data mapping, and return the new device path. - */ -int cryptfs_setup_volume(const char *label, int major, int minor, - char *crypto_sys_path, unsigned int max_path, - int *new_major, int *new_minor) -{ - char real_blkdev[MAXPATHLEN], crypto_blkdev[MAXPATHLEN]; - struct crypt_mnt_ftr sd_crypt_ftr; - struct stat statbuf; - int nr_sec, fd; - - sprintf(real_blkdev, "/dev/block/vold/%d:%d", major, minor); - - get_crypt_ftr_and_key(&sd_crypt_ftr); - - /* Update the fs_size field to be the size of the volume */ - fd = open(real_blkdev, O_RDONLY); - nr_sec = get_blkdev_size(fd); - close(fd); - if (nr_sec == 0) { - printf("Cannot get size of volume %s\n", real_blkdev); - return -1; - } - - sd_crypt_ftr.fs_size = nr_sec; - create_crypto_blk_dev(&sd_crypt_ftr, saved_master_key, real_blkdev, - crypto_blkdev, label); - - stat(crypto_blkdev, &statbuf); - *new_major = MAJOR(statbuf.st_rdev); - *new_minor = MINOR(statbuf.st_rdev); - - /* Create path to sys entry for this block device */ - snprintf(crypto_sys_path, max_path, "/devices/virtual/block/%s", strrchr(crypto_blkdev, '/')+1); - - return 0; -} - -int cryptfs_crypto_complete(void) -{ - return do_crypto_complete("/data"); -} - int check_unmounted_and_get_ftr(struct crypt_mnt_ftr* crypt_ftr) { char encrypted_state[PROPERTY_VALUE_MAX]; @@ -2034,24 +1263,11 @@ char* hexadj_passwd(const char* passwd) return hex; } -#define FSTAB_PREFIX "/fstab." - -int cryptfs_check_footer(void) +int cryptfs_check_footer() { int rc = -1; - char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)]; - char propbuf[PROPERTY_VALUE_MAX]; struct crypt_mnt_ftr crypt_ftr; - property_get("ro.hardware", propbuf, ""); - snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf); - - fstab = fs_mgr_read_fstab(fstab_filename); - if (!fstab) { - printf("failed to open %s\n", fstab_filename); - return -1; - } - rc = get_crypt_ftr_and_key(&crypt_ftr); return rc; @@ -2061,17 +1277,6 @@ int cryptfs_check_passwd(char *passwd) { struct crypt_mnt_ftr crypt_ftr; int rc; - char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)]; - char propbuf[PROPERTY_VALUE_MAX]; - - property_get("ro.hardware", propbuf, ""); - snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf); - - fstab = fs_mgr_read_fstab(fstab_filename); - if (!fstab) { - printf("failed to open %s\n", fstab_filename); - return -1; - } rc = check_unmounted_and_get_ftr(&crypt_ftr); if (rc) @@ -2223,1398 +1428,20 @@ static int cryptfs_init_crypt_mnt_ftr(struct crypt_mnt_ftr *ftr) return 0; } -static int cryptfs_enable_wipe(char *crypto_blkdev, off64_t size, int type) -{ - const char *args[10]; - char size_str[32]; /* Must be large enough to hold a %lld and null byte */ - int num_args; - int status; - int tmp; - int rc = -1; - - if (type == EXT4_FS) { - args[0] = "/system/bin/make_ext4fs"; - args[1] = "-a"; - args[2] = "/data"; - args[3] = "-l"; - snprintf(size_str, sizeof(size_str), "%" PRId64, size * 512); - args[4] = size_str; - args[5] = crypto_blkdev; - num_args = 6; - printf("Making empty filesystem with command %s %s %s %s %s %s\n", - args[0], args[1], args[2], args[3], args[4], args[5]); - } else if (type == F2FS_FS) { - args[0] = "/system/bin/mkfs.f2fs"; - args[1] = "-t"; - args[2] = "-d1"; - args[3] = crypto_blkdev; - snprintf(size_str, sizeof(size_str), "%" PRId64, size); - args[4] = size_str; - num_args = 5; - printf("Making empty filesystem with command %s %s %s %s %s\n", - args[0], args[1], args[2], args[3], args[4]); - } else { - printf("cryptfs_enable_wipe(): unknown filesystem type %d\n", type); - return -1; - } - - tmp = android_fork_execvp(num_args, (char **)args, &status, false, true); - - if (tmp != 0) { - printf("Error creating empty filesystem on %s due to logwrap error\n", crypto_blkdev); - } else { - if (WIFEXITED(status)) { - if (WEXITSTATUS(status)) { - printf("Error creating filesystem on %s, exit status %d ", - crypto_blkdev, WEXITSTATUS(status)); - } else { - printf("Successfully created filesystem on %s\n", crypto_blkdev); - rc = 0; - } - } else { - printf("Error creating filesystem on %s, did not exit normally\n", crypto_blkdev); - } - } - - return rc; -} - -#define CRYPT_INPLACE_BUFSIZE 4096 -#define CRYPT_SECTORS_PER_BUFSIZE (CRYPT_INPLACE_BUFSIZE / CRYPT_SECTOR_SIZE) -#define CRYPT_SECTOR_SIZE 512 - -/* aligned 32K writes tends to make flash happy. - * SD card association recommends it. +/* Returns type of the password, default, pattern, pin or password. */ -#define BLOCKS_AT_A_TIME 8 - -struct encryptGroupsData -{ - int realfd; - int cryptofd; - off64_t numblocks; - off64_t one_pct, cur_pct, new_pct; - off64_t blocks_already_done, tot_numblocks; - off64_t used_blocks_already_done, tot_used_blocks; - char* real_blkdev, * crypto_blkdev; - int count; - off64_t offset; - char* buffer; - off64_t last_written_sector; - int completed; - time_t time_started; - int remaining_time; -}; - -static void update_progress(struct encryptGroupsData* data, int is_used) -{ - data->blocks_already_done++; - - if (is_used) { - data->used_blocks_already_done++; - } - if (data->tot_used_blocks) { - data->new_pct = data->used_blocks_already_done / data->one_pct; - } else { - data->new_pct = data->blocks_already_done / data->one_pct; - } - - if (data->new_pct > data->cur_pct) { - char buf[8]; - data->cur_pct = data->new_pct; - snprintf(buf, sizeof(buf), "%" PRId64, data->cur_pct); - property_set("vold.encrypt_progress", buf); - } - - if (data->cur_pct >= 5) { - struct timespec time_now; - if (clock_gettime(CLOCK_MONOTONIC, &time_now)) { - printf("Error getting time"); - } else { - double elapsed_time = difftime(time_now.tv_sec, data->time_started); - off64_t remaining_blocks = data->tot_used_blocks - - data->used_blocks_already_done; - int remaining_time = (int)(elapsed_time * remaining_blocks - / data->used_blocks_already_done); - - // Change time only if not yet set, lower, or a lot higher for - // best user experience - if (data->remaining_time == -1 - || remaining_time < data->remaining_time - || remaining_time > data->remaining_time + 60) { - char buf[8]; - snprintf(buf, sizeof(buf), "%d", remaining_time); - property_set("vold.encrypt_time_remaining", buf); - data->remaining_time = remaining_time; - } - } - } -} - -static void log_progress(struct encryptGroupsData const* data, bool completed) -{ - // Precondition - if completed data = 0 else data != 0 - - // Track progress so we can skip logging blocks - static off64_t offset = -1; - - // Need to close existing 'Encrypting from' log? - if (completed || (offset != -1 && data->offset != offset)) { - printf("Encrypted to sector %" PRId64, - offset / info.block_size * CRYPT_SECTOR_SIZE); - offset = -1; - } - - // Need to start new 'Encrypting from' log? - if (!completed && offset != data->offset) { - printf("Encrypting from sector %" PRId64, - data->offset / info.block_size * CRYPT_SECTOR_SIZE); - } - - // Update offset - if (!completed) { - offset = data->offset + (off64_t)data->count * info.block_size; - } -} - -static int flush_outstanding_data(struct encryptGroupsData* data) +int cryptfs_get_password_type(void) { - if (data->count == 0) { - return 0; - } - - printf("Copying %d blocks at offset %" PRIx64, data->count, data->offset); - - if (pread64(data->realfd, data->buffer, - info.block_size * data->count, data->offset) - <= 0) { - printf("Error reading real_blkdev %s for inplace encrypt", - data->real_blkdev); - return -1; - } + struct crypt_mnt_ftr crypt_ftr; - if (pwrite64(data->cryptofd, data->buffer, - info.block_size * data->count, data->offset) - <= 0) { - printf("Error writing crypto_blkdev %s for inplace encrypt", - data->crypto_blkdev); + if (get_crypt_ftr_and_key(&crypt_ftr)) { + printf("Error getting crypt footer and key\n"); return -1; - } else { - log_progress(data, false); - } - - data->count = 0; - data->last_written_sector = (data->offset + data->count) - / info.block_size * CRYPT_SECTOR_SIZE - 1; - return 0; -} - -static int encrypt_groups(struct encryptGroupsData* data) -{ - unsigned int i; - u8 *block_bitmap = 0; - unsigned int block; - off64_t ret; - int rc = -1; - - data->buffer = malloc(info.block_size * BLOCKS_AT_A_TIME); - if (!data->buffer) { - printf("Failed to allocate crypto buffer"); - goto errout; - } - - block_bitmap = malloc(info.block_size); - if (!block_bitmap) { - printf("failed to allocate block bitmap"); - goto errout; - } - - for (i = 0; i < aux_info.groups; ++i) { - printf("Encrypting group %d", i); - - u32 first_block = aux_info.first_data_block + i * info.blocks_per_group; - u32 block_count = min(info.blocks_per_group, - aux_info.len_blocks - first_block); - - off64_t offset = (u64)info.block_size - * aux_info.bg_desc[i].bg_block_bitmap; - - ret = pread64(data->realfd, block_bitmap, info.block_size, offset); - if (ret != (int)info.block_size) { - printf("failed to read all of block group bitmap %d", i); - goto errout; - } - - offset = (u64)info.block_size * first_block; - - data->count = 0; - - for (block = 0; block < block_count; block++) { - int used = bitmap_get_bit(block_bitmap, block); - update_progress(data, used); - if (used) { - if (data->count == 0) { - data->offset = offset; - } - data->count++; - } else { - if (flush_outstanding_data(data)) { - goto errout; - } - } - - offset += info.block_size; - - /* Write data if we are aligned or buffer size reached */ - if (offset % (info.block_size * BLOCKS_AT_A_TIME) == 0 - || data->count == BLOCKS_AT_A_TIME) { - if (flush_outstanding_data(data)) { - goto errout; - } - } - - if (1) { - printf("Stopping encryption due to low battery"); - rc = 0; - goto errout; - } - - } - if (flush_outstanding_data(data)) { - goto errout; - } } - data->completed = 1; - rc = 0; - -errout: - log_progress(0, true); - free(data->buffer); - free(block_bitmap); - return rc; -} - -static int cryptfs_enable_inplace_ext4(char *crypto_blkdev, - char *real_blkdev, - off64_t size, - off64_t *size_already_done, - off64_t tot_size, - off64_t previously_encrypted_upto) -{ - u32 i; - struct encryptGroupsData data; - int rc; // Can't initialize without causing warning -Wclobbered - - if (previously_encrypted_upto > *size_already_done) { - printf("Not fast encrypting since resuming part way through"); - return -1; - } - - memset(&data, 0, sizeof(data)); - data.real_blkdev = real_blkdev; - data.crypto_blkdev = crypto_blkdev; - - if ( (data.realfd = open(real_blkdev, O_RDWR)) < 0) { - printf("Error opening real_blkdev %s for inplace encrypt. err=%d(%s)\n", - real_blkdev, errno, strerror(errno)); - rc = -1; - goto errout; - } - - if ( (data.cryptofd = open(crypto_blkdev, O_WRONLY)) < 0) { - printf("Error opening crypto_blkdev %s for ext4 inplace encrypt. err=%d(%s)\n", - crypto_blkdev, errno, strerror(errno)); - rc = ENABLE_INPLACE_ERR_DEV; - goto errout; - } - - if (setjmp(setjmp_env)) { - printf("Reading ext4 extent caused an exception\n"); - rc = -1; - goto errout; - } - - if (read_ext(data.realfd, 0) != 0) { - printf("Failed to read ext4 extent\n"); - rc = -1; - goto errout; - } - - data.numblocks = size / CRYPT_SECTORS_PER_BUFSIZE; - data.tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE; - data.blocks_already_done = *size_already_done / CRYPT_SECTORS_PER_BUFSIZE; - - printf("Encrypting ext4 filesystem in place..."); - - data.tot_used_blocks = data.numblocks; - for (i = 0; i < aux_info.groups; ++i) { - data.tot_used_blocks -= aux_info.bg_desc[i].bg_free_blocks_count; - } - - data.one_pct = data.tot_used_blocks / 100; - data.cur_pct = 0; - - struct timespec time_started = {0}; - if (clock_gettime(CLOCK_MONOTONIC, &time_started)) { - printf("Error getting time at start"); - // Note - continue anyway - we'll run with 0 - } - data.time_started = time_started.tv_sec; - data.remaining_time = -1; - - rc = encrypt_groups(&data); - if (rc) { - printf("Error encrypting groups"); - goto errout; - } - - *size_already_done += data.completed ? size : data.last_written_sector; - rc = 0; - -errout: - close(data.realfd); - close(data.cryptofd); - - return rc; -} - -static void log_progress_f2fs(u64 block, bool completed) -{ - // Precondition - if completed data = 0 else data != 0 - - // Track progress so we can skip logging blocks - static u64 last_block = (u64)-1; - - // Need to close existing 'Encrypting from' log? - if (completed || (last_block != (u64)-1 && block != last_block + 1)) { - printf("Encrypted to block %" PRId64, last_block); - last_block = -1; - } - - // Need to start new 'Encrypting from' log? - if (!completed && (last_block == (u64)-1 || block != last_block + 1)) { - printf("Encrypting from block %" PRId64, block); - } - - // Update offset - if (!completed) { - last_block = block; - } -} - -static int encrypt_one_block_f2fs(u64 pos, void *data) -{ - struct encryptGroupsData *priv_dat = (struct encryptGroupsData *)data; - - priv_dat->blocks_already_done = pos - 1; - update_progress(priv_dat, 1); - - off64_t offset = pos * CRYPT_INPLACE_BUFSIZE; - - if (pread64(priv_dat->realfd, priv_dat->buffer, CRYPT_INPLACE_BUFSIZE, offset) <= 0) { - printf("Error reading real_blkdev %s for f2fs inplace encrypt", priv_dat->crypto_blkdev); - return -1; - } - - if (pwrite64(priv_dat->cryptofd, priv_dat->buffer, CRYPT_INPLACE_BUFSIZE, offset) <= 0) { - printf("Error writing crypto_blkdev %s for f2fs inplace encrypt", priv_dat->crypto_blkdev); - return -1; - } else { - log_progress_f2fs(pos, false); - } - - return 0; -} - -static int cryptfs_enable_inplace_f2fs(char *crypto_blkdev, - char *real_blkdev, - off64_t size, - off64_t *size_already_done, - off64_t tot_size, - off64_t previously_encrypted_upto) -{ - u32 i; - struct encryptGroupsData data; - struct f2fs_info *f2fs_info = NULL; - int rc = ENABLE_INPLACE_ERR_OTHER; - if (previously_encrypted_upto > *size_already_done) { - printf("Not fast encrypting since resuming part way through"); - return ENABLE_INPLACE_ERR_OTHER; - } - memset(&data, 0, sizeof(data)); - data.real_blkdev = real_blkdev; - data.crypto_blkdev = crypto_blkdev; - data.realfd = -1; - data.cryptofd = -1; - if ( (data.realfd = open64(real_blkdev, O_RDWR)) < 0) { - printf("Error opening real_blkdev %s for f2fs inplace encrypt\n", - real_blkdev); - goto errout; - } - if ( (data.cryptofd = open64(crypto_blkdev, O_WRONLY)) < 0) { - printf("Error opening crypto_blkdev %s for f2fs inplace encrypt. err=%d(%s)\n", - crypto_blkdev, errno, strerror(errno)); - rc = ENABLE_INPLACE_ERR_DEV; - goto errout; - } - - f2fs_info = generate_f2fs_info(data.realfd); - if (!f2fs_info) - goto errout; - - data.numblocks = size / CRYPT_SECTORS_PER_BUFSIZE; - data.tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE; - data.blocks_already_done = *size_already_done / CRYPT_SECTORS_PER_BUFSIZE; - - data.tot_used_blocks = get_num_blocks_used(f2fs_info); - - data.one_pct = data.tot_used_blocks / 100; - data.cur_pct = 0; - data.time_started = time(NULL); - data.remaining_time = -1; - - data.buffer = malloc(f2fs_info->block_size); - if (!data.buffer) { - printf("Failed to allocate crypto buffer"); - goto errout; - } - - data.count = 0; - - /* Currently, this either runs to completion, or hits a nonrecoverable error */ - rc = run_on_used_blocks(data.blocks_already_done, f2fs_info, &encrypt_one_block_f2fs, &data); - - if (rc) { - printf("Error in running over f2fs blocks"); - rc = ENABLE_INPLACE_ERR_OTHER; - goto errout; - } - - *size_already_done += size; - rc = 0; - -errout: - if (rc) - printf("Failed to encrypt f2fs filesystem on %s", real_blkdev); - - log_progress_f2fs(0, true); - free(f2fs_info); - free(data.buffer); - close(data.realfd); - close(data.cryptofd); - - return rc; -} - -static int cryptfs_enable_inplace_full(char *crypto_blkdev, char *real_blkdev, - off64_t size, off64_t *size_already_done, - off64_t tot_size, - off64_t previously_encrypted_upto) -{ - int realfd, cryptofd; - char *buf[CRYPT_INPLACE_BUFSIZE]; - int rc = ENABLE_INPLACE_ERR_OTHER; - off64_t numblocks, i, remainder; - off64_t one_pct, cur_pct, new_pct; - off64_t blocks_already_done, tot_numblocks; - - if ( (realfd = open(real_blkdev, O_RDONLY)) < 0) { - printf("Error opening real_blkdev %s for inplace encrypt\n", real_blkdev); - return ENABLE_INPLACE_ERR_OTHER; - } - - if ( (cryptofd = open(crypto_blkdev, O_WRONLY)) < 0) { - printf("Error opening crypto_blkdev %s for inplace encrypt. err=%d(%s)\n", - crypto_blkdev, errno, strerror(errno)); - close(realfd); - return ENABLE_INPLACE_ERR_DEV; - } - - /* This is pretty much a simple loop of reading 4K, and writing 4K. - * The size passed in is the number of 512 byte sectors in the filesystem. - * So compute the number of whole 4K blocks we should read/write, - * and the remainder. - */ - numblocks = size / CRYPT_SECTORS_PER_BUFSIZE; - remainder = size % CRYPT_SECTORS_PER_BUFSIZE; - tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE; - blocks_already_done = *size_already_done / CRYPT_SECTORS_PER_BUFSIZE; - - printf("Encrypting filesystem in place..."); - - i = previously_encrypted_upto + 1 - *size_already_done; - - if (lseek64(realfd, i * CRYPT_SECTOR_SIZE, SEEK_SET) < 0) { - printf("Cannot seek to previously encrypted point on %s", real_blkdev); - goto errout; - } - - if (lseek64(cryptofd, i * CRYPT_SECTOR_SIZE, SEEK_SET) < 0) { - printf("Cannot seek to previously encrypted point on %s", crypto_blkdev); - goto errout; - } - - for (;i < size && i % CRYPT_SECTORS_PER_BUFSIZE != 0; ++i) { - if (unix_read(realfd, buf, CRYPT_SECTOR_SIZE) <= 0) { - printf("Error reading initial sectors from real_blkdev %s for " - "inplace encrypt\n", crypto_blkdev); - goto errout; - } - if (unix_write(cryptofd, buf, CRYPT_SECTOR_SIZE) <= 0) { - printf("Error writing initial sectors to crypto_blkdev %s for " - "inplace encrypt\n", crypto_blkdev); - goto errout; - } else { - printf("Encrypted 1 block at %" PRId64, i); - } - } - - one_pct = tot_numblocks / 100; - cur_pct = 0; - /* process the majority of the filesystem in blocks */ - for (i/=CRYPT_SECTORS_PER_BUFSIZE; i cur_pct) { - char buf[8]; - - cur_pct = new_pct; - snprintf(buf, sizeof(buf), "%" PRId64, cur_pct); - property_set("vold.encrypt_progress", buf); - } - if (unix_read(realfd, buf, CRYPT_INPLACE_BUFSIZE) <= 0) { - printf("Error reading real_blkdev %s for inplace encrypt", crypto_blkdev); - goto errout; - } - if (unix_write(cryptofd, buf, CRYPT_INPLACE_BUFSIZE) <= 0) { - printf("Error writing crypto_blkdev %s for inplace encrypt", crypto_blkdev); - goto errout; - } else { - printf("Encrypted %d block at %" PRId64, - CRYPT_SECTORS_PER_BUFSIZE, - i * CRYPT_SECTORS_PER_BUFSIZE); - } - - if (1) { - printf("Stopping encryption due to low battery"); - *size_already_done += (i + 1) * CRYPT_SECTORS_PER_BUFSIZE - 1; - rc = 0; - goto errout; - } - } - - /* Do any remaining sectors */ - for (i=0; iflags & (VOL_ENCRYPTABLE | VOL_NONREMOVABLE)) == - (VOL_ENCRYPTABLE | VOL_NONREMOVABLE); -} - -static int cryptfs_SHA256_fileblock(const char* filename, __le8* buf) -{ - int fd = open(filename, O_RDONLY); - if (fd == -1) { - printf("Error opening file %s", filename); - return -1; - } - - char block[CRYPT_INPLACE_BUFSIZE]; - memset(block, 0, sizeof(block)); - if (unix_read(fd, block, sizeof(block)) < 0) { - printf("Error reading file %s", filename); - close(fd); - return -1; - } - - close(fd); - - SHA256_CTX c; - SHA256_Init(&c); - SHA256_Update(&c, block, sizeof(block)); - SHA256_Final(buf, &c); - - return 0; -} - -static int get_fs_type(struct fstab_rec *rec) -{ - if (!strcmp(rec->fs_type, "ext4")) { - return EXT4_FS; - } else if (!strcmp(rec->fs_type, "f2fs")) { - return F2FS_FS; - } else { - return -1; - } -} - -static int cryptfs_enable_all_volumes(struct crypt_mnt_ftr *crypt_ftr, int how, - char *crypto_blkdev, char *real_blkdev, - int previously_encrypted_upto) -{ - off64_t cur_encryption_done=0, tot_encryption_size=0; - int i, rc = -1; - - if (1) { - printf("Not starting encryption due to low battery"); - return 0; - } - - /* The size of the userdata partition, and add in the vold volumes below */ - tot_encryption_size = crypt_ftr->fs_size; - - if (how == CRYPTO_ENABLE_WIPE) { - struct fstab_rec* rec = fs_mgr_get_entry_for_mount_point(fstab, DATA_MNT_POINT); - int fs_type = get_fs_type(rec); - if (fs_type < 0) { - printf("cryptfs_enable: unsupported fs type %s\n", rec->fs_type); - return -1; - } - rc = cryptfs_enable_wipe(crypto_blkdev, crypt_ftr->fs_size, fs_type); - } else if (how == CRYPTO_ENABLE_INPLACE) { - rc = cryptfs_enable_inplace(crypto_blkdev, real_blkdev, - crypt_ftr->fs_size, &cur_encryption_done, - tot_encryption_size, - previously_encrypted_upto); - - if (rc == ENABLE_INPLACE_ERR_DEV) { - /* Hack for b/17898962 */ - printf("cryptfs_enable: crypto block dev failure. Must reboot...\n"); - cryptfs_reboot(reboot); - } - - if (!rc) { - crypt_ftr->encrypted_upto = cur_encryption_done; - } - - if (!rc && crypt_ftr->encrypted_upto == crypt_ftr->fs_size) { - /* The inplace routine never actually sets the progress to 100% due - * to the round down nature of integer division, so set it here */ - property_set("vold.encrypt_progress", "100"); - } - } else { - /* Shouldn't happen */ - printf("cryptfs_enable: internal error, unknown option\n"); - rc = -1; - } - - return rc; -} - -int cryptfs_enable_internal(char *howarg, int crypt_type, char *passwd, - int allow_reboot) -{ - int how = 0; - char crypto_blkdev[MAXPATHLEN], real_blkdev[MAXPATHLEN]; - unsigned long nr_sec; - unsigned char decrypted_master_key[KEY_LEN_BYTES]; - int rc=-1, fd, i, ret; - struct crypt_mnt_ftr crypt_ftr; - struct crypt_persist_data *pdata; - char encrypted_state[PROPERTY_VALUE_MAX]; - char lockid[32] = { 0 }; - char key_loc[PROPERTY_VALUE_MAX]; - char fuse_sdcard[PROPERTY_VALUE_MAX]; - char *sd_mnt_point; - int num_vols; - struct volume_info *vol_list = 0; - off64_t previously_encrypted_upto = 0; -printf("cryptfs_enable_internal disabled by TWRP\n"); -return -1; - if (!strcmp(howarg, "wipe")) { - how = CRYPTO_ENABLE_WIPE; - } else if (! strcmp(howarg, "inplace")) { - how = CRYPTO_ENABLE_INPLACE; - } else { - /* Shouldn't happen, as CommandListener vets the args */ - goto error_unencrypted; - } - - /* See if an encryption was underway and interrupted */ - if (how == CRYPTO_ENABLE_INPLACE - && get_crypt_ftr_and_key(&crypt_ftr) == 0 - && (crypt_ftr.flags & CRYPT_ENCRYPTION_IN_PROGRESS)) { - previously_encrypted_upto = crypt_ftr.encrypted_upto; - crypt_ftr.encrypted_upto = 0; - crypt_ftr.flags &= ~CRYPT_ENCRYPTION_IN_PROGRESS; - - /* At this point, we are in an inconsistent state. Until we successfully - complete encryption, a reboot will leave us broken. So mark the - encryption failed in case that happens. - On successfully completing encryption, remove this flag */ - crypt_ftr.flags |= CRYPT_INCONSISTENT_STATE; - - put_crypt_ftr_and_key(&crypt_ftr); - } - - property_get("ro.crypto.state", encrypted_state, ""); - if (!strcmp(encrypted_state, "encrypted") && !previously_encrypted_upto) { - printf("Device is already running encrypted, aborting"); - goto error_unencrypted; - } - - // TODO refactor fs_mgr_get_crypt_info to get both in one call - fs_mgr_get_crypt_info(fstab, key_loc, 0, sizeof(key_loc)); - fs_mgr_get_crypt_info(fstab, 0, real_blkdev, sizeof(real_blkdev)); - - /* Get the size of the real block device */ - fd = open(real_blkdev, O_RDONLY); - if ( (nr_sec = get_blkdev_size(fd)) == 0) { - printf("Cannot get size of block device %s\n", real_blkdev); - goto error_unencrypted; - } - close(fd); - - /* If doing inplace encryption, make sure the orig fs doesn't include the crypto footer */ - if ((how == CRYPTO_ENABLE_INPLACE) && (!strcmp(key_loc, KEY_IN_FOOTER))) { - unsigned int fs_size_sec, max_fs_size_sec; - fs_size_sec = get_fs_size(real_blkdev); - if (fs_size_sec == 0) - fs_size_sec = get_f2fs_filesystem_size_sec(real_blkdev); - - max_fs_size_sec = nr_sec - (CRYPT_FOOTER_OFFSET / CRYPT_SECTOR_SIZE); - - if (fs_size_sec > max_fs_size_sec) { - printf("Orig filesystem overlaps crypto footer region. Cannot encrypt in place."); - goto error_unencrypted; - } - } - - /* Get a wakelock as this may take a while, and we don't want the - * device to sleep on us. We'll grab a partial wakelock, and if the UI - * wants to keep the screen on, it can grab a full wakelock. - */ - snprintf(lockid, sizeof(lockid), "enablecrypto%d", (int) getpid()); - acquire_wake_lock(PARTIAL_WAKE_LOCK, lockid); - - /* Get the sdcard mount point */ - sd_mnt_point = getenv("EMULATED_STORAGE_SOURCE"); - if (!sd_mnt_point) { - sd_mnt_point = getenv("EXTERNAL_STORAGE"); - } - if (!sd_mnt_point) { - sd_mnt_point = "/mnt/sdcard"; - } - - /* TODO - * Currently do not have test devices with multiple encryptable volumes. - * When we acquire some, re-add support. - */ - num_vols=0/*vold_getNumDirectVolumes()*/; - vol_list = malloc(sizeof(struct volume_info) * num_vols); - //vold_getDirectVolumeList(vol_list); - - for (i=0; i= 0) { - write(fd, "--wipe_data\n", strlen("--wipe_data\n") + 1); - write(fd, "--reason=cryptfs_enable_internal\n", strlen("--reason=cryptfs_enable_internal\n") + 1); - close(fd); - } else { - printf("could not open /cache/recovery/command\n"); - } - cryptfs_reboot(recovery); - } else { - /* set property to trigger dialog */ - property_set("vold.encrypt_progress", "error_partially_encrypted"); - release_wake_lock(lockid); - } - return -1; - } - - /* hrm, the encrypt step claims success, but the reboot failed. - * This should not happen. - * Set the property and return. Hope the framework can deal with it. - */ - property_set("vold.encrypt_progress", "error_reboot_failed"); - release_wake_lock(lockid); - return rc; - -error_unencrypted: - free(vol_list); - property_set("vold.encrypt_progress", "error_not_encrypted"); - if (lockid[0]) { - release_wake_lock(lockid); - } - return -1; - -error_shutting_down: - /* we failed, and have not encrypted anthing, so the users's data is still intact, - * but the framework is stopped and not restarted to show the error, so it's up to - * vold to restart the system. - */ - printf("Error enabling encryption after framework is shutdown, no data changed, restarting system"); - cryptfs_reboot(reboot); - - /* shouldn't get here */ - property_set("vold.encrypt_progress", "error_shutting_down"); - free(vol_list); - if (lockid[0]) { - release_wake_lock(lockid); - } - return -1; -} - -int cryptfs_enable(char *howarg, int type, char *passwd, int allow_reboot) -{ - char* adjusted_passwd = adjust_passwd(passwd); - if (adjusted_passwd) { - passwd = adjusted_passwd; - } - - int rc = cryptfs_enable_internal(howarg, type, passwd, allow_reboot); - - free(adjusted_passwd); - return rc; -} - -int cryptfs_enable_default(char *howarg, int allow_reboot) -{ - return cryptfs_enable_internal(howarg, CRYPT_TYPE_DEFAULT, - DEFAULT_PASSWORD, allow_reboot); -} - -int cryptfs_changepw(int crypt_type, const char *newpw) -{ - struct crypt_mnt_ftr crypt_ftr; - unsigned char decrypted_master_key[KEY_LEN_BYTES]; - - /* This is only allowed after we've successfully decrypted the master key */ - if (!master_key_saved) { - printf("Key not saved, aborting"); - return -1; - } - - if (crypt_type < 0 || crypt_type > CRYPT_TYPE_MAX_TYPE) { - printf("Invalid crypt_type %d", crypt_type); - return -1; - } - - /* get key */ - if (get_crypt_ftr_and_key(&crypt_ftr)) { - printf("Error getting crypt footer and key"); - return -1; - } - - crypt_ftr.crypt_type = crypt_type; - - char* adjusted_passwd = adjust_passwd(newpw); - if (adjusted_passwd) { - newpw = adjusted_passwd; - } - - encrypt_master_key(crypt_type == CRYPT_TYPE_DEFAULT ? DEFAULT_PASSWORD - : newpw, - crypt_ftr.salt, - saved_master_key, - crypt_ftr.master_key, - &crypt_ftr); - - /* save the key */ - put_crypt_ftr_and_key(&crypt_ftr); - - free(adjusted_passwd); - return 0; -} - -static int persist_get_key(char *fieldname, char *value) -{ - unsigned int i; - - if (persist_data == NULL) { - return -1; - } - for (i = 0; i < persist_data->persist_valid_entries; i++) { - if (!strncmp(persist_data->persist_entry[i].key, fieldname, PROPERTY_KEY_MAX)) { - /* We found it! */ - strlcpy(value, persist_data->persist_entry[i].val, PROPERTY_VALUE_MAX); - return 0; - } - } - - return -1; -} - -static int persist_set_key(char *fieldname, char *value, int encrypted) -{ - unsigned int i; - unsigned int num; - struct crypt_mnt_ftr crypt_ftr; - unsigned int max_persistent_entries; - unsigned int dsize; - - if (persist_data == NULL) { - return -1; - } - - /* If encrypted, use the values from the crypt_ftr, otherwise - * use the values for the current spec. - */ - if (encrypted) { - if(get_crypt_ftr_and_key(&crypt_ftr)) { - return -1; - } - dsize = crypt_ftr.persist_data_size; - } else { - dsize = CRYPT_PERSIST_DATA_SIZE; - } - max_persistent_entries = (dsize - sizeof(struct crypt_persist_data)) / - sizeof(struct crypt_persist_entry); - - num = persist_data->persist_valid_entries; - - for (i = 0; i < num; i++) { - if (!strncmp(persist_data->persist_entry[i].key, fieldname, PROPERTY_KEY_MAX)) { - /* We found an existing entry, update it! */ - memset(persist_data->persist_entry[i].val, 0, PROPERTY_VALUE_MAX); - strlcpy(persist_data->persist_entry[i].val, value, PROPERTY_VALUE_MAX); - return 0; - } - } - - /* We didn't find it, add it to the end, if there is room */ - if (persist_data->persist_valid_entries < max_persistent_entries) { - memset(&persist_data->persist_entry[num], 0, sizeof(struct crypt_persist_entry)); - strlcpy(persist_data->persist_entry[num].key, fieldname, PROPERTY_KEY_MAX); - strlcpy(persist_data->persist_entry[num].val, value, PROPERTY_VALUE_MAX); - persist_data->persist_valid_entries++; - return 0; - } - - return -1; -} - -/* Return the value of the specified field. */ -int cryptfs_getfield(char *fieldname, char *value, int len) -{ - char temp_value[PROPERTY_VALUE_MAX]; - char real_blkdev[MAXPATHLEN]; - /* 0 is success, 1 is not encrypted, - * -1 is value not set, -2 is any other error - */ - int rc = -2; - - if (persist_data == NULL) { - load_persistent_data(); - if (persist_data == NULL) { - printf("Getfield error, cannot load persistent data"); - goto out; - } - } - - if (!persist_get_key(fieldname, temp_value)) { - /* We found it, copy it to the caller's buffer and return */ - strlcpy(value, temp_value, len); - rc = 0; - } else { - /* Sadness, it's not there. Return the error */ - rc = -1; - } - -out: - return rc; -} - -/* Set the value of the specified field. */ -int cryptfs_setfield(char *fieldname, char *value) -{ - struct crypt_persist_data stored_pdata; - struct crypt_persist_data *pdata_p; - struct crypt_mnt_ftr crypt_ftr; - char encrypted_state[PROPERTY_VALUE_MAX]; - /* 0 is success, -1 is an error */ - int rc = -1; - int encrypted = 0; - - if (persist_data == NULL) { - load_persistent_data(); - if (persist_data == NULL) { - printf("Setfield error, cannot load persistent data"); - goto out; - } - } - - property_get("ro.crypto.state", encrypted_state, ""); - if (!strcmp(encrypted_state, "encrypted") ) { - encrypted = 1; - } - - if (persist_set_key(fieldname, value, encrypted)) { - goto out; - } - - /* If we are running encrypted, save the persistent data now */ - if (encrypted) { - if (save_persistent_data()) { - printf("Setfield error, cannot save persistent data"); - goto out; - } - } - - rc = 0; - -out: - return rc; -} - -/* Checks userdata. Attempt to mount the volume if default- - * encrypted. - * On success trigger next init phase and return 0. - * Currently do not handle failure - see TODO below. - */ -int cryptfs_mount_default_encrypted(void) -{ - char decrypt_state[PROPERTY_VALUE_MAX]; - property_get("vold.decrypt", decrypt_state, "0"); - if (!strcmp(decrypt_state, "0")) { - printf("Not encrypted - should not call here"); - } else { - int crypt_type = cryptfs_get_password_type(); - if (crypt_type < 0 || crypt_type > CRYPT_TYPE_MAX_TYPE) { - printf("Bad crypt type - error"); - } else if (crypt_type != CRYPT_TYPE_DEFAULT) { - printf("Password is not default - " - "starting min framework to prompt"); - property_set("vold.decrypt", "trigger_restart_min_framework"); - return 0; - } else if (cryptfs_check_passwd(DEFAULT_PASSWORD) == 0) { - printf("Password is default - restarting filesystem"); - cryptfs_restart_internal(0); - return 0; - } else { - printf("Encrypted, default crypt type but can't decrypt"); - } - } - - /** Corrupt. Allow us to boot into framework, which will detect bad - crypto when it calls do_crypto_complete, then do a factory reset - */ - property_set("vold.decrypt", "trigger_restart_min_framework"); - return 0; -} - -/* Returns type of the password, default, pattern, pin or password. - */ -int cryptfs_get_password_type(void) -{ - struct crypt_mnt_ftr crypt_ftr; - char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)]; - char propbuf[PROPERTY_VALUE_MAX]; - - property_get("ro.hardware", propbuf, ""); - snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf); - - fstab = fs_mgr_read_fstab(fstab_filename); - if (!fstab) { - printf("failed to open %s\n", fstab_filename); - return -1; - } - - if (get_crypt_ftr_and_key(&crypt_ftr)) { - printf("Error getting crypt footer and key\n"); - return -1; - } - - if (crypt_ftr.flags & CRYPT_INCONSISTENT_STATE) { + if (crypt_ftr.flags & CRYPT_INCONSISTENT_STATE) { return -1; } return crypt_ftr.crypt_type; } - -char* cryptfs_get_password() -{ - struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - if (now.tv_sec < password_expiry_time) { - return password; - } else { - cryptfs_clear_password(); - return 0; - } -} - -void cryptfs_clear_password() -{ - if (password) { - size_t len = strlen(password); - memset(password, 0, len); - free(password); - password = 0; - password_expiry_time = 0; - } -} diff --git a/crypto/lollipop/cryptfs.h b/crypto/lollipop/cryptfs.h index b95a290cf..8cb8a7a32 100644 --- a/crypto/lollipop/cryptfs.h +++ b/crypto/lollipop/cryptfs.h @@ -208,24 +208,11 @@ extern "C" { typedef int (*kdf_func)(const char *passwd, const unsigned char *salt, unsigned char *ikey, void *params); - int cryptfs_crypto_complete(void); - int cryptfs_check_footer(void); + void set_partition_data(const char* block_device, const char* key_location, const char* fs); + int cryptfs_check_footer(); int cryptfs_check_passwd(char *pw); int cryptfs_verify_passwd(char *newpw); - int cryptfs_restart(void); - int cryptfs_enable(char *flag, int type, char *passwd, int allow_reboot); - int cryptfs_changepw(int type, const char *newpw); - int cryptfs_enable_default(char *flag, int allow_reboot); - int cryptfs_setup_volume(const char *label, int major, int minor, - char *crypto_dev_path, unsigned int max_pathlen, - int *new_major, int *new_minor); - int cryptfs_revert_volume(const char *label); - int cryptfs_getfield(char *fieldname, char *value, int len); - int cryptfs_setfield(char *fieldname, char *value); - int cryptfs_mount_default_encrypted(void); int cryptfs_get_password_type(void); - char* cryptfs_get_password(void); - void cryptfs_clear_password(void); #ifdef __cplusplus } #endif diff --git a/crypto/scrypt/Android.mk b/crypto/scrypt/Android.mk index a427de655..4514f9467 100644 --- a/crypto/scrypt/Android.mk +++ b/crypto/scrypt/Android.mk @@ -1,5 +1,4 @@ LOCAL_PATH := $(call my-dir) -#include $(call all-named-subdir-makefiles,tests) # Enable to be able to use ALOG* with #include "cutils/log.h" #log_c_includes += system/core/include @@ -10,3 +9,5 @@ LOCAL_PATH := $(call my-dir) # that import_openssl.sh import won't remove them. include $(LOCAL_PATH)/build-config.mk include $(LOCAL_PATH)/Scrypt.mk + +include $(LOCAL_PATH)/tests/Android.mk diff --git a/crypto/scrypt/Scrypt-config.mk b/crypto/scrypt/Scrypt-config.mk index c0b00d873..bbe10631e 100644 --- a/crypto/scrypt/Scrypt-config.mk +++ b/crypto/scrypt/Scrypt-config.mk @@ -77,7 +77,7 @@ target_arch := unknown_arch endif target_c_flags := $(common_c_flags) $($(target_arch)_c_flags) $(local_c_flags) -target_c_includes := $(addprefix $(commands_recovery_local_path)/crypto/scrypt/,$(common_c_includes)) $(local_c_includes) +target_c_includes := $(addprefix external/scrypt/,$(common_c_includes)) $(local_c_includes) target_src_files := $(common_src_files) $($(target_arch)_src_files) target_src_files := $(filter-out $($(target_arch)_exclude_files), $(target_src_files)) @@ -97,7 +97,7 @@ host_arch := unknown_arch endif host_c_flags := $(common_c_flags) $($(host_arch)_c_flags) $(local_c_flags) -host_c_includes := $(addprefix $(commands_recovery_local_path)/crypto/scrypt/,$(common_c_includes)) $(local_c_includes) +host_c_includes := $(addprefix external/scrypt/,$(common_c_includes)) $(local_c_includes) host_src_files := $(common_src_files) $($(host_arch)_src_files) host_src_files := $(filter-out $($(host_arch)_exclude_files), $(host_src_files)) diff --git a/crypto/scrypt/tests/Android.mk b/crypto/scrypt/tests/Android.mk index 60257e0f9..07c21023d 100644 --- a/crypto/scrypt/tests/Android.mk +++ b/crypto/scrypt/tests/Android.mk @@ -3,6 +3,8 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) +LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk + LOCAL_SRC_FILES:= \ scrypt_test.cpp @@ -18,6 +20,6 @@ LOCAL_STATIC_LIBRARIES := \ libgtest \ libgtest_main -LOCAL_MODULE := scrypt_test_twrp +LOCAL_MODULE := scrypttwrp_test include $(BUILD_NATIVE_TEST) diff --git a/crypto/scrypt/tests/scrypt_test.cpp b/crypto/scrypt/tests/scrypt_test.cpp index 28334d6f5..ffb568df9 100644 --- a/crypto/scrypt/tests/scrypt_test.cpp +++ b/crypto/scrypt/tests/scrypt_test.cpp @@ -15,8 +15,8 @@ */ #define LOG_TAG "scrypt_test" +#include #include -#include #include -- cgit v1.2.3