From 87cfd90c012f37fa346e14b3290adf25d4aa90a8 Mon Sep 17 00:00:00 2001 From: Vojtech Bocek Date: Sun, 1 Mar 2015 22:30:53 +0100 Subject: [PATCH] Support device encryption with PIN --- install_zip/Android.mk | 4 +- lib/framebuffer.h | 1 + lib/framebuffer_truetype.c | 19 ++- lib/keyboard.c | 67 +++++---- lib/keyboard.h | 15 +- multirom_ui.c | 2 +- multirom_ui.h | 2 +- trampoline/encryption.c | 13 +- trampoline/encryption.h | 4 + trampoline/trampoline.c | 9 +- trampoline_encmnt/Android.mk | 2 + trampoline_encmnt/encmnt.c | 21 ++- trampoline_encmnt/encmnt_defines.h | 27 ++++ trampoline_encmnt/pw_ui.c | 223 ++++++++++++++++++++++++++++- 14 files changed, 365 insertions(+), 44 deletions(-) create mode 100644 trampoline_encmnt/encmnt_defines.h diff --git a/install_zip/Android.mk b/install_zip/Android.mk index 925e112..33f58f5 100644 --- a/install_zip/Android.mk +++ b/install_zip/Android.mk @@ -40,9 +40,11 @@ $(MULTIROM_ZIP_TARGET): multirom trampoline fw_mounter signapk bbootimg mrom_kex cp -a $(TARGET_OUT_OPTIONAL_EXECUTABLES)/mrom_adbd $(MULTIROM_INST_DIR)/multirom/adbd if $(MR_ENCRYPTION); then \ - mkdir -p $(MULTIROM_INST_DIR)/multirom/enc; \ + mkdir -p $(MULTIROM_INST_DIR)/multirom/enc/res; \ cp -a $(TARGET_ROOT_OUT)/trampoline_encmnt $(MULTIROM_INST_DIR)/multirom/enc/; \ cp -a $(TARGET_OUT_EXECUTABLES)/linker $(MULTIROM_INST_DIR)/multirom/enc/; \ + cp -a $(install_zip_path)/prebuilt-installer/multirom/res/Roboto-Regular.ttf $(MULTIROM_INST_DIR)/multirom/enc/res/; \ + \ cp -a $(TARGET_OUT_SHARED_LIBRARIES)/libcryptfslollipop.so $(MULTIROM_INST_DIR)/multirom/enc/; \ cp -a $(TARGET_OUT_SHARED_LIBRARIES)/libcrypto.so $(MULTIROM_INST_DIR)/multirom/enc/; \ cp -a $(TARGET_OUT_SHARED_LIBRARIES)/libc.so $(MULTIROM_INST_DIR)/multirom/enc/; \ diff --git a/lib/framebuffer.h b/lib/framebuffer.h index 72bef7f..3e74ea0 100644 --- a/lib/framebuffer.h +++ b/lib/framebuffer.h @@ -255,6 +255,7 @@ fb_img *fb_text_finalize(fb_text_proto *p); void fb_text_set_color(fb_img *img, uint32_t color); void fb_text_set_size(fb_img *img, int size); void fb_text_set_content(fb_img *img, const char *text); +char *fb_text_get_content(fb_img *img); void fb_text_drop_cache_unused(void); void fb_text_destroy(fb_img *i); diff --git a/lib/framebuffer_truetype.c b/lib/framebuffer_truetype.c index a3f32d5..2fbe174 100644 --- a/lib/framebuffer_truetype.c +++ b/lib/framebuffer_truetype.c @@ -134,7 +134,7 @@ static int convert_ft_bitmap(FT_BitmapGlyph bit, px_type color, px_type *res_dat return 0; } -static struct glyphs_entry *get_cache_for_size(const int style, const int size) +static struct glyphs_entry *get_cache_for_size(int style, const int size) { int error; struct glyphs_entry *res; @@ -152,6 +152,7 @@ static struct glyphs_entry *get_cache_for_size(const int style, const int size) if(!cache.glyphs[style]) cache.glyphs[style] = imap_create(); +retry_load: res = imap_get_val(cache.glyphs[style], size); if(!res) { @@ -161,8 +162,16 @@ static struct glyphs_entry *get_cache_for_size(const int style, const int size) error = FT_New_Face(cache.ft_lib, buff, 0, &res->face); if(error) { - ERROR("font load failed with %d\n", error); + ERROR("font style %d load failed with %d\n", style, error); free(res); + + if(style != STYLE_NORMAL) + { + ERROR("Retrying with STYLE_NORMAL instead."); + style = STYLE_NORMAL; + goto retry_load; + } + return NULL; } @@ -690,6 +699,12 @@ void fb_text_set_content(fb_img *img, const char *text) fb_items_unlock(); } +char *fb_text_get_content(fb_img *img) +{ + text_extra *ex = img->extra; + return ex->text; +} + inline void center_text(fb_img *text, int targetX, int targetY, int targetW, int targetH) { text_extra *ex = text->extra; diff --git a/lib/keyboard.c b/lib/keyboard.c index da6e347..cb2eda1 100644 --- a/lib/keyboard.c +++ b/lib/keyboard.c @@ -25,38 +25,37 @@ #define KS(x) ((x-1) << 16) #define GET_KS(x) ((x & 0xFF0000)>> 16) -#define KEY_EMPTY 0xFF -#define KEY_EMPTY_HALF 0xFE -#define KEY_ENTER 0xFD -#define KEY_CLEAR 0xFC -#define KEY_SHIFT 0xFB +#define KF(x) ((x) << 8) +#define GET_KF(x) ((x & 0xFF00) >> 8) +#define KFLAG_HALF KF(0x01) static const char *specialKeys[] = { - NULL, // KEY_EMPTY - NULL, // KEY_EMPTY_HALF - "OK", // KEY_ENTER - "X", // KEY_CLEAR + NULL, // OSK_EMPTY + "OK", // OSK_ENTER + "<", // OSK_BACKSPACE + "^", // OSK_SHIFT + "X", // OSK_CLEAR }; // One keycode // bits | 0 | 8 | 16 | // data | character | flags | colspan | static const uint32_t pinKeycodeMap[] = { - '1', '2', '3', KEY_EMPTY, - '4', '5', '6', KEY_EMPTY, - '7', '8', '9', KEY_CLEAR, - '0' | KS(3), KEY_ENTER, + OSK_EMPTY | KFLAG_HALF, '1', '2', '3', OSK_EMPTY, + OSK_EMPTY | KFLAG_HALF, '4', '5', '6', OSK_CLEAR, + OSK_EMPTY | KFLAG_HALF, '7', '8', '9', OSK_BACKSPACE, + OSK_EMPTY | KFLAG_HALF, '0' | KS(3), OSK_ENTER, 0 }; // rows, cols -static const uint32_t pinKeycodeMapDimensions[] = { 4, 4 }; +static const uint32_t pinKeycodeMapDimensions[] = { 4, 5 }; static const uint32_t normalKeycodeMap[] = { 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', - KEY_EMPTY_HALF, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', - KEY_SHIFT, 'z', 'x', 'c', 'v', 'b', 'n', 'm', KEY_CLEAR | KS(2), - KEY_CLEAR, ' ' | KS(6), '.', KEY_ENTER | KS(2), + 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), 0 }; @@ -73,7 +72,9 @@ struct keyboard_btn_data { static void keyboard_btn_clicked(void *data) { struct keyboard_btn_data *d = data; - INFO("keyboard %c pressed.", (char)(d->k->keycode_map[d->btn_idx] & 0xFF)); + uint8_t keycode = (d->k->keycode_map[d->btn_idx] & 0xFF); + 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) @@ -95,9 +96,10 @@ static int keyboard_init_map(struct keyboard *k, const uint32_t *map, const uint code = (map[i] & 0xFF); w = (GET_KS(map[i])+1)*btn_w + PADDING*GET_KS(map[i]); - if(code == KEY_EMPTY_HALF) + if(map[i] & KFLAG_HALF) w /= 2; - else if(code != KEY_EMPTY) + + if(code != OSK_EMPTY) { btn = mzalloc(sizeof(button)); btn->x = x; @@ -112,7 +114,7 @@ static int keyboard_init_map(struct keyboard *k, const uint32_t *map, const uint btn->clicked = keyboard_btn_clicked; buf[0] = (map[i] & 0xFF); - button_init_ui(btn, buf[0] >= 0 ? buf : specialKeys[0xFF - (map[i] & 0xFF)], SIZE_NORMAL); + button_init_ui(btn, ((int8_t)buf[0]) >= 0 ? buf : specialKeys[0xFF - (map[i] & 0xFF)], SIZE_NORMAL); list_add(&k->btns, btn); } @@ -131,7 +133,7 @@ static int keyboard_init_map(struct keyboard *k, const uint32_t *map, const uint return 0; } -struct keyboard *keyboard_create(int x, int y, int w, int h) +struct keyboard *keyboard_create(int type, int x, int y, int w, int h) { struct keyboard *k = mzalloc(sizeof(struct keyboard)); k->x = x; @@ -139,13 +141,28 @@ struct keyboard *keyboard_create(int x, int y, int w, int h) k->w = w; k->h = h; - //keyboard_init_map(k, pinKeycodeMap, pinKeycodeMapDimensions); - keyboard_init_map(k, normalKeycodeMap, normalKeycodeMapDimensions); + switch(type) + { + case KEYBOARD_PIN: + keyboard_init_map(k, pinKeycodeMap, pinKeycodeMapDimensions); + break; + case KEYBOARD_NORMAL: + default: + keyboard_init_map(k, normalKeycodeMap, normalKeycodeMapDimensions); + break; + } return k; } void keyboard_destroy(struct keyboard *k) { - + list_clear(&k->btns, &button_destroy); + free(k); +} + +void keyboard_set_callback(struct keyboard *k, keyboard_on_pressed_callback callback, void *data) +{ + k->key_pressed = callback; + k->key_pressed_data = data; } diff --git a/lib/keyboard.h b/lib/keyboard.h index 541f8d1..174eee0 100644 --- a/lib/keyboard.h +++ b/lib/keyboard.h @@ -23,14 +23,27 @@ #include "framebuffer.h" #include "button.h" +#define OSK_EMPTY 0xFF +#define OSK_ENTER 0xFE +#define OSK_BACKSPACE 0xFD +#define OSK_SHIFT 0xFC +#define OSK_CLEAR 0xFB + +typedef void (*keyboard_on_pressed_callback)(void *data, uint8_t keycode); struct keyboard { FB_ITEM_POS button **btns; const uint32_t *keycode_map; + keyboard_on_pressed_callback key_pressed; + void *key_pressed_data; }; -struct keyboard *keyboard_create(int x, int y, int w, int h); +#define KEYBOARD_PIN 0 +#define KEYBOARD_NORMAL 1 + +struct keyboard *keyboard_create(int type, int x, int y, int w, int h); +void keyboard_set_callback(struct keyboard *k, keyboard_on_pressed_callback callback, void *data); void keyboard_destroy(struct keyboard *k); #endif diff --git a/multirom_ui.c b/multirom_ui.c index 23a3076..9bd00ec 100644 --- a/multirom_ui.c +++ b/multirom_ui.c @@ -490,7 +490,7 @@ void multirom_ui_refresh_usb_handler(void) pthread_mutex_unlock(&exit_code_mutex); } -void multirom_ui_start_pong(int action) +void multirom_ui_start_pong(void *data) { pthread_mutex_lock(&exit_code_mutex); loop_act |= LOOP_START_PONG; diff --git a/multirom_ui.h b/multirom_ui.h index 9126cad..b9593dd 100644 --- a/multirom_ui.h +++ b/multirom_ui.h @@ -50,7 +50,7 @@ void multirom_ui_switch_btn(void *data); void multirom_ui_fill_rom_list(listview *view, int mask); void multirom_ui_auto_boot(void); void multirom_ui_refresh_usb_handler(void); -void multirom_ui_start_pong(int action); +void multirom_ui_start_pong(void *data); void multirom_ui_init_theme(int tab); void multirom_ui_destroy_theme(void); diff --git a/trampoline/encryption.c b/trampoline/encryption.c index 63c2f34..43646a1 100644 --- a/trampoline/encryption.c +++ b/trampoline/encryption.c @@ -23,6 +23,8 @@ #include "../lib/fstab.h" #include "../lib/util.h" #include "../lib/log.h" +#include "encryption.h" +#include "../trampoline_encmnt/encmnt_defines.h" static char encmnt_cmd_arg[64] = { 0 }; static char *const encmnt_cmd[] = { "/mrom_enc/trampoline_encmnt", encmnt_cmd_arg, NULL }; @@ -32,7 +34,7 @@ int encryption_before_mount(struct fstab *fstab) { int exit_code = -1; char *output = NULL, *itr; - int res = -1; + int res = ENC_RES_ERR; mkdir_recursive("/system/bin", 0755); remove("/system/bin/linker"); @@ -54,6 +56,13 @@ int encryption_before_mount(struct fstab *fstab) while(itr >= output && isspace(*itr)) *itr-- = 0; + if(strcmp(output, ENCMNT_BOOT_INTERNAL_OUTPUT) == 0) + { + INFO("trampoline_encmnt requested to boot internal ROM."); + res = ENC_RES_BOOT_INTERNAL; + goto exit; + } + if(!strstartswith(output, "/dev")) { ERROR("Invalid trampoline_encmnt output: %s", output); @@ -71,7 +80,7 @@ int encryption_before_mount(struct fstab *fstab) fstab_update_device(fstab, datap->device, output); fstab_dump(fstab); - res = 0; + res = ENC_RES_OK; exit: free(output); return res; diff --git a/trampoline/encryption.h b/trampoline/encryption.h index d25604a..ffc4934 100644 --- a/trampoline/encryption.h +++ b/trampoline/encryption.h @@ -18,6 +18,10 @@ #ifndef ENCRYPTION_H #define ENCRYPTION_H +#define ENC_RES_ERR -1 +#define ENC_RES_OK 0 +#define ENC_RES_BOOT_INTERNAL 1 + #ifdef MR_ENCRYPTION int encryption_before_mount(struct fstab *fstab); int encryption_destroy(void); diff --git a/trampoline/trampoline.c b/trampoline/trampoline.c index dd44203..f5f3c4d 100644 --- a/trampoline/trampoline.c +++ b/trampoline/trampoline.c @@ -125,8 +125,11 @@ static void mount_and_run(struct fstab *fstab) mkdir(REALDATA, 0755); - if(encryption_before_mount(fstab) < 0) + int enc_res = encryption_before_mount(fstab); + if(enc_res == ENC_RES_ERR) ERROR("Decryption failed, trying to mount anyway - might be unencrypted device."); + else if(enc_res == ENC_RES_BOOT_INTERNAL) + return; int mount_err = -1; struct fstab_part *p_itr = p; @@ -183,7 +186,7 @@ static void mount_and_run(struct fstab *fstab) return; } - //adb_init(path_multirom); + adb_init(path_multirom); run_multirom(); adb_quit(); @@ -332,7 +335,7 @@ int main(int argc, char *argv[]) #endif // REMOVE, DEBUGGING! - adb_init("/adb_sbin/"); + //adb_init("/adb_sbin/"); // mount and run multirom from sdcard mount_and_run(fstab); diff --git a/trampoline_encmnt/Android.mk b/trampoline_encmnt/Android.mk index 14d814c..89c7ce3 100644 --- a/trampoline_encmnt/Android.mk +++ b/trampoline_encmnt/Android.mk @@ -16,4 +16,6 @@ LOCAL_SRC_FILES := \ encmnt.c \ pw_ui.c \ +include $(multirom_local_path)/device_defines.mk + include $(BUILD_EXECUTABLE) diff --git a/trampoline_encmnt/encmnt.c b/trampoline_encmnt/encmnt.c index 56d24a9..8d67192 100644 --- a/trampoline_encmnt/encmnt.c +++ b/trampoline_encmnt/encmnt.c @@ -28,6 +28,7 @@ #include "crypto/lollipop/cryptfs.h" #include "pw_ui.h" +#include "encmnt_defines.h" #define CMD_NONE 0 #define CMD_DECRYPT 1 @@ -121,10 +122,22 @@ static int handle_decrypt(int stdout_fd, const char *password) return -1; } } - else if(pw_ui_run(pwtype) < 0) + else { - ERROR("pw_ui_get() failed!"); - return -1; + switch(pw_ui_run(pwtype)) + { + default: + case ENCMNT_UIRES_ERROR: + ERROR("pw_ui_run() failed!"); + return -1; + case ENCMNT_UIRES_BOOT_INTERNAL: + INFO("Wants to boot internal!"); + write(stdout_fd, ENCMNT_BOOT_INTERNAL_OUTPUT, strlen(ENCMNT_BOOT_INTERNAL_OUTPUT)); + fsync(stdout_fd); + return 0; + case ENCMNT_UIRES_PASS_OK: + break; + } } d = opendir("/dev/block/"); @@ -179,7 +192,7 @@ int main(int argc, char *argv[]) klog_set_level(6); mrom_set_log_tag("trampoline_encmnt"); - mrom_set_dir("/adb_sbin/"); + mrom_set_dir("/mrom_enc/"); for(i = 1; i < argc; ++i) { diff --git a/trampoline_encmnt/encmnt_defines.h b/trampoline_encmnt/encmnt_defines.h new file mode 100644 index 0000000..311f1f3 --- /dev/null +++ b/trampoline_encmnt/encmnt_defines.h @@ -0,0 +1,27 @@ +/* + * 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 . + */ + +#ifndef ENCMNT_DEFINES_H +#define ENCMNT_DEFINES_H + +#define ENCMNT_BOOT_INTERNAL_OUTPUT "boot-internal-requested" + +#define ENCMNT_UIRES_BOOT_INTERNAL 1 +#define ENCMNT_UIRES_PASS_OK 0 +#define ENCMNT_UIRES_ERROR -1 + +#endif diff --git a/trampoline_encmnt/pw_ui.c b/trampoline_encmnt/pw_ui.c index c344f92..87fbd38 100644 --- a/trampoline_encmnt/pw_ui.c +++ b/trampoline_encmnt/pw_ui.c @@ -16,12 +16,202 @@ */ #include +#include +#include #include "pw_ui.h" +#include "encmnt_defines.h" #include "../lib/framebuffer.h" #include "../lib/colors.h" #include "../lib/log.h" #include "../lib/input.h" +#include "../lib/keyboard.h" +#include "../lib/util.h" +#include "../lib/notification_card.h" +#include "../lib/animation.h" +#include "../lib/workers.h" + +#include "crypto/lollipop/cryptfs.h" + +#define HEADER_HEIGHT (110*DPI_MUL) + +struct pwui_type_pass_data { + fb_text *passwd_text; + fb_rect *cursor_rect; + struct keyboard *keyboard; +}; + +static pthread_mutex_t exit_code_mutex = PTHREAD_MUTEX_INITIALIZER; +static int exit_code = ENCMNT_UIRES_ERROR; +static void *pwui_type_data = NULL; +static fb_text *invalid_pass_text = NULL; +static button *boot_primary_btn = NULL; + +static void boot_internal_clicked(void *data) +{ + ncard_builder *b = ncard_create_builder(); + ncard_set_pos(b, NCARD_POS_CENTER); + ncard_set_text(b, "Booting the primary ROM..."); + ncard_show(b, 1); + + pthread_mutex_lock(&exit_code_mutex); + exit_code = ENCMNT_UIRES_BOOT_INTERNAL; + pthread_mutex_unlock(&exit_code_mutex); +} + +static void fade_rect_alpha_step(void *data, float interpolated) +{ + fb_rect *r = data; + r->color = (((int)(0xFF*interpolated)) << 24); + fb_request_draw(); +} + +static void reveal_rect_alpha_step(void *data, float interpolated) +{ + fb_rect *r = data; + interpolated = 1.f - interpolated; + r->color = (r->color & ~(0xFF << 24)) | (((int)(0xFF*interpolated)) << 24); + fb_request_draw(); +} + +static void try_password(const char *pass) +{ + fb_text_set_content(invalid_pass_text, ""); + + ncard_builder *b = ncard_create_builder(); + ncard_set_pos(b, NCARD_POS_CENTER); + ncard_set_text(b, "Verifying password..."); + ncard_show(b, 1); + + if(cryptfs_check_passwd(pass) != 0) + { + ncard_hide(); + fb_text_set_content(invalid_pass_text, "Invalid password!"); + center_text(invalid_pass_text, 0, -1, fb_width, -1); + } + else + { + ncard_builder *b = ncard_create_builder(); + ncard_set_pos(b, NCARD_POS_CENTER); + ncard_set_text(b, "Correct!"); + ncard_show(b, 1); + + fb_rect *r = fb_add_rect_lvl(10000, 0, 0, fb_width, fb_height, 0x00000000); + call_anim *a = call_anim_create(r, fade_rect_alpha_step, 500, INTERPOLATOR_ACCELERATE); + call_anim_add(a); + + pthread_mutex_lock(&exit_code_mutex); + exit_code = ENCMNT_UIRES_PASS_OK; + pthread_mutex_unlock(&exit_code_mutex); + } +} + +static void type_pass_key_pressed(void *data, uint8_t code) +{ + struct pwui_type_pass_data *d = data; + + 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); + center_text(d->passwd_text, 0, 0, fb_width, fb_height); + free(new_text); + return; + } + + switch(code) + { + case OSK_BACKSPACE: + { + char *old = fb_text_get_content(d->passwd_text); + int len = strlen(old); + if(len <= 0) + break; + + char *new_text = strdup(old); + new_text[len-1] = 0; + fb_text_set_content(d->passwd_text, new_text); + center_text(d->passwd_text, 0, 0, fb_width, fb_height); + free(new_text); + break; + } + case OSK_CLEAR: + fb_text_set_content(d->passwd_text, ""); + break; + case OSK_ENTER: + try_password(fb_text_get_content(d->passwd_text)); + break; + } +} + +static void type_pass_init(int pwtype) +{ + struct pwui_type_pass_data *d = mzalloc(sizeof(struct pwui_type_pass_data)); + d->keyboard = keyboard_create(pwtype == CRYPT_TYPE_PIN ? KEYBOARD_PIN : KEYBOARD_NORMAL, + 0, fb_height*0.65, fb_width, fb_height*0.35); + keyboard_set_callback(d->keyboard, type_pass_key_pressed, d); + + d->passwd_text = fb_add_text(0, 0, C_TEXT, SIZE_BIG, ""); + center_text(d->passwd_text, 0, 0, fb_width, fb_height); + + 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); + pwui_type_data = NULL; +} + +static void init_ui(int pwtype) +{ + fb_add_rect_lvl(100, 0, 0, fb_width, HEADER_HEIGHT, C_HIGHLIGHT_BG); + + fb_text_proto *p = fb_text_create(0, 0, C_HIGHLIGHT_TEXT, SIZE_EXTRA, "Encrypted device"); + p->level = 110; + fb_text *t = fb_text_finalize(p); + center_text(t, -1, 0, -1, HEADER_HEIGHT); + t->x = t->y; + + t = fb_add_text(0, HEADER_HEIGHT + 200*DPI_MUL, C_TEXT, SIZE_NORMAL, "Please enter your password:"); + center_text(t, 0, -1, fb_width, -1); + + invalid_pass_text = fb_add_text(0, 0, 0xFFFF0000, SIZE_BIG, ""); + center_text(invalid_pass_text, -1, HEADER_HEIGHT, -1, 200*DPI_MUL); + + boot_primary_btn = mzalloc(sizeof(button)); + boot_primary_btn->w = fb_width*0.30; + boot_primary_btn->h = HEADER_HEIGHT; + boot_primary_btn->x = fb_width - boot_primary_btn->w; + boot_primary_btn->y = 0; + boot_primary_btn->level_off = 101; + boot_primary_btn->clicked = &boot_internal_clicked; + button_init_ui(boot_primary_btn, "BOOT PRIMARY ROM", SIZE_SMALL); + + switch(pwtype) + { + case CRYPT_TYPE_PASSWORD: + case CRYPT_TYPE_PIN: + type_pass_init(pwtype); + break; + } +} + +static void destroy_ui(int pwtype) +{ + switch(pwtype) + { + case CRYPT_TYPE_PASSWORD: + case CRYPT_TYPE_PIN: + type_pass_destroy(pwtype); + break; + } + button_destroy(boot_primary_btn); +} int pw_ui_run(int pwtype) { @@ -34,17 +224,42 @@ int pw_ui_run(int pwtype) fb_freeze(1); fb_set_background(C_BACKGROUND); + workers_start(); + anim_init(1.f); + + init_ui(pwtype); + start_input_thread(); fb_freeze(0); - fb_request_draw(); + + fb_rect *r = fb_add_rect_lvl(1000, 0, 0, fb_width, fb_height, BLACK); + call_anim *a = call_anim_create(r, reveal_rect_alpha_step, 500, INTERPOLATOR_ACCELERATE); + a->on_finished_call = fb_remove_item; + a->on_finished_data = r; + call_anim_add(a); while(1) { - sleep(1); + pthread_mutex_lock(&exit_code_mutex); + const int c = exit_code; + pthread_mutex_unlock(&exit_code_mutex); + + if(c != ENCMNT_UIRES_ERROR) + break; + + usleep(100000); } - stop_input_thread(); + anim_stop(1); + fb_freeze(1); + fb_force_draw(); + stop_input_thread(); + workers_stop(); + + destroy_ui(pwtype); + + fb_clear(); fb_close(); - return -1; + return exit_code; }