Support device encryption with passphrase

This commit is contained in:
Vojtech Bocek
2015-03-02 20:58:39 +01:00
parent 87cfd90c01
commit e75092e73b
15 changed files with 156 additions and 41 deletions

View File

@@ -188,7 +188,7 @@ static void call_anim_step(call_anim *anim, float interpolated)
anim->callback(anim->data, interpolated);
}
static void anim_update(uint32_t diff, void *data)
static int anim_update(uint32_t diff, void *data)
{
struct anim_list *list = data;
struct anim_list_it *it;
@@ -275,6 +275,8 @@ static void anim_update(uint32_t diff, void *data)
list->in_update_loop = 0;
pthread_mutex_unlock(&list->mutex);
return 0;
}
static uint32_t anim_generate_id(void)

View File

@@ -143,14 +143,14 @@ int list_rm_noreorder(ptrToList list_p, void *item, callback destroy_callback_p)
return list_rm_opt(list_p, item, destroy_callback_p, 0);
}
int list_rm_at(ptrToList list_p, int idx, callback destroy_callback_p)
listItself list_rm_at(ptrToList list_p, int idx, callback destroy_callback_p)
{
void ***list = (void***)list_p;
callbackPtr destroy_callback = (callbackPtr)destroy_callback_p;
int size = list_size(*list);
if(idx < 0 || idx >= size-1)
return -1;
return NULL;
void *item = (*list)[idx];
if(destroy_callback)
@@ -161,15 +161,15 @@ int list_rm_at(ptrToList list_p, int idx, callback destroy_callback_p)
{
free(*list);
*list = NULL;
return 0;
return NULL;
}
int i = idx;
for(; i < size; ++i)
(*list)[i] = (*list)[i+1];
*list= realloc(*list, size*sizeof(item));
return 0;
*list = realloc(*list, size*sizeof(item));
return *list + idx;
}
void list_clear(ptrToList list_p, callback destroy_callback_p)
@@ -289,7 +289,7 @@ int map_find(map *m, const char *key)
for(i = 0; m->keys && m->keys[i]; ++i)
if(strcmp(m->keys[i], key) == 0)
return i;
return -1;
return -1;
}
void *map_get_val(map *m, const char *key)
@@ -367,7 +367,7 @@ int imap_find(imap *m, int key)
for(i = 0; i < m->size; ++i)
if(key == m->keys[i])
return i;
return -1;
return -1;
}
void *imap_get_val(imap *m, int key)

View File

@@ -30,7 +30,7 @@ int list_add_from_list(ptrToList list_p, listItself src_p);
int list_rm(ptrToList list_p, void *item, callback destroy_callback_p);
int list_rm_noreorder(ptrToList list_p, void *item, callback destroy_callback_p);
int list_rm_opt(ptrToList list_p, void *item, callback destroy_callback_p, int reorder);
int list_rm_at(ptrToList list_p, int idx, callback destroy_callback_p);
listItself list_rm_at(ptrToList list_p, int idx, callback destroy_callback_p); // returns pointer to the next item in list or NULL
int list_size(listItself list);
int list_item_count(listItself list);
int list_copy(ptrToList dest_p, listItself src);

View File

@@ -115,6 +115,12 @@ static int convert_ft_bitmap(FT_BitmapGlyph bit, px_type color, px_type *res_dat
buff = (uint8_t*)bit->bitmap.buffer;
res_itr = (px_type*)(((uint32_t*)res_data) + (line->offY + line->base - bit->top)*stride + (line->offX + pos->x + bit->left));
// FIXME: if bit->left is negative and everything else is 0 (e.g. letter 'j' in Roboto-Regular),
// the result might end up being before the buffer - I'm not sure how to properly handle this.
if(res_itr < res_data)
res_itr = res_data;
for(y = 0; y < bit->bitmap.rows; ++y)
{
for(x = 0; x < bit->bitmap.width; ++x)

View File

@@ -687,7 +687,7 @@ static void keyaction_call_cur_act(struct keyaction_ctx *c, int action)
ERROR("keyaction_call_cur_act: current action not found in actions!\n");
}
static void keyaction_repeat_worker(uint32_t diff, void *data)
static int keyaction_repeat_worker(uint32_t diff, void *data)
{
struct keyaction_ctx *c = data;
@@ -703,6 +703,8 @@ static void keyaction_repeat_worker(uint32_t diff, void *data)
c->repeat_timer -= diff;
}
pthread_mutex_unlock(&c->lock);
return 0;
}
void keyaction_clear_active(void)

View File

@@ -21,6 +21,7 @@
#include "keyboard.h"
#include "util.h"
#include "log.h"
#include "workers.h"
#define KS(x) ((x-1) << 16)
#define GET_KS(x) ((x & 0xFF0000)>> 16)
@@ -28,13 +29,17 @@
#define KF(x) ((x) << 8)
#define GET_KF(x) ((x & 0xFF00) >> 8)
#define KFLAG_HALF KF(0x01)
#define KFLAG_PLUS_HALF KF(0x02)
static const char *specialKeys[] = {
NULL, // OSK_EMPTY
"OK", // OSK_ENTER
"<", // OSK_BACKSPACE
"^", // OSK_SHIFT
"X", // OSK_CLEAR
"abc", // OSK_CHARSET1
"ABC", // OSK_CHARSET2
"?123",// OSK_CHARSET3
"=\\<",// OSK_CHARSET4
};
// One keycode
@@ -51,14 +56,45 @@ static const uint32_t pinKeycodeMap[] = {
// rows, cols
static const uint32_t pinKeycodeMapDimensions[] = { 4, 5 };
static const uint32_t normalKeycodeMap[] = {
static const uint32_t normalKeycodeMapCharset1[] = {
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p',
OSK_EMPTY| KFLAG_HALF, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l',
OSK_SHIFT, 'z', 'x', 'c', 'v', 'b', 'n', 'm', OSK_BACKSPACE | KS(2),
OSK_BACKSPACE, ' ' | KS(6), '.', OSK_ENTER | KS(2),
OSK_CHARSET2 | KFLAG_PLUS_HALF, 'z', 'x', 'c', 'v', 'b', 'n', 'm', OSK_BACKSPACE | KFLAG_PLUS_HALF, OSK_EMPTY,
OSK_CHARSET3 | KS(2), ' ' | KS(5), '.', OSK_ENTER | KS(2),
0
};
static const uint32_t normalKeycodeMapCharset2[] = {
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P',
OSK_EMPTY| KFLAG_HALF, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L',
OSK_CHARSET1 | KFLAG_PLUS_HALF, 'Z', 'X', 'C', 'V', 'B', 'N', 'M', OSK_BACKSPACE | KFLAG_PLUS_HALF, OSK_EMPTY,
OSK_CHARSET3 | KS(2), ' ' | KS(5), '.', OSK_ENTER | KS(2),
0
};
static const uint32_t normalKeycodeMapCharset3[] = {
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
OSK_EMPTY | KFLAG_HALF, '@', '#', '$', '%', '&', '-', '+', '(', ')',
OSK_CHARSET4 | KFLAG_PLUS_HALF, '*', '"', '\'', ':', ';', '!', '?', OSK_BACKSPACE | KFLAG_PLUS_HALF, OSK_EMPTY,
OSK_CHARSET1 | KS(2), ',', '_', ' ' | KS(3), '/', OSK_ENTER | KS(2),
0
};
static const uint32_t normalKeycodeMapCharset4[] = {
'~', '`', '|', '<', '>', '-', '+', '!', '?', ';',
OSK_EMPTY | KFLAG_HALF, '^', '\\', '$', '%', '&', '-', '+', '{', '}',
OSK_CHARSET3 | KFLAG_PLUS_HALF, '*', '"', '\'', ':', ';', '[', ']', OSK_BACKSPACE | KFLAG_PLUS_HALF, OSK_EMPTY,
OSK_CHARSET1 | KS(2), ',', ' ' | KS(4), '/', OSK_ENTER | KS(2),
0
};
static const uint32_t *normalKeycodeMapCharsetMapping[] = {
normalKeycodeMapCharset4, // OSK_CHARSET4
normalKeycodeMapCharset3, // OSK_CHARSET3
normalKeycodeMapCharset2, // OSK_CHARSET2
normalKeycodeMapCharset1, // OSK_CHARSET1
};
// rows, cols
static const uint32_t normalKeycodeMapDimensions[] = { 4, 10 };
@@ -69,15 +105,38 @@ struct keyboard_btn_data {
int btn_idx;
};
static int keyboard_init_map(struct keyboard *k, const uint32_t *map, const uint32_t *dimen);
static int keyboard_charset_switch_worker(uint32_t diff, void *data)
{
void **keyboard_bnt_data_old = NULL;
struct keyboard_btn_data *d = data;
uint8_t keycode = (d->k->keycode_map[d->btn_idx] & 0xFF);
fb_batch_start();
list_clear(&d->k->btns, &button_destroy);
list_swap(&d->k->keyboard_bnt_data, &keyboard_bnt_data_old);
keyboard_init_map(d->k, normalKeycodeMapCharsetMapping[keycode - OSK_CHARSET4], normalKeycodeMapDimensions);
fb_batch_end();
fb_request_draw();
list_clear(&keyboard_bnt_data_old, free);
return 1;
}
static void keyboard_btn_clicked(void *data)
{
struct keyboard_btn_data *d = data;
uint8_t keycode = (d->k->keycode_map[d->btn_idx] & 0xFF);
if(d->k->key_pressed)
if(keycode >= OSK_CHARSET4 && keycode <= OSK_CHARSET1)
workers_add(keyboard_charset_switch_worker, data);
else if(d->k->key_pressed)
d->k->key_pressed(d->k->key_pressed_data, keycode);
}
static int keyboard_init_map(struct keyboard *k, const uint32_t *map, const uint32_t *dimen)
int keyboard_init_map(struct keyboard *k, const uint32_t *map, const uint32_t *dimen)
{
button *btn;
int i, idx = 0;
@@ -98,6 +157,8 @@ static int keyboard_init_map(struct keyboard *k, const uint32_t *map, const uint
if(map[i] & KFLAG_HALF)
w /= 2;
else if(map[i] & KFLAG_PLUS_HALF)
w = w*1.5 + PADDING*0.5;
if(code != OSK_EMPTY)
{
@@ -116,6 +177,7 @@ static int keyboard_init_map(struct keyboard *k, const uint32_t *map, const uint
buf[0] = (map[i] & 0xFF);
button_init_ui(btn, ((int8_t)buf[0]) >= 0 ? buf : specialKeys[0xFF - (map[i] & 0xFF)], SIZE_NORMAL);
list_add(&k->btns, btn);
list_add(&k->keyboard_bnt_data, d);
}
col += GET_KS(map[i])+1;
@@ -148,7 +210,7 @@ struct keyboard *keyboard_create(int type, int x, int y, int w, int h)
break;
case KEYBOARD_NORMAL:
default:
keyboard_init_map(k, normalKeycodeMap, normalKeycodeMapDimensions);
keyboard_init_map(k, normalKeycodeMapCharset1, normalKeycodeMapDimensions);
break;
}
@@ -158,6 +220,7 @@ struct keyboard *keyboard_create(int type, int x, int y, int w, int h)
void keyboard_destroy(struct keyboard *k)
{
list_clear(&k->btns, &button_destroy);
list_clear(&k->keyboard_bnt_data, free);
free(k);
}

View File

@@ -26,14 +26,18 @@
#define OSK_EMPTY 0xFF
#define OSK_ENTER 0xFE
#define OSK_BACKSPACE 0xFD
#define OSK_SHIFT 0xFC
#define OSK_CLEAR 0xFB
#define OSK_CLEAR 0xFC
#define OSK_CHARSET1 0xFB
#define OSK_CHARSET2 0xFA
#define OSK_CHARSET3 0xF9
#define OSK_CHARSET4 0xF8
typedef void (*keyboard_on_pressed_callback)(void *data, uint8_t keycode);
struct keyboard
{
FB_ITEM_POS
button **btns;
void **keyboard_bnt_data;
const uint32_t *keycode_map;
keyboard_on_pressed_callback key_pressed;
void *key_pressed_data;

View File

@@ -37,7 +37,7 @@
#define OVERSCROLL_MARK_H (4*DPI_MUL)
#define OVERSCROLL_RETURN_SPD (10*DPI_MUL)
static void listview_bounceback(uint32_t diff, void *data)
static int listview_bounceback(uint32_t diff, void *data)
{
listview *v = (listview*)data;
const int max = v->fullH - v->h;
@@ -59,11 +59,13 @@ static void listview_bounceback(uint32_t diff, void *data)
v->overscroll_marks[0]->w = 0;
if(v->overscroll_marks[1]->w != 0)
v->overscroll_marks[1]->w = 0;
return;
return 0;
}
if(v->touch.id == -1)
listview_scroll_by(v, step);
return 0;
}
void listview_init_ui(listview *view)

View File

@@ -425,7 +425,6 @@ char *run_get_stdout_with_exit_with_env(char **cmd, int *exit_code, char *const
close(fd[0]);
waitpid(pid, exit_code, 0);
*exit_code = WEXITSTATUS(*exit_code);
if(written == 0)
{

View File

@@ -61,10 +61,12 @@ static void *worker_thread_work(void *data)
clock_gettime(CLOCK_MONOTONIC, &curr);
diff = timespec_diff(&last, &curr);
if(t->workers)
for(w = t->workers; w && *w;)
{
for(w = t->workers; *w; ++w)
(*w)->call(diff, (*w)->data);
if((*w)->call(diff, (*w)->data))
w = list_rm_at(&worker_thread.workers, w - t->workers, &free);
else
++w;
}
pthread_mutex_unlock(&t->mutex);

View File

@@ -21,7 +21,7 @@
#include <stdint.h>
#include <pthread.h>
typedef void (*worker_call)(uint32_t, void *); // ms_diff, data
typedef int (*worker_call)(uint32_t, void *); // ms_diff, data. Returns 1 if it should be removed
void workers_start(void);
void workers_stop(void);

View File

@@ -48,7 +48,7 @@ int encryption_before_mount(struct fstab *fstab)
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: %s", output);
ERROR("Failed to run trampoline_encmnt, exit code %d: %s", exit_code, output);
goto exit;
}

View File

@@ -9,7 +9,14 @@ LOCAL_SHARED_LIBRARIES := libcryptfslollipop libcutils
LOCAL_STATIC_LIBRARIES := libmultirom_static
LOCAL_WHOLE_STATIC_LIBRARIES := libm libpng libz libft2_mrom_static
mr_twrp_path := bootable/recovery
ifneq ($(wildcard bootable/recovery/crypto/lollipop/cryptfs.h),)
mr_twrp_path := bootable/recovery
else ifneq($(wildcard bootable/recovery-twrp/crypto/lollipop/cryptfs.h),)
mr_twrp_path := bootable/recovery-twrp
else
$(error Failed to find path to TWRP, which is required to build MultiROM with encryption support)
endif
LOCAL_C_INCLUDES += $(multirom_local_path) $(mr_twrp_path) $(mr_twrp_path)/crypto/scrypt/lib/crypto external/openssl/include
LOCAL_SRC_FILES := \

View File

@@ -153,6 +153,7 @@ static int handle_decrypt(int stdout_fd, const char *password)
if(de->d_type == DT_BLK && strncmp(de->d_name, "dm-", 3) == 0)
{
snprintf(buff, sizeof(buff), "/dev/block/%s\n", de->d_name);
INFO("Found block device %s", buff);
write(stdout_fd, buff, strlen(buff));
fsync(stdout_fd);
res = 0;

View File

@@ -39,6 +39,9 @@ struct pwui_type_pass_data {
fb_text *passwd_text;
fb_rect *cursor_rect;
struct keyboard *keyboard;
char *pass_buf;
char *pass_buf_stars;
size_t pass_buf_cap;
};
static pthread_mutex_t exit_code_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -112,12 +115,26 @@ static void type_pass_key_pressed(void *data, uint8_t code)
if(code < 128)
{
char *old = fb_text_get_content(d->passwd_text);
char *new_text = malloc(strlen(old)+2);
sprintf(new_text, "%s%c", old, (char)code);
fb_text_set_content(d->passwd_text, new_text);
size_t pass_len = strlen(d->pass_buf);
while(d->pass_buf_cap < pass_len + 2)
{
d->pass_buf_cap *= 2;
d->pass_buf = realloc(d->pass_buf, d->pass_buf_cap);
d->pass_buf_stars = realloc(d->pass_buf_stars, d->pass_buf_cap);
}
if(pass_len > 0)
d->pass_buf_stars[pass_len-1] = '*';
d->pass_buf_stars[pass_len] = (char)code;
d->pass_buf_stars[pass_len+1] = 0;
d->pass_buf[pass_len++] = (char)code;
d->pass_buf[pass_len] = 0;
fb_text_set_content(d->passwd_text, d->pass_buf_stars);
center_text(d->passwd_text, 0, 0, fb_width, fb_height);
free(new_text);
fb_request_draw();
return;
}
@@ -125,23 +142,26 @@ static void type_pass_key_pressed(void *data, uint8_t code)
{
case OSK_BACKSPACE:
{
char *old = fb_text_get_content(d->passwd_text);
int len = strlen(old);
if(len <= 0)
size_t pass_len = strlen(d->pass_buf);
if(pass_len == 0)
break;
char *new_text = strdup(old);
new_text[len-1] = 0;
fb_text_set_content(d->passwd_text, new_text);
d->pass_buf_stars[--pass_len] = 0;
d->pass_buf[pass_len] = 0;
fb_text_set_content(d->passwd_text, d->pass_buf_stars);
center_text(d->passwd_text, 0, 0, fb_width, fb_height);
free(new_text);
fb_request_draw();
break;
}
case OSK_CLEAR:
d->pass_buf[0] = 0;
d->pass_buf_stars[0] = 0;
fb_text_set_content(d->passwd_text, "");
fb_request_draw();
break;
case OSK_ENTER:
try_password(fb_text_get_content(d->passwd_text));
try_password(d->pass_buf);
break;
}
}
@@ -156,13 +176,20 @@ static void type_pass_init(int pwtype)
d->passwd_text = fb_add_text(0, 0, C_TEXT, SIZE_BIG, "");
center_text(d->passwd_text, 0, 0, fb_width, fb_height);
d->pass_buf_cap = 12;
d->pass_buf = mzalloc(d->pass_buf_cap);
d->pass_buf_stars = mzalloc(d->pass_buf_cap);
pwui_type_data = d;
}
static void type_pass_destroy(int pwtype)
{
struct pwui_type_pass_data *d = pwui_type_data;
keyboard_destroy(d->keyboard);
free(d->pass_buf);
free(d->pass_buf_stars);
free(d);
pwui_type_data = NULL;
}