Commit c798c9cd authored by Ethan Yonker's avatar Ethan Yonker
Browse files

Merge up to AOSP marshmallow-release

In order to maintain compatibility with older trees, we now have
minadbd.old and minui.old. I had to use a TARGET_GLOBAL_CFLAG to
handle ifdef issues in minui/minui.d because healthd includes
minui/minui.h and there was no other alternative to make minui.h
compatible with older trees without having to modify healthd rules
which is outside of TWRP.

Note that the new minui does not currently have support for qcom
overlay graphics. Support for this graphics mode will likely be
added in a later patch set. If you are building in a 6.0 tree and
have a device that needs qcom overlay graphics, be warned, as off
mode charging may not work properly. A dead battery in this case
could potentially brick your device if it is unable to charge as
healthd handles charging duties.

Update rules for building toolbox and add rules for making toybox

Use permissive.sh in init.rc which will follow symlinks so we do
not have to worry about what binary is supplying the setenforce
functionality (toolbox, toybox, or busybox).

Fix a few warnings in the main recovery binary source code.

Fix a few includes that were missing that prevented compiling in
6.0

Change-Id: Ia67aa2107d260883da5e365475a19bea538e8b97
parents d6821a11 f5cfdcec
......@@ -88,14 +88,25 @@ LOCAL_CFLAGS += -Wno-unused-parameter
# libm \
# libc
LOCAL_C_INCLUDES += \
system/vold \
system/extras/ext4_utils \
system/core/adb \
LOCAL_C_INCLUDES += bionic external/stlport/stlport external/openssl/include $(LOCAL_PATH)/libmincrypt/includes
LOCAL_STATIC_LIBRARIES :=
LOCAL_SHARED_LIBRARIES :=
LOCAL_STATIC_LIBRARIES += libguitwrp
LOCAL_SHARED_LIBRARIES += libz libc libstlport libcutils libstdc++ libtar libblkid libminuitwrp libminadbd libmtdutils libminzip libaosprecovery
LOCAL_SHARED_LIBRARIES += libgccdemangle libcrecovery
LOCAL_SHARED_LIBRARIES += libz libc libcutils libstdc++ libtar libblkid libminuitwrp libminadbd libmtdutils libminzip libaosprecovery
LOCAL_SHARED_LIBRARIES += libcrecovery
ifneq ($(wildcard external/stlport/Android.mk),)
LOCAL_SHARED_LIBRARIES += libstlport
else
LOCAL_SHARED_LIBRARIES += libc++
endif
ifneq ($(wildcard system/core/libsparse/Android.mk),)
LOCAL_SHARED_LIBRARIES += libsparse
......@@ -113,7 +124,7 @@ ifeq ($(TARGET_USERIMAGES_USE_EXT4), true)
LOCAL_C_INCLUDES += system/extras/ext4_utils
LOCAL_SHARED_LIBRARIES += libext4_utils
ifneq ($(wildcard external/lz4/Android.mk),)
LOCAL_STATIC_LIBRARIES += liblz4-static
#LOCAL_STATIC_LIBRARIES += liblz4-static
endif
endif
ifneq ($(wildcard external/libselinux/Android.mk),)
......@@ -138,14 +149,10 @@ ifeq ($(TWHAVE_SELINUX), true)
endif
endif
# This binary is in the recovery ramdisk, which is otherwise a copy of root.
# It gets copied there in config/Makefile. LOCAL_MODULE_TAGS suppresses
# a (redundant) copy of the binary in /system/bin for user builds.
# TODO: Build the ramdisk image in a more principled way.
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
#ifeq ($(TARGET_RECOVERY_UI_LIB),)
LOCAL_SRC_FILES += default_device.cpp
# LOCAL_SRC_FILES += default_device.cpp
#else
# LOCAL_STATIC_LIBRARIES += $(TARGET_RECOVERY_UI_LIB)
#endif
......@@ -271,6 +278,7 @@ endif
ifeq ($(TW_INCLUDE_CRYPTO), true)
LOCAL_CFLAGS += -DTW_INCLUDE_CRYPTO
LOCAL_SHARED_LIBRARIES += libcryptfslollipop
LOCAL_C_INCLUDES += external/boringssl/src/include
endif
ifeq ($(TW_USE_MODEL_HARDWARE_ID_FOR_DEVICE_ID), true)
LOCAL_CFLAGS += -DTW_USE_MODEL_HARDWARE_ID_FOR_DEVICE_ID
......@@ -311,6 +319,9 @@ endif
ifneq ($(TARGET_RECOVERY_INITRC),)
TW_EXCLUDE_DEFAULT_USB_INIT := true
endif
ifeq ($(shell test $(PLATFORM_SDK_VERSION) -gt 22; echo $$?),0)
LOCAL_CFLAGS += -DTW_USE_NEW_MINADBD
endif
LOCAL_ADDITIONAL_DEPENDENCIES := \
dump_image \
......@@ -339,6 +350,10 @@ else
endif
ifneq ($(TW_USE_TOOLBOX), true)
LOCAL_ADDITIONAL_DEPENDENCIES += busybox_symlinks
else
ifneq ($(wildcard external/toybox/Android.mk),)
LOCAL_ADDITIONAL_DEPENDENCIES += toybox_symlinks
endif
endif
ifneq ($(TW_NO_EXFAT), true)
LOCAL_ADDITIONAL_DEPENDENCIES += mkexfatfs
......@@ -483,9 +498,7 @@ endif
include $(BUILD_SHARED_LIBRARY)
commands_recovery_local_path := $(LOCAL_PATH)
include $(LOCAL_PATH)/minui/Android.mk \
$(LOCAL_PATH)/minadbd/Android.mk \
$(LOCAL_PATH)/tests/Android.mk \
include $(LOCAL_PATH)/tests/Android.mk \
$(LOCAL_PATH)/tools/Android.mk \
$(LOCAL_PATH)/edify/Android.mk \
$(LOCAL_PATH)/updater/Android.mk \
......@@ -495,6 +508,15 @@ ifeq ($(wildcard system/core/uncrypt/Android.mk),)
include $(commands_recovery_local_path)/uncrypt/Android.mk
endif
ifeq ($(shell test $(PLATFORM_SDK_VERSION) -gt 22; echo $$?),0)
include $(commands_recovery_local_path)/minadbd/Android.mk \
$(commands_recovery_local_path)/minui/Android.mk
else
TARGET_GLOBAL_CFLAGS += -DTW_USE_OLD_MINUI_H
include $(commands_recovery_local_path)/minadbd.old/Android.mk \
$(commands_recovery_local_path)/minui.old/Android.mk
endif
#includes for TWRP
include $(commands_recovery_local_path)/injecttwrp/Android.mk \
$(commands_recovery_local_path)/htcdumlock/Android.mk \
......@@ -516,7 +538,9 @@ include $(commands_recovery_local_path)/injecttwrp/Android.mk \
$(commands_recovery_local_path)/mtp/Android.mk \
$(commands_recovery_local_path)/minzip/Android.mk \
$(commands_recovery_local_path)/dosfstools/Android.mk \
$(commands_recovery_local_path)/etc/Android.mk
$(commands_recovery_local_path)/etc/Android.mk \
$(commands_recovery_local_path)/toybox/Android.mk \
$(commands_recovery_local_path)/libpixelflinger/Android.mk
ifeq ($(TW_INCLUDE_CRYPTO), true)
include $(commands_recovery_local_path)/crypto/lollipop/Android.mk
......
**Team Win Recovery Project (TWRP)**
The goal of this branch is to rebase TWRP onto AOSP while maintaining as much of the original AOSP code as possible. This goal should allow us to apply updates to the AOSP code going forward with little to no extra work. With this goal in mind, we will carefully consider any changes needed to the AOSP code before allowing them. In most cases, instead of changing the AOSP code, we'll create our own functions instead. The only changes that should be made to AOSP code should be those affecting startup of the recovery and some of the make files.
If there are changes that need to be merged from AOSP, we will pull the change directly from AOSP instead of creating a new patch in order to prevent merge conflicts with AOSP.
This branch is under final testing and will be used shortly for public builds, but has not officially been released.
You can find a compiling guide [here](http://forum.xda-developers.com/showthread.php?t=1943625 "Guide").
[More information about the project.](http://www.teamw.in/project/twrp2 "More Information")
If you have code changes to submit those should be pushed to our gerrit instance. A guide can be found [here](http://teamw.in/twrp2-gerrit "Gerrit Guide").
......@@ -29,10 +29,8 @@
#include "ui.h"
#include "cutils/properties.h"
#include "adb_install.h"
extern "C" {
#include "minadbd/fuse_adb_provider.h"
#include "fuse_sideload.h"
}
static RecoveryUI* ui = NULL;
......@@ -47,7 +45,8 @@ set_usb_driver(bool enabled) {
printf("failed to open driver control: %s\n", strerror(errno));
return;
}
if (write(fd, enabled ? "1" : "0", 1) < 0) {
if (TEMP_FAILURE_RETRY(write(fd, enabled ? "1" : "0", 1)) == -1) {
/*
ui->Print("failed to set driver control: %s\n", strerror(errno));
*/
......@@ -67,12 +66,15 @@ stop_adbd() {
set_usb_driver(false);
}
bool is_ro_debuggable() {
char value[PROPERTY_VALUE_MAX+1];
return (property_get("ro.debuggable", value, NULL) == 1 && value[0] == '1');
}
void
maybe_restart_adbd() {
char value[PROPERTY_VALUE_MAX+1];
int len = property_get("ro.debuggable", value, NULL);
if (len == 1 && value[0] == '1') {
if (is_ro_debuggable()) {
printf("Restarting adbd...\n");
set_usb_driver(true);
property_set("ctl.start", "adbd");
......
......@@ -453,20 +453,19 @@ int WriteToPartition(unsigned char* data, size_t len,
int attempt;
for (attempt = 0; attempt < 2; ++attempt) {
lseek(fd, start, SEEK_SET);
if (TEMP_FAILURE_RETRY(lseek(fd, start, SEEK_SET)) == -1) {
printf("failed seek on %s: %s\n",
partition, strerror(errno));
return -1;
}
while (start < len) {
size_t to_write = len - start;
if (to_write > 1<<20) to_write = 1<<20;
ssize_t written = write(fd, data+start, to_write);
if (written < 0) {
if (errno == EINTR) {
written = 0;
} else {
printf("failed write writing to %s (%s)\n",
partition, strerror(errno));
return -1;
}
ssize_t written = TEMP_FAILURE_RETRY(write(fd, data+start, to_write));
if (written == -1) {
printf("failed write writing to %s: %s\n", partition, strerror(errno));
return -1;
}
start += written;
}
......@@ -491,13 +490,20 @@ int WriteToPartition(unsigned char* data, size_t len,
// won't just be reading the cache.
sync();
int dc = open("/proc/sys/vm/drop_caches", O_WRONLY);
write(dc, "3\n", 2);
if (TEMP_FAILURE_RETRY(write(dc, "3\n", 2)) == -1) {
printf("write to /proc/sys/vm/drop_caches failed: %s\n", strerror(errno));
} else {
printf(" caches dropped\n");
}
close(dc);
sleep(1);
printf(" caches dropped\n");
// verify
lseek(fd, 0, SEEK_SET);
if (TEMP_FAILURE_RETRY(lseek(fd, 0, SEEK_SET)) == -1) {
printf("failed to seek back to beginning of %s: %s\n",
partition, strerror(errno));
return -1;
}
unsigned char buffer[4096];
start = len;
size_t p;
......@@ -507,15 +513,12 @@ int WriteToPartition(unsigned char* data, size_t len,
size_t so_far = 0;
while (so_far < to_read) {
ssize_t read_count = read(fd, buffer+so_far, to_read-so_far);
if (read_count < 0) {
if (errno == EINTR) {
read_count = 0;
} else {
printf("verify read error %s at %zu: %s\n",
partition, p, strerror(errno));
return -1;
}
ssize_t read_count =
TEMP_FAILURE_RETRY(read(fd, buffer+so_far, to_read-so_far));
if (read_count == -1) {
printf("verify read error %s at %zu: %s\n",
partition, p, strerror(errno));
return -1;
}
if ((size_t)read_count < to_read) {
printf("short verify read %s at %zu: %zd %zu %s\n",
......@@ -656,8 +659,8 @@ ssize_t FileSink(const unsigned char* data, ssize_t len, void* token) {
ssize_t done = 0;
ssize_t wrote;
while (done < (ssize_t) len) {
wrote = write(fd, data+done, len-done);
if (wrote <= 0) {
wrote = TEMP_FAILURE_RETRY(write(fd, data+done, len-done));
if (wrote == -1) {
printf("error writing %d bytes: %s\n", (int)(len-done), strerror(errno));
return done;
}
......@@ -690,7 +693,7 @@ size_t FreeSpaceForFile(const char* filename) {
printf("failed to statfs %s: %s\n", filename, strerror(errno));
return -1;
}
return sf.f_bsize * sf.f_bfree;
return sf.f_bsize * sf.f_bavail;
}
int CacheSizeCheck(size_t bytes) {
......
......@@ -23,6 +23,7 @@
#include <stdio.h>
#include <sys/stat.h>
#include <errno.h>
#include <malloc.h>
#include <unistd.h>
#include <string.h>
......
......@@ -408,6 +408,7 @@ unsigned char* ReadImage(const char* filename,
p[2] == 0x08 && // deflate compression
p[3] == 0x00) { // no header flags
// 'pos' is the offset of the start of a gzip chunk.
size_t chunk_offset = pos;
*num_chunks += 3;
*chunks = realloc(*chunks, *num_chunks * sizeof(ImageChunk));
......@@ -453,6 +454,14 @@ unsigned char* ReadImage(const char* filename,
strm.avail_out = allocated - curr->len;
strm.next_out = curr->data + curr->len;
ret = inflate(&strm, Z_NO_FLUSH);
if (ret < 0) {
printf("Error: inflate failed [%s] at file offset [%zu]\n"
"imgdiff only supports gzip kernel compression,"
" did you try CONFIG_KERNEL_LZO?\n",
strm.msg, chunk_offset);
free(img);
return NULL;
}
curr->len = allocated - strm.avail_out;
if (strm.avail_out == 0) {
allocated *= 2;
......
......@@ -21,6 +21,7 @@
#include <sys/cdefs.h>
#include <sys/stat.h>
#include <errno.h>
#include <malloc.h>
#include <unistd.h>
#include <string.h>
......
......@@ -14,6 +14,7 @@
* limitations under the License.
*/
#include <malloc.h>
#include <stdint.h>
#include <string.h>
......
......@@ -30,6 +30,7 @@ extern "C" {
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
// fake Volume struct that allows us to use the AOSP code easily
struct Volume
......
......@@ -17,6 +17,7 @@
#ifndef RECOVERY_COMMON_H
#define RECOVERY_COMMON_H
#include <stdbool.h>
#include <stdio.h>
#include <stdarg.h>
......@@ -24,13 +25,7 @@
extern "C" {
#endif
static long tmplog_offset = 0;
#define ui_print(...) printf(__VA_ARGS__)
#define ui_print_overwrite(...) printf(__VA_ARGS__)
// TODO: restore ui_print for LOGE
#define LOGE(...) printf("E:" __VA_ARGS__)
#define LOGE(...) fprintf(stdout, "E:" __VA_ARGS__)
#define LOGW(...) fprintf(stdout, "W:" __VA_ARGS__)
#define LOGI(...) fprintf(stdout, "I:" __VA_ARGS__)
......@@ -45,12 +40,15 @@ static long tmplog_offset = 0;
#define STRINGIFY(x) #x
#define EXPAND(x) STRINGIFY(x)
extern bool modified_flash;
//typedef struct fstab_rec Volume;
// fopen a file, mounting volumes and making parent dirs as necessary.
FILE* fopen_path(const char *path, const char *mode);
//void ui_print(const char* format, ...);
void ui_print(const char* format, ...);
bool is_ro_debuggable();
#ifdef __cplusplus
}
......
......@@ -15,28 +15,38 @@ ifeq ($(TARGET_HW_DISK_ENCRYPTION),true)
LOCAL_CFLAGS += -DCONFIG_HW_DISK_ENCRYPTION
endif
ifneq ($(wildcard hardware/libhardware/include/hardware/keymaster0.h),)
LOCAL_CFLAGS += -DTW_CRYPTO_HAVE_KEYMASTERX
LOCAL_C_INCLUDES += external/boringssl/src/include
endif
LOCAL_WHOLE_STATIC_LIBRARIES += libscrypttwrp_static
include $(BUILD_SHARED_LIBRARY)
#include $(CLEAR_VARS)
#LOCAL_MODULE := twrpdec
#LOCAL_MODULE_TAGS := eng optional
#LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
#LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
#LOCAL_SRC_FILES := main.c cryptfs.c
#LOCAL_SHARED_LIBRARIES := libcrypto libhardware libcutils libc
#LOCAL_C_INCLUDES := external/openssl/include $(commands_recovery_local_path)/crypto/scrypt/lib/crypto
include $(CLEAR_VARS)
LOCAL_MODULE := twrpdec
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
LOCAL_SRC_FILES := main.c cryptfs.c
LOCAL_SHARED_LIBRARIES := libcrypto libhardware libcutils libc
LOCAL_C_INCLUDES := external/openssl/include $(commands_recovery_local_path)/crypto/scrypt/lib/crypto
ifeq ($(TARGET_HW_DISK_ENCRYPTION),true)
LOCAL_C_INCLUDES += device/qcom/common/cryptfs_hw
LOCAL_SHARED_LIBRARIES += libcryptfs_hw
LOCAL_CFLAGS += -DCONFIG_HW_DISK_ENCRYPTION
endif
#ifeq ($(TARGET_HW_DISK_ENCRYPTION),true)
# LOCAL_C_INCLUDES += device/qcom/common/cryptfs_hw
# LOCAL_SHARED_LIBRARIES += libcryptfs_hw
# LOCAL_CFLAGS += -DCONFIG_HW_DISK_ENCRYPTION
#endif
ifneq ($(wildcard hardware/libhardware/include/hardware/keymaster0.h),)
LOCAL_CFLAGS += -DTW_CRYPTO_HAVE_KEYMASTERX
LOCAL_C_INCLUDES += external/boringssl/src/include
endif
#LOCAL_WHOLE_STATIC_LIBRARIES += libscrypttwrp_static
#include $(BUILD_EXECUTABLE)
LOCAL_WHOLE_STATIC_LIBRARIES += libscrypttwrp_static
include $(BUILD_EXECUTABLE)
endif
......@@ -43,7 +43,16 @@
#include "cryptfs.h"
#include "cutils/properties.h"
#include "crypto_scrypt.h"
#ifndef TW_CRYPTO_HAVE_KEYMASTERX
#include <hardware/keymaster.h>
#else
#include <stdbool.h>
#include <openssl/evp.h>
#include <openssl/sha.h>
#include <hardware/keymaster0.h>
#include <hardware/keymaster1.h>
#endif
#ifndef min /* already defined by windows.h */
#define min(a, b) ((a) < (b) ? (a) : (b))
......@@ -76,6 +85,7 @@
#define RSA_KEY_SIZE 2048
#define RSA_KEY_SIZE_BYTES (RSA_KEY_SIZE / 8)
#define RSA_EXPONENT 0x10001
#define KEYMASTER_CRYPTFS_RATE_LIMIT 1 // Maximum one try per second
#define RETRY_MOUNT_ATTEMPTS 10
#define RETRY_MOUNT_DELAY_SECONDS 1
......@@ -97,6 +107,7 @@ void set_partition_data(const char* block_device, const char* key_location, cons
strcpy(file_system, fs);
}
#ifndef TW_CRYPTO_HAVE_KEYMASTERX
static int keymaster_init(keymaster_device_t **keymaster_dev)
{
int rc;
......@@ -279,6 +290,308 @@ static int keymaster_sign_object(struct crypt_mnt_ftr *ftr,
keymaster_close(keymaster_dev);
return rc;
}
#else //#ifndef TW_CRYPTO_HAVE_KEYMASTERX
static int keymaster_init(keymaster0_device_t **keymaster0_dev,
keymaster1_device_t **keymaster1_dev)
{
int rc;
const hw_module_t* mod;
rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod);
if (rc) {
printf("could not find any keystore module\n");
goto err;
}
printf("keymaster module name is %s\n", mod->name);
printf("keymaster version is %d\n", mod->module_api_version);
*keymaster0_dev = NULL;
*keymaster1_dev = NULL;
if (mod->module_api_version == KEYMASTER_MODULE_API_VERSION_1_0) {
printf("Found keymaster1 module, using keymaster1 API.\n");
rc = keymaster1_open(mod, keymaster1_dev);
} else {
printf("Found keymaster0 module, using keymaster0 API.\n");
rc = keymaster0_open(mod, keymaster0_dev);
}
if (rc) {
printf("could not open keymaster device in %s (%s)\n",
KEYSTORE_HARDWARE_MODULE_ID, strerror(-rc));
goto err;
}
return 0;
err:
*keymaster0_dev = NULL;
*keymaster1_dev = NULL;
return rc;
}
/* Should we use keymaster? */
static int keymaster_check_compatibility()
{
keymaster0_device_t *keymaster0_dev = 0;
keymaster1_device_t *keymaster1_dev = 0;
int rc = 0;
if (keymaster_init(&keymaster0_dev, &keymaster1_dev)) {
printf("Failed to init keymaster\n");
rc = -1;
goto out;
}
if (keymaster1_dev) {
rc = 1;
goto out;
}
// TODO(swillden): Check to see if there's any reason to require v0.3. I think v0.1 and v0.2
// should work.
if (keymaster0_dev->common.module->module_api_version
< KEYMASTER_MODULE_API_VERSION_0_3) {
rc = 0;
goto out;
}
if (!(keymaster0_dev->flags & KEYMASTER_SOFTWARE_ONLY) &&
(keymaster0_dev->flags & KEYMASTER_BLOBS_ARE_STANDALONE)) {
rc = 1;
}
out:
if (keymaster1_dev) {
keymaster1_close(keymaster1_dev);
}
if (keymaster0_dev) {
keymaster0_close(keymaster0_dev);
}
return rc;
}
/* Create a new keymaster key and store it in this footer */
static int keymaster_create_key(struct crypt_mnt_ftr *ftr)
{
uint8_t* key = 0;
keymaster0_device_t *keymaster0_dev = 0;
keymaster1_device_t *keymaster1_dev = 0;
if (keymaster_init(&keymaster0_dev, &keymaster1_dev)) {
printf("Failed to init keymaster\n");
return -1;
}
int rc = 0;
size_t key_size = 0;
if (keymaster1_dev) {
keymaster_key_param_t params[] = {
/* Algorithm & size specifications. Stick with RSA for now. Switch to AES later. */
keymaster_param_enum(KM_TAG_ALGORITHM, KM_ALGORITHM_RSA),
keymaster_param_int(KM_TAG_KEY_SIZE, RSA_KEY_SIZE),
keymaster_param_long(KM_TAG_RSA_PUBLIC_EXPONENT, RSA_EXPONENT),
/* The only allowed purpose for this key is signing. */
keymaster_param_enum(KM_TAG_PURPOSE, KM_PURPOSE_SIGN),
/* Padding & digest specifications. */
keymaster_param_enum(KM_TAG_PADDING, KM_PAD_NONE),
keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_NONE),
/* Require that the key be usable in standalone mode. File system isn't available. */
keymaster_param_enum(KM_TAG_BLOB_USAGE_REQUIREMENTS, KM_BLOB_STANDALONE),
/* No auth requirements, because cryptfs is not yet integrated with gatekeeper. */
keymaster_param_bool(KM_TAG_NO_AUTH_REQUIRED),
/* Rate-limit key usage attempts, to rate-limit brute force */
keymaster_param_int(KM_TAG_MIN_SECONDS_BETWEEN_OPS, KEYMASTER_CRYPTFS_RATE_LIMIT),
};
keymaster_key_param_set_t param_set = { params, sizeof(params)/sizeof(*params) };
keymaster_key_blob_t key_blob;
keymaster_error_t error = keymaster1_dev->generate_key(keymaster1_dev, &param_set,
&key_blob,
NULL /* characteristics */);
if (error != KM_ERROR_OK) {
printf("Failed to generate keymaster1 key, error %d\n", error);
rc = -1;
goto out;
}
key = (uint8_t*)key_blob.key_material;
key_size = key_blob.key_material_size;
}
else if (keymaster0_dev) {
keymaster_rsa_keygen_params_t params;
memset(&params, '\0', sizeof(params));
params.public_exponent = RSA_EXPONENT;
params.modulus_size = RSA_KEY_SIZE;
if (keymaster0_dev->generate_keypair(keymaster0_dev, TYPE_RSA, &params,
&key, &key_size)) {
printf("Failed to generate keypair\n");
rc = -1;
goto out;
}
} else {
printf("Cryptfs bug: keymaster_init succeeded but didn't initialize a device\n");
rc = -1;
goto out;
}
if (key_size > KEYMASTER_BLOB_SIZE) {
printf("Keymaster key too large for crypto footer\n");
rc = -1;
goto out;
}
memcpy(ftr->keymaster_blob, key, key_size);
ftr->keymaster_blob_size = key_size;
out:
if (keymaster0_dev)
keymaster0_close(keymaster0_dev);
if (keymaster1_dev)
keymaster1_close(keymaster1_dev);
free(key);
return rc;
}
/* This signs the given object using the keymaster key. */
static int keymaster_sign_object(struct crypt_mnt_ftr *ftr,
const unsigned char *object,
const size_t object_size,
unsigned char **signature,
size_t *signature_size)
{
int rc = 0;
keymaster0_device_t *keymaster0_dev = 0;
keymaster1_device_t *keymaster1_dev = 0;
if (keymaster_init(&keymaster0_dev, &keymaster1_dev)) {
printf("Failed to init keymaster\n");
rc = -1;
goto out;
}
unsigned char to_sign[RSA_KEY_SIZE_BYTES];
size_t to_sign_size = sizeof(to_sign);
memset(to_sign, 0, RSA_KEY_SIZE_BYTES);
// To sign a message with RSA, the message must satisfy two
// constraints:
//
// 1. The message, when interpreted as a big-endian numeric value, must
// be strictly less than the public modulus of the RSA key. Note
// that because the most significant bit of the public modulus is
// guaranteed to be 1 (else it's an (n-1)-bit key, not an n-bit
// key), an n-bit message with most significant bit 0 always
// satisfies this requirement.
//
// 2. The message must have the same length in bits as the public
// modulus of the RSA key. This requirement isn't mathematically
// necessary, but is necessary to ensure consistency in
// implementations.
switch (ftr->kdf_type) {
case KDF_SCRYPT_KEYMASTER:
// This ensures the most significant byte of the signed message
// is zero. We could have zero-padded to the left instead, but
// this approach is slightly more robust against changes in
// object size. However, it's still broken (but not unusably
// so) because we really should be using a proper deterministic
// RSA padding function, such as PKCS1.
memcpy(to_sign + 1, object, min(RSA_KEY_SIZE_BYTES - 1, object_size));
printf("Signing safely-padded object\n");
break;
default:
printf("Unknown KDF type %d\n", ftr->kdf_type);
rc = -1;
goto out;
}
if (keymaster0_dev) {
keymaster_rsa_sign_params_t params;
params.digest_type = DIGEST_NONE;
params.padding_type = PADDING_NONE;
rc = keymaster0_dev->sign_data(keymaster0_dev,
&params,
ftr->keymaster_blob,
ftr->keymaster_blob_size,
to_sign,
to_sign_size,
signature,
signature_size);
goto out;
} else if (keymaster1_dev) {
keymaster_key_blob_t key = { ftr->keymaster_blob, ftr->keymaster_blob_size };
keymaster_key_param_t params[] = {
keymaster_param_enum(KM_TAG_PADDING, KM_PAD_NONE),
keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_NONE),
};
keymaster_key_param_set_t param_set = { params, sizeof(params)/sizeof(*params) };
keymaster_operation_handle_t op_handle;
keymaster_error_t error = keymaster1_dev->begin(keymaster1_dev, KM_PURPOSE_SIGN, &key,
&param_set, NULL /* out_params */,
&op_handle);
if (error == KM_ERROR_KEY_RATE_LIMIT_EXCEEDED) {
// Key usage has been rate-limited. Wait a bit and try again.
sleep(KEYMASTER_CRYPTFS_RATE_LIMIT);
error = keymaster1_dev->begin(keymaster1_dev, KM_PURPOSE_SIGN, &key,
&param_set, NULL /* out_params */,
&op_handle);
}
if (error != KM_ERROR_OK) {
printf("Error starting keymaster signature transaction: %d\n", error);
rc = -1;
goto out;
}
keymaster_blob_t input = { to_sign, to_sign_size };
size_t input_consumed;
error = keymaster1_dev->update(keymaster1_dev, op_handle, NULL /* in_params */,
&input, &input_consumed, NULL /* out_params */,
NULL /* output */);
if (error != KM_ERROR_OK) {
printf("Error sending data to keymaster signature transaction: %d\n", error);
rc = -1;
goto out;
}
if (input_consumed != to_sign_size) {
// This should never happen. If it does, it's a bug in the keymaster implementation.
printf("Keymaster update() did not consume all data.\n");
keymaster1_dev->abort(keymaster1_dev, op_handle);
rc = -1;
goto out;
}
keymaster_blob_t tmp_sig;
error = keymaster1_dev->finish(keymaster1_dev, op_handle, NULL /* in_params */,
NULL /* verify signature */, NULL /* out_params */,
&tmp_sig);
if (error != KM_ERROR_OK) {
printf("Error finishing keymaster signature transaction: %d\n", error);
rc = -1;
goto out;
}
*signature = (uint8_t*)tmp_sig.data;
*signature_size = tmp_sig.data_length;
} else {
printf("Cryptfs bug: keymaster_init succeded but didn't initialize a device.\n");
rc = -1;
goto out;
}
out:
if (keymaster1_dev)
keymaster1_close(keymaster1_dev);
if (keymaster0_dev)
keymaster0_close(keymaster0_dev);
return rc;
}
#endif //#ifndef TW_CRYPTO_HAVE_KEYMASTERX
/* Store password when userdata is successfully decrypted and mounted.
* Cleared by cryptfs_clear_password
......@@ -352,7 +665,7 @@ static void get_device_scrypt_params(struct crypt_mnt_ftr *ftr) {
* taken.
*/
if ((i != 3) || (token != NULL)) {
printf("bad scrypt parameters '%s' should be like '12:8:1'; using defaults", paramstr);
printf("bad scrypt parameters '%s' should be like '12:8:1'; using defaults\n", paramstr);
memcpy(params, default_params, sizeof(params));
}
}
......@@ -526,13 +839,13 @@ static unsigned char* convert_hex_ascii_to_key(const char* master_key_ascii,
size_t size = strlen (master_key_ascii);
if (size % 2) {
printf("Trying to convert ascii string of odd length");
printf("Trying to convert ascii string of odd length\n");
return NULL;
}
unsigned char* master_key = (unsigned char*) malloc(size / 2);
if (master_key == 0) {
printf("Cannot allocate");
printf("Cannot allocate\n");
return NULL;
}
......@@ -541,7 +854,7 @@ static unsigned char* convert_hex_ascii_to_key(const char* master_key_ascii,
int low_nibble = hexdigit (master_key_ascii[i + 1]);
if(high_nibble < 0 || low_nibble < 0) {
printf("Invalid hex string");
printf("Invalid hex string\n");
free (master_key);
return NULL;
}
......@@ -818,7 +1131,7 @@ errout:
static int pbkdf2(const char *passwd, const unsigned char *salt,
unsigned char *ikey, void *params UNUSED)
{
printf("Using pbkdf2 for cryptfs KDF");
printf("Using pbkdf2 for cryptfs KDF\n");
/* Turn the password into a key and IV that can decrypt the master key */
unsigned int keysize;
......@@ -922,25 +1235,25 @@ static int encrypt_master_key(const char *passwd, const unsigned char *salt,
case KDF_SCRYPT_KEYMASTER_BADLY_PADDED:
case KDF_SCRYPT_KEYMASTER:
if (keymaster_create_key(crypt_ftr)) {
printf("keymaster_create_key failed");
printf("keymaster_create_key failed\n");
return -1;
}
if (scrypt_keymaster(passwd, salt, ikey, crypt_ftr)) {
printf("scrypt failed");
printf("scrypt failed\n");
return -1;
}
break;
case KDF_SCRYPT:
if (scrypt(passwd, salt, ikey, crypt_ftr)) {
printf("scrypt failed");
printf("scrypt failed\n");
return -1;
}
break;
default:
printf("Invalid kdf_type");
printf("Invalid kdf_type\n");
return -1;
}
......@@ -957,7 +1270,11 @@ static int encrypt_master_key(const char *passwd, const unsigned char *salt,
printf("EVP_EncryptUpdate failed\n");
return -1;
}
#ifndef TW_CRYPTO_HAVE_KEYMASTERX
if (! EVP_EncryptFinal(&e_ctx, encrypted_master_key + encrypted_len, &final_len)) {
#else
if (! EVP_EncryptFinal_ex(&e_ctx, encrypted_master_key + encrypted_len, &final_len)) {
#endif
printf("EVP_EncryptFinal failed\n");
return -1;
}
......@@ -982,7 +1299,7 @@ static int encrypt_master_key(const char *passwd, const unsigned char *salt,
sizeof(crypt_ftr->scrypted_intermediate_key));
if (rc) {
printf("encrypt_master_key: crypto_scrypt failed");
printf("encrypt_master_key: crypto_scrypt failed\n");
}
return 0;
......@@ -1002,7 +1319,7 @@ static int decrypt_master_key_aux(char *passwd, unsigned char *salt,
/* Turn the password into an intermediate key and IV that can decrypt the
master key */
if (kdf(passwd, salt, ikey, kdf_params)) {
printf("kdf failed");
printf("kdf failed\n");
return -1;
}
......@@ -1016,7 +1333,11 @@ static int decrypt_master_key_aux(char *passwd, unsigned char *salt,
encrypted_master_key, KEY_LEN_BYTES)) {
return -1;
}
#ifndef TW_CRYPTO_HAVE_KEYMASTERX
if (! EVP_DecryptFinal(&d_ctx, decrypted_master_key + decrypted_len, &final_len)) {
#else
if (! EVP_DecryptFinal_ex(&d_ctx, decrypted_master_key + decrypted_len, &final_len)) {
#endif
return -1;
}
......@@ -1066,7 +1387,7 @@ static int decrypt_master_key(char *passwd, unsigned char *decrypted_master_key,
decrypted_master_key, kdf, kdf_params,
intermediate_key, intermediate_key_size);
if (ret != 0) {
printf("failure decrypting master key");
printf("failure decrypting master key\n");
}
return ret;
......@@ -1396,7 +1717,7 @@ int cryptfs_check_passwd(char *passwd)
// cryptfs_changepw also adjusts so pass original
// Note that adjust_passwd only recognises patterns
// so we can safely use CRYPT_TYPE_PATTERN
printf("TWRP NOT Updating pattern to new format");
printf("TWRP NOT Updating pattern to new format\n");
//cryptfs_changepw(CRYPT_TYPE_PATTERN, passwd);
} else if (hex_passwd) {
//printf("trying hex_passwd '%s'\n", hex_passwd);
......@@ -1445,17 +1766,17 @@ int cryptfs_verify_passwd(char *passwd)
property_get("ro.crypto.state", encrypted_state, "");
if (strcmp(encrypted_state, "encrypted") ) {
printf("device not encrypted, aborting");
printf("device not encrypted, aborting\n");
return -2;
}
if (!master_key_saved) {
printf("encrypted fs not yet mounted, aborting");
printf("encrypted fs not yet mounted, aborting\n");
return -1;
}
if (!saved_mount_point) {
printf("encrypted fs failed to save mount point, aborting");
printf("encrypted fs failed to save mount point, aborting\n");
return -1;
}
......@@ -1515,7 +1836,7 @@ static int cryptfs_init_crypt_mnt_ftr(struct crypt_mnt_ftr *ftr)
break;
default:
printf("keymaster_check_compatibility failed");
printf("keymaster_check_compatibility failed\n");
return -1;
}
......
......@@ -23,13 +23,10 @@
#include "cryptfs.h"
#include "cutils/properties.h"
#include "crypto_scrypt.h"
#include <hardware/keymaster.h>
int main() {
printf("blah\n");
set_partition_data("/dev/block/mmcblk0p28", "/dev/block/mmcblk0p27", "ext4");
printf("blah2\n");
int ret = cryptfs_check_passwd("30303030");
//int ret = cryptfs_check_passwd("0000");
set_partition_data("/dev/block/platform/sdhci-tegra.3/by-name/UDA", "/dev/block/platform/sdhci-tegra.3/by-name/MD1", "f2fs");
//int ret = cryptfs_check_passwd("30303030");
int ret = cryptfs_check_passwd("0000");
return 0;
}
local_c_flags := -DUSE_OPENSSL_PBKDF2
local_c_includes := $(log_c_includes) external/openssl/include
local_c_includes := $(log_c_includes) external/openssl/include external/boringssl/src/include
local_additional_dependencies := $(LOCAL_PATH)/android-config.mk $(LOCAL_PATH)/Scrypt.mk
......
......@@ -38,6 +38,7 @@
#include <map>
#include <fstream>
#include <sstream>
#include <pthread.h>
#include "variables.h"
#include "data.hpp"
......@@ -76,7 +77,11 @@ int DataManager::mInitialized = 0;
extern bool datamedia;
#ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
pthread_mutex_t DataManager::m_valuesLock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
#else
pthread_mutex_t DataManager::m_valuesLock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
#endif
// Device ID functions
void DataManager::sanitize_device_id(char* device_id) {
......
......@@ -22,6 +22,7 @@
#include <string>
#include <utility>
#include <map>
#include <pthread.h>
using namespace std;
......
......@@ -14,74 +14,9 @@
* limitations under the License.
*/
#include <linux/input.h>
#include "common.h"
#include "device.h"
#include "screen_ui.h"
static const char* HEADERS[] = { "Volume up/down to move highlight;",
"enter button to select.",
"",
NULL };
static const char* ITEMS[] = {"reboot system now",
"apply update from ADB",
"wipe data/factory reset",
"wipe cache partition",
"reboot to bootloader",
"power down",
"view recovery logs",
NULL };
class DefaultDevice : public Device {
public:
DefaultDevice() :
ui(new ScreenRecoveryUI) {
}
RecoveryUI* GetUI() { return ui; }
int HandleMenuKey(int key, int visible) {
if (visible) {
switch (key) {
case KEY_DOWN:
case KEY_VOLUMEDOWN:
return kHighlightDown;
case KEY_UP:
case KEY_VOLUMEUP:
return kHighlightUp;
case KEY_ENTER:
case KEY_POWER:
return kInvokeItem;
}
}
return kNoAction;
}
BuiltinAction InvokeMenuItem(int menu_position) {
switch (menu_position) {
case 0: return REBOOT;
case 1: return APPLY_ADB_SIDELOAD;
case 2: return WIPE_DATA;
case 3: return WIPE_CACHE;
case 4: return REBOOT_BOOTLOADER;
case 5: return SHUTDOWN;
case 6: return READ_RECOVERY_LASTLOG;
default: return NO_ACTION;
}
}
const char* const* GetMenuHeaders() { return HEADERS; }
const char* const* GetMenuItems() { return ITEMS; }
private:
RecoveryUI* ui;
};
Device* make_device() {
return new DefaultDevice();
return new Device(new ScreenRecoveryUI);
}
/*
* Copyright (C) 2015 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 "device.h"
static const char* MENU_ITEMS[] = {
"Reboot system now",
"Reboot to bootloader",
"Apply update from ADB",
"Apply update from SD card",
"Wipe data/factory reset",
"Wipe cache partition",
"Mount /system",
"View recovery logs",
"Power off",
NULL
};
const char* const* Device::GetMenuItems() {
return MENU_ITEMS;
}
Device::BuiltinAction Device::InvokeMenuItem(int menu_position) {
switch (menu_position) {
case 0: return REBOOT;
case 1: return REBOOT_BOOTLOADER;
case 2: return APPLY_ADB_SIDELOAD;
case 3: return APPLY_SDCARD;
case 4: return WIPE_DATA;
case 5: return WIPE_CACHE;
case 6: return MOUNT_SYSTEM;
case 7: return VIEW_RECOVERY_LOGS;
case 8: return SHUTDOWN;
default: return NO_ACTION;
}
}
int Device::HandleMenuKey(int key, int visible) {
if (!visible) {
return kNoAction;
}
switch (key) {
case KEY_DOWN:
case KEY_VOLUMEDOWN:
return kHighlightDown;
case KEY_UP:
case KEY_VOLUMEUP:
return kHighlightUp;
case KEY_ENTER:
case KEY_POWER:
return kInvokeItem;
default:
// If you have all of the above buttons, any other buttons
// are ignored. Otherwise, any button cycles the highlight.
return ui_->HasThreeButtons() ? kNoAction : kHighlightDown;
}
}
......@@ -21,29 +21,20 @@
class Device {
public:
Device(RecoveryUI* ui) : ui_(ui) { }
virtual ~Device() { }
// Called to obtain the UI object that should be used to display
// the recovery user interface for this device. You should not
// have called Init() on the UI object already, the caller will do
// that after this method returns.
virtual RecoveryUI* GetUI() = 0;
virtual RecoveryUI* GetUI() { return ui_; }
// Called when recovery starts up (after the UI has been obtained
// and initialized and after the arguments have been parsed, but
// before anything else).
virtual void StartRecovery() { };
// enum KeyAction { NONE, TOGGLE, REBOOT };
// // Called in the input thread when a new key (key_code) is
// // pressed. *key_pressed is an array of KEY_MAX+1 bytes
// // indicating which other keys are already pressed. Return a
// // KeyAction to indicate action should be taken immediately.
// // These actions happen when recovery is not waiting for input
// // (eg, in the midst of installing a package).
// virtual KeyAction CheckImmediateKeyAction(volatile char* key_pressed, int key_code) = 0;
// Called from the main thread when recovery is at the main menu
// and waiting for input, and a key is pressed. (Note that "at"
// the main menu does not necessarily mean the menu is visible;
......@@ -63,12 +54,26 @@ class Device {
// - invoke the highlighted item (kInvokeItem)
// - do nothing (kNoAction)
// - invoke a specific action (a menu position: any non-negative number)
virtual int HandleMenuKey(int key, int visible) = 0;
virtual int HandleMenuKey(int key, int visible);
enum BuiltinAction {
NO_ACTION = 0,
REBOOT = 1,
APPLY_SDCARD = 2,
// APPLY_CACHE was 3.
APPLY_ADB_SIDELOAD = 4,
WIPE_DATA = 5,
WIPE_CACHE = 6,
REBOOT_BOOTLOADER = 7,
SHUTDOWN = 8,
VIEW_RECOVERY_LOGS = 9,
MOUNT_SYSTEM = 10,
};
enum BuiltinAction { NO_ACTION, REBOOT, APPLY_EXT,
APPLY_CACHE, // APPLY_CACHE is deprecated; has no effect
APPLY_ADB_SIDELOAD, WIPE_DATA, WIPE_CACHE,
REBOOT_BOOTLOADER, SHUTDOWN, READ_RECOVERY_LASTLOG };
// Return the list of menu items (an array of strings,
// NULL-terminated). The menu_position passed to InvokeMenuItem
// will correspond to the indexes into this array.
virtual const char* const* GetMenuItems();
// Perform a recovery action selected from the menu.
// 'menu_position' will be the item number of the selected menu
......@@ -79,31 +84,26 @@ class Device {
// builtin actions, you can just return the corresponding enum
// value. If it is an action specific to your device, you
// actually perform it here and return NO_ACTION.
virtual BuiltinAction InvokeMenuItem(int menu_position) = 0;
virtual BuiltinAction InvokeMenuItem(int menu_position);
static const int kNoAction = -1;
static const int kHighlightUp = -2;
static const int kHighlightDown = -3;
static const int kInvokeItem = -4;
// Called when we do a wipe data/factory reset operation (either via a
// reboot from the main system with the --wipe_data flag, or when the
// user boots into recovery manually and selects the option from the
// menu.) Can perform whatever device-specific wiping actions are
// needed. Return 0 on success. The userdata and cache partitions
// are erased AFTER this returns (whether it returns success or not).
virtual int WipeData() { return 0; }
// Return the headers (an array of strings, one per line,
// NULL-terminated) for the main menu. Typically these tell users
// what to push to move the selection and invoke the selected
// item.
virtual const char* const* GetMenuHeaders() = 0;
// Return the list of menu items (an array of strings,
// NULL-terminated). The menu_position passed to InvokeMenuItem
// will correspond to the indexes into this array.
virtual const char* const* GetMenuItems() = 0;
// Called before and after we do a wipe data/factory reset operation,
// either via a reboot from the main system with the --wipe_data flag,
// or when the user boots into recovery image manually and selects the
// option from the menu, to perform whatever device-specific wiping
// actions are needed.
// Return true on success; returning false from PreWipeData will prevent
// the regular wipe, and returning false from PostWipeData will cause
// the wipe to be considered a failure.
virtual bool PreWipeData() { return true; }
virtual bool PostWipeData() { return true; }
private:
RecoveryUI* ui_;
};
// The device-specific library must define this function (or the
......
......@@ -24,6 +24,6 @@ void MD5Transform(uint32_t buf[4], uint32_t const in[16]);
/*
* This is needed to make RSAREF happy on some MS-DOS compilers.
*/
typedef struct MD5Context MD5_CTX;
//typedef struct MD5Context MD5_CTX;
#endif /* !MD5_H */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment