Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 79f88bdf authored by Ethan Yonker's avatar Ethan Yonker
Browse files

Support backup/restore of FBE policies

Change-Id: Iba8ef20f57b0fb57bb9406c53148a806441d0b59
parent bd7492de
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@ include $(CLEAR_VARS)
LOCAL_MODULE := libe4crypt
LOCAL_MODULE_TAGS := eng optional
LOCAL_CFLAGS :=
LOCAL_SRC_FILES := Decrypt.cpp Ext4Crypt.cpp Keymaster.cpp KeyStorage.cpp ScryptParameters.cpp Utils.cpp HashPassword.cpp
LOCAL_SRC_FILES := Decrypt.cpp Ext4Crypt.cpp Keymaster.cpp KeyStorage.cpp ScryptParameters.cpp Utils.cpp HashPassword.cpp ext4_crypt.cpp
LOCAL_SHARED_LIBRARIES := libselinux libc libc++ libext4_utils libsoftkeymaster libbase libcrypto libcutils libkeymaster_messages libhardware libprotobuf-cpp-lite
LOCAL_STATIC_LIBRARIES := libscrypt_static
LOCAL_C_INCLUDES := system/extras/ext4_utils external/scrypt/lib/crypto system/security/keystore hardware/libhardware/include/hardware system/security/softkeymaster/include/keymaster system/keymaster/include
@@ -30,4 +30,15 @@ LOCAL_SHARED_LIBRARIES := libe4crypt

include $(BUILD_EXECUTABLE)

include $(CLEAR_VARS)
LOCAL_MODULE := e4policyget
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
LOCAL_SRC_FILES := e4policyget.cpp
LOCAL_SHARED_LIBRARIES := libe4crypt
LOCAL_LDFLAGS += -Wl,-dynamic-linker,/sbin/linker64

include $(BUILD_EXECUTABLE)

endif
+62 −0
Original line number Diff line number Diff line
@@ -17,10 +17,12 @@
#include "Decrypt.h"
#include "Ext4Crypt.h"

#include <map>
#include <string>

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>

@@ -32,6 +34,66 @@

#include <android-base/file.h>

// Store main DE raw ref / policy
extern std::string de_raw_ref;
extern std::map<userid_t, std::string> s_de_key_raw_refs;
extern std::map<userid_t, std::string> s_ce_key_raw_refs;

static bool lookup_ref_key_internal(std::map<userid_t, std::string>& key_map, const char* policy, userid_t* user_id) {
    for (std::map<userid_t, std::string>::iterator it=key_map.begin(); it!=key_map.end(); ++it) {
        if (strncmp(it->second.c_str(), policy, it->second.size()) == 0) {
            *user_id = it->first;
            return true;
        }
    }
    return false;
}

extern "C" bool lookup_ref_key(const char* policy, char* policy_type) {
    userid_t user_id = 0;
    if (strncmp(de_raw_ref.c_str(), policy, de_raw_ref.size()) == 0) {
        strcpy(policy_type, "1DK");
        return true;
    }
    if (!lookup_ref_key_internal(s_de_key_raw_refs, policy, &user_id)) {
        if (!lookup_ref_key_internal(s_ce_key_raw_refs, policy, &user_id)) {
            return false;
		} else
		    sprintf(policy_type, "1CE%d", user_id);
    } else
        sprintf(policy_type, "1DE%d", user_id);
    return true;
}

extern "C" bool lookup_ref_tar(const char* policy_type, char* policy) {
    if (strncmp(policy_type, "1", 1) != 0) {
        printf("Unexpected version %c\n", policy_type);
        return false;
    }
    const char* ptr = policy_type + 1; // skip past the version number
    if (strncmp(ptr, "DK", 2) == 0) {
        strncpy(policy, de_raw_ref.data(), de_raw_ref.size());
        return true;
    }
    userid_t user_id = atoi(ptr + 2);
    std::string raw_ref;
    if (*ptr == 'D') {
        if (lookup_key_ref(s_de_key_raw_refs, user_id, &raw_ref)) {
            strncpy(policy, raw_ref.data(), raw_ref.size());
        } else
            return false;
    } else if (*ptr == 'C') {
        if (lookup_key_ref(s_ce_key_raw_refs, user_id, &raw_ref)) {
            strncpy(policy, raw_ref.data(), raw_ref.size());
        } else
            return false;
    } else {
        printf("unknown policy type '%s'\n", policy_type);
        return false;
    }
    return true;
}

int gatekeeper_device_initialize(gatekeeper_device_t **dev) {
	int ret;
	const hw_module_t *mod;
+8 −4
Original line number Diff line number Diff line
@@ -67,6 +67,12 @@ using android::vold::kEmptyAuthentication;
//static constexpr int FLAG_STORAGE_DE = 1 << 0; // moved to Decrypt.h
//static constexpr int FLAG_STORAGE_CE = 1 << 1;

// Store main DE raw ref / policy
std::string de_raw_ref;
// Map user ids to key references
std::map<userid_t, std::string> s_de_key_raw_refs;
std::map<userid_t, std::string> s_ce_key_raw_refs;

namespace {
const std::string device_key_dir = std::string() + DATA_MNT_POINT + e4crypt_unencrypted_folder;
const std::string device_key_path = device_key_dir + "/key";
@@ -80,9 +86,6 @@ bool s_global_de_initialized = false;
// Some users are ephemeral, don't try to wipe their keys from disk
std::set<userid_t> s_ephemeral_users;

// Map user ids to key references
std::map<userid_t, std::string> s_de_key_raw_refs;
std::map<userid_t, std::string> s_ce_key_raw_refs;
// TODO abolish this map. Keys should not be long-lived in user memory, only kernel memory.
// See b/26948053
std::map<userid_t, std::string> s_ce_keys;
@@ -290,7 +293,7 @@ static bool path_exists(const std::string& path) {
    return access(path.c_str(), F_OK) == 0;
}

static bool lookup_key_ref(const std::map<userid_t, std::string>& key_map, userid_t user_id,
bool lookup_key_ref(const std::map<userid_t, std::string>& key_map, userid_t user_id,
                           std::string* raw_ref) {
    auto refi = key_map.find(user_id);
    if (refi == key_map.end()) {
@@ -379,6 +382,7 @@ bool e4crypt_initialize_global_de() {
    }

    s_global_de_initialized = true;
    de_raw_ref = device_key_ref;
    return true;
}

+4 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@

#include <cutils/multiuser.h>

#include <map>
#include <string>

__BEGIN_DECLS
@@ -40,4 +41,7 @@ bool e4crypt_unlock_user_key(userid_t user_id, int serial, const char* token, co
bool e4crypt_prepare_user_storage(const char* volume_uuid, userid_t user_id, int serial, int flags);
//bool e4crypt_destroy_user_storage(const char* volume_uuid, userid_t user_id, int flags);

bool lookup_key_ref(const std::map<userid_t, std::string>& key_map, userid_t user_id,
                           std::string* raw_ref);

__END_DECLS
+44 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 Team Win Recovery Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ext4crypt_tar.h"

#define EXT4_KEY_DESCRIPTOR_SIZE 8
#define EXT4_KEY_DESCRIPTOR_SIZE_HEX 17

int main(int argc, char *argv[]) {
	bool ret = false;
	if (argc != 2) {
		printf("Must specify a path\n");
		return -1;
	} else  {
		char e4crypt_policy[EXT4_KEY_DESCRIPTOR_SIZE];
		if (e4crypt_policy_get(argv[1], e4crypt_policy, EXT4_KEY_DESCRIPTOR_SIZE, 0))
		{
			char* ptr = tar_policy;
			memset(tar_policy, 0, sizeof(tar_policy));
			char policy_hex[EXT4_KEY_DESCRIPTOR_SIZE_HEX];
			policy_to_hex(e4crypt_policy, policy_hex);
			printf("%s\n", policy_hex);
		} else {
			printf("No policy set\n");
		}
	}
	return 0;
}
Loading