Files
multirom_m86/trampoline/encryption.c
Zhuowei Zhang 42d2dcb3cf trampoline: Add new pre/post encrypt hooks, fake system properties library
These are needed on Snapdragon 810 where an extra daemon (qseecomd) must
be started prior to decryption, and where the decryption library polls
a system property to make sure that daemon is running

Also fix missing fonts log spam in trampoline_encmnt by symlinking the one available font
2016-02-10 20:19:16 -08:00

160 lines
4.6 KiB
C

/*
* This file is part of MultiROM.
*
* MultiROM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MultiROM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MultiROM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <stdio.h>
#include <sys/mount.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include "../lib/fstab.h"
#include "../lib/util.h"
#include "../lib/log.h"
#include "encryption.h"
#include "../trampoline_encmnt/encmnt_defines.h"
#include "../hooks.h"
static char encmnt_cmd_arg[64] = { 0 };
static char *const encmnt_cmd[] = { "/mrom_enc/trampoline_encmnt", encmnt_cmd_arg, NULL };
#ifdef MR_ENCRYPTION_FAKE_PROPERTIES
static char *const encmnt_envp[] = { "LD_LIBRARY_PATH=/mrom_enc/", "LD_PRELOAD=/mrom_enc/libmultirom_fake_properties.so", NULL };
#else
static char *const encmnt_envp[] = { "LD_LIBRARY_PATH=/mrom_enc/", NULL };
#endif
static int g_decrypted = 0;
#ifdef __LP64__
#define LINKER_PATH "/system/bin/linker64"
#else
#define LINKER_PATH "/system/bin/linker"
#endif
int encryption_before_mount(struct fstab *fstab)
{
int exit_code = -1;
char *output = NULL, *itr;
int res = ENC_RES_ERR;
mkdir_recursive("/system/bin", 0755);
remove(LINKER_PATH);
symlink("/mrom_enc/linker", LINKER_PATH);
chmod("/mrom_enc/linker", 0775);
chmod("/mrom_enc/trampoline_encmnt", 0775);
// some fonts not in ramdisk to save space, so use regular instead
symlink("/mrom_enc/res/Roboto-Regular.ttf", "/mrom_enc/res/Roboto-Italic.ttf");
symlink("/mrom_enc/res/Roboto-Regular.ttf", "/mrom_enc/res/Roboto-Medium.ttf");
remove("/vendor");
symlink("/mrom_enc/vendor", "/vendor");
mkdir("/firmware", 0775);
struct fstab_part *fwpart = fstab_find_first_by_path(fstab, "/firmware");
if(fwpart && strcmp(fwpart->type, "emmc") != 0)
{
if(mount(fwpart->device, "/firmware", fwpart->type, fwpart->mountflags, NULL) < 0)
ERROR("Mounting /firmware for encryption failed with %s\n", strerror(errno));
}
#if MR_DEVICE_HOOKS >= 6
tramp_hook_encryption_setup();
#endif
INFO("Running trampoline_encmnt\n");
strcpy(encmnt_cmd_arg, "decrypt");
output = run_get_stdout_with_exit_with_env(encmnt_cmd, &exit_code, encmnt_envp);
if(exit_code != 0 || !output)
{
ERROR("Failed to run trampoline_encmnt, exit code %d: %s\n", exit_code, output);
goto exit;
}
itr = output + strlen(output) - 1;
while(itr >= output && isspace(*itr))
*itr-- = 0;
if(strcmp(output, ENCMNT_BOOT_INTERNAL_OUTPUT) == 0)
{
INFO("trampoline_encmnt requested to boot internal ROM.\n");
res = ENC_RES_BOOT_INTERNAL;
goto exit;
}
if(!strstartswith(output, "/dev"))
{
ERROR("Invalid trampoline_encmnt output: %s\n", output);
goto exit;
}
g_decrypted = 1;
struct fstab_part *datap = fstab_find_first_by_path(fstab, "/data");
if(!datap)
{
ERROR("Failed to find /data in fstab!\n");
goto exit;
}
INFO("Updating device %s to %s in fstab due to encryption.\n", datap->device, output);
fstab_update_device(fstab, datap->device, output);
res = ENC_RES_OK;
exit:
free(output);
return res;
}
void encryption_destroy(void)
{
int res = -1;
int exit_code = -1;
char *output = NULL;
struct stat info;
if(g_decrypted)
{
strcpy(encmnt_cmd_arg, "remove");
output = run_get_stdout_with_exit_with_env(encmnt_cmd, &exit_code, encmnt_envp);
if(exit_code != 0)
ERROR("Failed to run trampoline_encmnt: %s\n", output);
g_decrypted = 0;
free(output);
}
// Make sure we're removing our symlink and not ROM's linker
if(lstat(LINKER_PATH, &info) >= 0 && S_ISLNK(info.st_mode))
remove(LINKER_PATH);
}
int encryption_cleanup(void)
{
#if MR_DEVICE_HOOKS >= 6
tramp_hook_encryption_cleanup();
#endif
remove("/vendor");
if(access("/firmware", R_OK) >= 0 && umount("/firmware") < 0)
ERROR("encryption_cleanup: failed to unmount /firmware: %s\n", strerror(errno));
rmdir("/firmware");
return 0;
}