Skip to content

Commit

Permalink
a
Browse files Browse the repository at this point in the history
  • Loading branch information
bmax committed Apr 1, 2024
1 parent c314f2b commit 9c80c49
Show file tree
Hide file tree
Showing 13 changed files with 141 additions and 22 deletions.
2 changes: 1 addition & 1 deletion kernel/base/predata.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ int auth_superkey(const char *key)
sha256_init(&ctx);
sha256_update(&ctx, (const BYTE *)key, lib_strnlen(key, SUPER_KEY_LEN));
sha256_final(&ctx, hash);
int len = SHA256_BLOCK_SIZE > SUPER_KEY_HASH_LEN ? SUPER_KEY_HASH_LEN : SHA256_BLOCK_SIZE;
int len = SHA256_BLOCK_SIZE > ROOT_SUPER_KEY_HASH_LEN ? ROOT_SUPER_KEY_HASH_LEN : SHA256_BLOCK_SIZE;
rc = lib_memcmp(superkey_hash, hash, len);

return rc;
Expand Down
4 changes: 2 additions & 2 deletions kernel/base/setup1.S
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,10 @@ start_prepare:
mov x2, #SUPER_KEY_LEN
bl memcpy8

// memcpy(start_preset.superkey_hash, setup_preset.superkey_hash, SUPER_KEY_HASH_LEN);
// memcpy(start_preset.superkey_hash, setup_preset.superkey_hash, ROOT_SUPER_KEY_HASH_LEN);
add x0, x11, #start_superkey_hash_offset;
add x1, x10, #setup_superkey_hash_offset
mov x2, #SUPER_KEY_HASH_LEN
mov x2, #ROOT_SUPER_KEY_HASH_LEN
bl memcpy8

// memcpy(&start_preset.patch_symbol, &setup_preset.patch_symbol, sizeof(header.patch_symbol));
Expand Down
4 changes: 2 additions & 2 deletions kernel/base/start.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ typedef struct
int64_t map_backup_len;
uint8_t map_backup[MAP_MAX_SIZE];
uint8_t superkey[SUPER_KEY_LEN];
uint8_t superkey_hash[SUPER_KEY_HASH_LEN];
uint8_t superkey_hash[ROOT_SUPER_KEY_HASH_LEN];
patch_symbol_t patch_symbol;
} start_preset_t;
#else
Expand All @@ -39,7 +39,7 @@ typedef struct
#define start_map_backup_offset (start_map_backup_len_offset + 8)
#define start_superkey_offset (start_map_backup_offset + MAP_MAX_SIZE)
#define start_superkey_hash_offset (start_superkey_offset + SUPER_KEY_LEN)
#define start_patch_symbol_offset (start_superkey_hash_offset + SUPER_KEY_HASH_LEN)
#define start_patch_symbol_offset (start_superkey_hash_offset + ROOT_SUPER_KEY_HASH_LEN)
#define start_patch_extra_offset_offset (start_patch_symbol_offset + PATCH_SYMBOL_LEN)
#define start_patch_extra_size_offset (start_patch_extra_offset_offset + 8)
#define start_end (start_patch_extra_size_offset + 8)
Expand Down
6 changes: 3 additions & 3 deletions kernel/include/preset.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#define MAGIC_LEN 0x8
#define KP_HEADER_SIZE 0x40
#define SUPER_KEY_LEN 0x40
#define SUPER_KEY_HASH_LEN 0x20
#define ROOT_SUPER_KEY_HASH_LEN 0x20
#define SETUP_PRESERVE_LEN 0x40
#define HDR_BACKUP_SIZE 0x8
#define COMPILE_TIME_LEN 0x18
Expand Down Expand Up @@ -234,7 +234,7 @@ typedef struct _setup_preset_t
map_symbol_t map_symbol;
uint8_t header_backup[HDR_BACKUP_SIZE];
uint8_t superkey[SUPER_KEY_LEN];
uint8_t superkey_hash[SUPER_KEY_HASH_LEN];
uint8_t superkey_hash[ROOT_SUPER_KEY_HASH_LEN];
uint8_t __[SETUP_PRESERVE_LEN];
patch_symbol_t patch_symbol;
char additional[ADDITIONAL_LEN];
Expand All @@ -257,7 +257,7 @@ typedef struct _setup_preset_t
#define setup_header_backup_offset (setup_map_symbol_offset + MAP_SYMBOL_SIZE)
#define setup_superkey_offset (setup_header_backup_offset + HDR_BACKUP_SIZE)
#define setup_superkey_hash_offset (setup_superkey_offset + SUPER_KEY_LEN)
#define setup_patch_symbol_offset (setup_superkey_hash_offset + SUPER_KEY_HASH_LEN + SETUP_PRESERVE_LEN)
#define setup_patch_symbol_offset (setup_superkey_hash_offset + ROOT_SUPER_KEY_HASH_LEN + SETUP_PRESERVE_LEN)
#define setup_end (setup_patch_symbol_offset + PATCH_SYMBOL_LEN)
#endif

Expand Down
2 changes: 1 addition & 1 deletion kernel/patch/common/supercall.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ static long supercall(long cmd, long arg1, long arg2, long arg3, long arg4)
break;
case SUPERCALL_SKEY_RAND:
break;
case SUPERCALL_SKEY_TRY_HASH_AUTH:
case SUPERCALL_SKEY_ROOT_ENABLE:
break;
}

Expand Down
2 changes: 1 addition & 1 deletion kernel/patch/include/uapi/scdefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ static inline long hash_key(const char *key)
#define SUPERCALL_SKEY_GET 0x100a
#define SUPERCALL_SKEY_SET 0x100b
#define SUPERCALL_SKEY_RAND 0x100c
#define SUPERCALL_SKEY_TRY_HASH_AUTH 0x100d
#define SUPERCALL_SKEY_ROOT_ENABLE 0x100d

#define SUPERCALL_SU 0x1010
#define SUPERCALL_SU_TASK 0x1011 // syscall(__NR_gettid)
Expand Down
8 changes: 4 additions & 4 deletions tools/kptools.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ void print_usage(char **argv)
" -i, --image PATH Kernel image path.\n"
" -k, --kpimg PATH KernelPatch image path.\n"
" -s, --skey KEY Set the superkey and save it directly in the boot.img.\n"
" -S, --skey-hash KEY Consistent with (-s), but store the hash value of skey.\n"
" -S, --root-skey KEY Set the root-superkey that uses hash verification, and the superkey can be changed dynamically.\n"
" -o, --out PATH Patched image path.\n"
" -a --addition KEY=VALUE Add additional information.\n"

Expand Down Expand Up @@ -106,7 +106,7 @@ int main(int argc, char *argv[])
char *out_path = NULL;
char *superkey = NULL;
char *kpatch_path = NULL;
bool do_hash_key = false;
bool root_skey = false;

int additional_num = 0;
const char *additional[16] = { 0 };
Expand Down Expand Up @@ -138,7 +138,7 @@ int main(int argc, char *argv[])
kpimg_path = optarg;
break;
case 'S':
do_hash_key = true;
root_skey = true;
case 's':
superkey = optarg;
break;
Expand Down Expand Up @@ -190,7 +190,7 @@ int main(int argc, char *argv[])
else
fprintf(stdout, "%x\n", version);
} else if (cmd == 'p') {
ret = patch_update_img(kimg_path, kpimg_path, out_path, superkey, do_hash_key, additional, kpatch_path,
ret = patch_update_img(kimg_path, kpimg_path, out_path, superkey, root_skey, additional, kpatch_path,
extra_configs, extra_config_num);
} else if (cmd == 'd') {
ret = dump_kallsym(kimg_path);
Expand Down
14 changes: 7 additions & 7 deletions tools/patch.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,16 +150,16 @@ void print_preset_info(preset_t *preset)

// todo: remove compat version
if (ver_num > 0xa04) {
char *hexstr = bytes_to_hexstr(setup->superkey_hash, SUPER_KEY_HASH_LEN);
fprintf(stdout, "superkey_hash=%s\n", hexstr);
char *hexstr = bytes_to_hexstr(setup->superkey_hash, ROOT_SUPER_KEY_HASH_LEN);
fprintf(stdout, "root_superkey=%s\n", hexstr);
free(hexstr);
}

fprintf(stdout, INFO_ADDITIONAL_SESSION "\n");
char *addition = setup->additional;
// todo: remove compat version
if (ver_num <= 0xa04) {
addition -= (SUPER_KEY_HASH_LEN + SETUP_PRESERVE_LEN);
addition -= (ROOT_SUPER_KEY_HASH_LEN + SETUP_PRESERVE_LEN);
}
char *pos = addition;
while (pos < addition + ADDITIONAL_LEN) {
Expand Down Expand Up @@ -337,7 +337,7 @@ static void extra_append(char *kimg, const void *data, int len, int *offset)
}

int patch_update_img(const char *kimg_path, const char *kpimg_path, const char *out_path, const char *superkey,
bool hash_key, const char **additional, const char *kpatch_path, extra_config_t *extra_configs,
bool root_key, const char **additional, const char *kpatch_path, extra_config_t *extra_configs,
int extra_config_num)
{
set_log_enable(true);
Expand Down Expand Up @@ -547,19 +547,19 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char *
fillin_patch_symbol(&kallsym, kallsym_kimg, ori_kimg_len, &setup->patch_symbol, kinfo->is_be, 0);

// superkey
if (!hash_key) {
if (!root_key) {
tools_logi("superkey: %s\n", superkey);
strncpy((char *)setup->superkey, superkey, SUPER_KEY_LEN - 1);
} else {
int len = SHA256_BLOCK_SIZE > SUPER_KEY_HASH_LEN ? SUPER_KEY_HASH_LEN : SHA256_BLOCK_SIZE;
int len = SHA256_BLOCK_SIZE > ROOT_SUPER_KEY_HASH_LEN ? ROOT_SUPER_KEY_HASH_LEN : SHA256_BLOCK_SIZE;
BYTE buf[SHA256_BLOCK_SIZE];
SHA256_CTX ctx;
sha256_init(&ctx);
sha256_update(&ctx, (const BYTE *)superkey, strnlen(superkey, SUPER_KEY_LEN));
sha256_final(&ctx, buf);
memcpy(setup->superkey_hash, buf, len);
char *hexstr = bytes_to_hexstr(setup->superkey_hash, len);
tools_logi("superkey hash: %s\n", hexstr);
tools_logi("root superkey hash: %s\n", hexstr);
free(hexstr);
}

Expand Down
2 changes: 1 addition & 1 deletion tools/patch.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ uint32_t get_kpimg_version(const char *kpimg_path);
int extra_str_type(const char *extra_str);
const char *extra_type_str(extra_item_type extra_type);
int patch_update_img(const char *kimg_path, const char *kpimg_path, const char *out_path, const char *superkey,
bool hash_key, const char **additional, const char *kpatch_path, extra_config_t *extra_configs,
bool root_skey, const char **additional, const char *kpatch_path, extra_config_t *extra_configs,
int extra_config_num);
int unpatch_img(const char *kimg_path, const char *out_path);
int reset_key(const char *kimg_path, const char *out_path, const char *key);
Expand Down
81 changes: 81 additions & 0 deletions user/kpatch.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <errno.h>
#include <ctype.h>
#include <stdarg.h>
#include <error.h>

#include "supercall.h"

Expand Down Expand Up @@ -59,3 +60,83 @@ int __test(const char *key)
// return __sc_test(key, 0, 0, 0);
return sc_pid_virt_to_phys(key, getpid(), (unsigned long)__test);
}

extern const char program_name[];
extern const char *key;

static void usage(int status)
{
if (status != EXIT_SUCCESS)
fprintf(stderr, "Try `%s help' for more information.\n", program_name);
else {
printf("Usage: %s <COMMAND> [ARG]...\n\n", program_name);
fprintf(stdout, ""
"KernelPatch SuperKey manager.\n"
"\n"
"help Print this help message. \n"
"get Print current superkey.\n"
"set <SUPERKEY> Set current superkey.\n"
"rand Randomize current superkey.\n"
"root [enable|disable] Whether to use hash to verify the root superkey.\n"
"");
}
exit(status);
}

int skey_main(int argc, char **argv)
{
if (argc < 2) usage(EXIT_FAILURE);

const char *scmd = argv[1];
int cmd = -1;

struct
{
const char *scmd;
int cmd;
} cmd_arr[] = {
{ "get", SUPERCALL_SKEY_GET },
{ "set", SUPERCALL_SKEY_SET },
{ "rand", SUPERCALL_SKEY_RAND },
{ "root", SUPERCALL_SKEY_ROOT_ENABLE },
{ "help", 0 },
};

for (int i = 0; i < sizeof(cmd_arr) / sizeof(cmd_arr[0]); i++) {
if (strcmp(scmd, cmd_arr[i].scmd)) continue;
cmd = cmd_arr[i].cmd;
break;
}

if (cmd < 0) usage(EXIT_FAILURE);
char out_buf[SUPERCALL_KEY_MAX_LEN] = { '\0' };

switch (cmd) {
case SUPERCALL_SKEY_GET:
sc_skey_get(key, out_buf, sizeof(out_buf));
fprintf(stdout, "%s\n", out_buf);
break;
case SUPERCALL_SKEY_SET:
if (argc < 3) error(-EINVAL, 0, "no new superkey");
const char *new_key = argv[2];
return sc_skey_set(key, new_key);
case SUPERCALL_SKEY_RAND:
return sc_skey_rand(key);
case SUPERCALL_SKEY_ROOT_ENABLE:
if (argc < 3) error(-EINVAL, 0, "no enable or disable specified");
if (!strcmp("enable", argv[2])) {
sc_skey_root_enable(key, true);
} else if (!strcmp("disable", argv[2])) {
sc_skey_root_enable(key, false);
} else {
error(-EINVAL, 0, "no enable or disable specified");
}
break;
case 0:
usage(EXIT_SUCCESS);
default:
usage(EXIT_FAILURE);
}

return 0;
}
2 changes: 2 additions & 0 deletions user/kpatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ extern "C"
void kpv(const char *key);
void kv(const char *key);

int skey_main(int argc, char **argv);

void bootlog(const char *key);
void panic(const char *key);
int __test(const char *key);
Expand Down
6 changes: 6 additions & 0 deletions user/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ static void usage(int status)
"hello If KernelPatch installed, '%s' will echoed.\n"
"kpver Print KernelPatch version.\n"
"kver Print Kernel version.\n"
"key Manager the superkey.\n"
"su KernelPatch Substitute User.\n"
"kpm KernelPatch Module manager.\n"
#ifdef ANDROID
Expand All @@ -58,6 +59,7 @@ static void usage(int status)
exit(status);
}

// todo: refactor
int main(int argc, char **argv)
{
strcat(program_name, argv[0]);
Expand Down Expand Up @@ -93,6 +95,7 @@ int main(int argc, char **argv)
{ "hello", SUPERCALL_HELLO },
{ "kpver", SUPERCALL_KERNELPATCH_VER },
{ "kver", SUPERCALL_KERNEL_VER },
{ "key", 'K' },
{ "su", 's' },
{ "kpm", 'k' },

Expand Down Expand Up @@ -131,6 +134,9 @@ int main(int argc, char **argv)
case 's':
strcat(program_name, " su");
return su_main(argc - 2, argv + 2);
case 'K':
strcat(program_name, " key");
return skey_main(argc - 2, argv + 2);
case 'k':
strcat(program_name, " kpm");
return kpm_main(argc - 2, argv + 2);
Expand Down
30 changes: 30 additions & 0 deletions user/supercall.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,36 @@ static inline uint32_t sc_k_ver(const char *key)
return (uint32_t)ret;
}

static inline uint32_t sc_skey_get(const char *key, char *out_key, int outlen)
{
if (!key || !key[0]) return -EINVAL;
if (outlen < SUPERCALL_KEY_MAX_LEN) return -EINVAL;
long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_SKEY_GET), out_key, outlen);
return (uint32_t)ret;
}

static inline uint32_t sc_skey_set(const char *key, const char *new_key)
{
if (!key || !key[0]) return -EINVAL;
if (!new_key || !new_key[0]) return -EINVAL;
long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_SKEY_SET), new_key);
return (uint32_t)ret;
}

static inline uint32_t sc_skey_rand(const char *key)
{
if (!key || !key[0]) return -EINVAL;
long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_SKEY_RAND));
return (uint32_t)ret;
}

static inline uint32_t sc_skey_root_enable(const char *key, bool enable)
{
if (!key || !key[0]) return -EINVAL;
long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_SKEY_ROOT_ENABLE), (long)enable);
return (uint32_t)ret;
}

static inline long sc_su(const char *key, struct su_profile *profile)
{
if (!key || !key[0]) return -EINVAL;
Expand Down

0 comments on commit 9c80c49

Please sign in to comment.