From d7ca0b60b95ebc24128b4dccd6d8a09867ae0163 Mon Sep 17 00:00:00 2001 From: Wang Haoran Date: Tue, 12 Jul 2016 14:21:21 +0800 Subject: MA-7875-1 Support fastboot lock&unlock in u-boot Support "fastboot flashing/oem lock/unlock" command. Support "fastboot getvar secure/unlocked" command. Protect the lock/unlock status by CAAM-Keyblob. Signed-off-by: Wang Haoran --- drivers/usb/gadget/Makefile | 1 + drivers/usb/gadget/f_fastboot.c | 178 ++++++++++++++- drivers/usb/gadget/fastboot_lock_unlock.c | 360 ++++++++++++++++++++++++++++++ drivers/usb/gadget/fastboot_lock_unlock.h | 68 ++++++ 4 files changed, 602 insertions(+), 5 deletions(-) create mode 100644 drivers/usb/gadget/fastboot_lock_unlock.c create mode 100644 drivers/usb/gadget/fastboot_lock_unlock.h (limited to 'drivers') diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index ad9804a..b00e753 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_USBDOWNLOAD_GADGET) += g_dnl.o obj-$(CONFIG_DFU_FUNCTION) += f_dfu.o obj-$(CONFIG_USB_GADGET_MASS_STORAGE) += f_mass_storage.o obj-$(CONFIG_CMD_FASTBOOT) += f_fastboot.o +obj-$(CONFIG_FASTBOOT_LOCK) += fastboot_lock_unlock.o obj-$(CONFIG_BRILLO_SUPPORT) += bootctrl.o obj-$(CONFIG_BCB_SUPPORT) += command.o bcb.o endif diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c index d641ebd..6ffc1af 100644 --- a/drivers/usb/gadget/f_fastboot.c +++ b/drivers/usb/gadget/f_fastboot.c @@ -46,6 +46,13 @@ #endif #define FASTBOOT_VERSION "0.4" +#ifdef CONFIG_FASTBOOT_LOCK +#include "fastboot_lock_unlock.h" +#define FASTBOOT_VAR_SECURE "yes" +#define FASTBOOT_VAR_YES "yes" +#define FASTBOOT_VAR_NO "no" +#endif + #define FASTBOOT_INTERFACE_CLASS 0xff #define FASTBOOT_INTERFACE_SUB_CLASS 0x42 #define FASTBOOT_INTERFACE_PROTOCOL 0x03 @@ -1720,18 +1727,41 @@ int do_boota(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) addr = load_addr; +#ifdef CONFIG_FASTBOOT_LOCK + int verifyresult = -1; +#endif #ifdef CONFIG_SECURE_BOOT extern uint32_t authenticate_image(uint32_t ddr_start, uint32_t image_size); if (authenticate_image(load_addr, image_size)) { printf("Authenticate OK\n"); +#ifdef CONFIG_FASTBOOT_LOCK + verifyresult = 0; +#endif } else { printf("Authenticate image Fail, Please check\n\n"); + + /* For Android if the verify not passed we continue the boot process */ +#ifdef CONFIG_FASTBOOT_LOCK +#ifndef CONFIG_ANDROID_SUPPORT return 1; +#endif + verifyresult = 1; +#endif } #endif /*CONFIG_SECURE_BOOT*/ +#ifdef CONFIG_FASTBOOT_LOCK + int lock_status = fastboot_get_lock_stat(); + if (lock_status == FASTBOOT_LOCK_ERROR) { + printf("In boota get fastboot lock status error. Set lock status\n"); + fastboot_set_lock_stat(FASTBOOT_LOCK); + } + display_lock(fastboot_get_lock_stat(), verifyresult); +#endif + + sector = pte->start + (hdr->page_size / 512); sector += ALIGN(hdr->kernel_size, hdr->page_size) / 512; if (mmc->block_dev.block_read(mmcc, sector, @@ -2145,10 +2175,23 @@ static void cb_getvar(struct usb_ep *ep, struct usb_request *req) if (s) strncat(response, s, chars_left); else - strcpy(response, "FAILValue not set"); - } else if (!strcmp_l1("partition-type", cmd)) { - strcpy(response, "FAILVariable not implemented"); - } else { + strcpy(response, "FAILValue not set"); + } else if (!strcmp_l1("product", cmd)) { + strncat(response, "Freescale i.MX", chars_left); + } +#ifdef CONFIG_FASTBOOT_LOCK + else if (!strcmp_l1("secure", cmd)) { + strncat(response, FASTBOOT_VAR_SECURE, chars_left); + } else if (!strcmp_l1("unlocked",cmd)) { + int status = fastboot_get_lock_stat(); + if (status == FASTBOOT_UNLOCK) { + strncat(response, FASTBOOT_VAR_YES, chars_left); + } else { + strncat(response, FASTBOOT_VAR_NO, chars_left); + } + } +#endif + else { error("unknown variable: %s\n", cmd); strcpy(response, "FAILVariable not implemented"); } @@ -2327,6 +2370,104 @@ static void cb_continue(struct usb_ep *ep, struct usb_request *req) fastboot_tx_write_str("OKAY"); } +#ifdef CONFIG_FASTBOOT_LOCK + +int do_lock_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { + int status = fastboot_get_lock_stat(); + if (status != FASTBOOT_LOCK_ERROR) { + if (status == FASTBOOT_LOCK) + printf("fastboot lock status: locked.\n"); + else + printf("fastboot lock status: unlocked.\n"); + } else + printf("fastboot lock status error!\n"); + + display_lock(status, -1); + + return 0; + +} + +U_BOOT_CMD( + lock_status, 2, 1, do_lock_status, + "lock_status", + "lock_status"); + +static void cb_flashing(struct usb_ep *ep, struct usb_request *req) +{ + char *cmd = req->buf; + char response[RESPONSE_LEN]; + unsigned char len = strlen(cmd); + int status; + if (!strncmp(cmd + len - 15, "unlock_critical", 15)) { + strcpy(response, "OKAY"); + } else if (!strncmp(cmd + len - 13, "lock_critical", 13)) { + strcpy(response, "OKAY"); + } else if (!strncmp(cmd + len - 6, "unlock", 6)) { + printf("flashing unlock.\n"); + status = do_fastboot_unlock(); + if (status >= 0) + strcpy(response, "OKAY"); + else + strcpy(response, "FAIL unlock device failed."); + } else if (!strncmp(cmd + len - 4, "lock", 4)) { + printf("flashing lock.\n"); + status = do_fastboot_lock(); + if (status >= 0) + strcpy(response, "OKAY"); + else + strcpy(response, "FAIL lock device failed."); + } else { + printf("Unknown flashing command:%s\n", cmd); + strcpy(response, "FAIL command not defined"); + } + fastboot_tx_write_str(response); +} + +int do_fastboot_unlock() { + int status; + if (fastboot_lock_enable() == FASTBOOT_UL_ENABLE) { + printf("It is able to unlock device. %d\n",fastboot_lock_enable()); + status = fastboot_get_lock_stat(); + if (status == FASTBOOT_UNLOCK) { + printf("The device is already unlocked\n"); + return 1; + } + status = fastboot_set_lock_stat(FASTBOOT_UNLOCK); + if (status < 0) + return status; + + printf("Start /data wipe process....\n"); + fastboot_wipe_data_partition(); + + } else { + printf("It is not able to unlock device."); + return -1; + } + + return status; +} + +int do_fastboot_lock() { + int status; + if (status == FASTBOOT_LOCK) { + printf("The device is already locked\n"); + return 1; + } + status = fastboot_set_lock_stat(FASTBOOT_LOCK); + if (status < 0) + return status; + + printf("Start /data wipe process....\n"); + fastboot_wipe_data_partition(); + + return status; + +} + + +#endif + #ifdef CONFIG_FASTBOOT_FLASH static void cb_flash(struct usb_ep *ep, struct usb_request *req) { @@ -2340,6 +2481,25 @@ static void cb_flash(struct usb_ep *ep, struct usb_request *req) return; } +#ifdef CONFIG_FASTBOOT_LOCK + int status; + status = fastboot_get_lock_stat(); + + if (status == FASTBOOT_LOCK) { + error("device is LOCKed!\n"); + strcpy(response, "FAIL device is locked."); + fastboot_tx_write_str(response); + return; + + } else if (status == FASTBOOT_LOCK_ERROR) { + error("write lock status into device!\n"); + fastboot_set_lock_stat(FASTBOOT_LOCK); + strcpy(response, "FAIL device is locked."); + fastboot_tx_write_str(response); + return; + } +#endif + strcpy(response, "FAILno flash device defined"); #ifdef CONFIG_FSL_FASTBOOT @@ -2441,6 +2601,12 @@ static const struct cmd_dispatch_info cmd_dispatch_info[] = { .cmd = "continue", .cb = cb_continue, }, +#ifdef CONFIG_FASTBOOT_LOCK + { + .cmd = "flashing", + .cb = cb_flashing, + }, +#endif #ifdef CONFIG_FASTBOOT_FLASH { .cmd = "flash", @@ -2450,10 +2616,12 @@ static const struct cmd_dispatch_info cmd_dispatch_info[] = { .cb = cb_erase, }, #endif +#ifdef CONFIG_FASTBOOT_LOCK { .cmd = "oem", - .cb = cb_oem, + .cb = cb_flashing, }, +#endif #ifdef CONFIG_BRILLO_SUPPORT { .cmd = "set_active", diff --git a/drivers/usb/gadget/fastboot_lock_unlock.c b/drivers/usb/gadget/fastboot_lock_unlock.c new file mode 100644 index 0000000..1176f98 --- /dev/null +++ b/drivers/usb/gadget/fastboot_lock_unlock.c @@ -0,0 +1,360 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "fastboot_lock_unlock.h" + +#include +#include +#include +#include +#include + +#ifdef FASTBOOT_ENCRYPT_LOCK + +#include +#include + +//Encrypted data is 80bytes length. +#define ENDATA_LEN 80 + +#endif + + +#ifndef FASTBOOT_ENCRYPT_LOCK + +/* + * This will return FASTBOOT_LOCK, FASTBOOT_UNLOCK or FASTBOOT_ERROR + */ +inline unsigned char decrypt_lock_store(unsigned char* bdata) { + return *bdata; +} + +inline void encrypt_lock_store(unsigned char lock, unsigned char* bdata) { + *bdata = lock; +} +#else + +int sha1sum(unsigned char* data, int len, unsigned char* output) { + struct hash_algo *algo; + void *buf; + if (hash_lookup_algo("sha1", &algo)) { + printf("error in lookup sha1 algo!\n"); + return -1; + } + buf = map_sysmem(data, len); + algo->hash_func_ws(buf, len, output, algo->chunk_size); + unmap_sysmem(buf); + + return algo->digest_size; + +} + +int generate_salt(unsigned char* salt) { + unsigned long time = get_timer(0); + return sha1sum(&time, sizeof(unsigned long), salt); + +} + +unsigned char decrypt_lock_store(unsigned char *bdata) { + unsigned char plain_data[ENDATA_LEN]; + int p = 0, ret; + + caam_open(); + ret = caam_decap_blob((uint32_t)plain_data, bdata + ENDATA_LEN, ENDATA_LEN); + if (ret != 0) { + printf("Error during blob decap operation: 0x%x\n",ret); + return FASTBOOT_LOCK_ERROR; + } +#ifdef FASTBOOT_LOCK_DEBUG + DEBUG("Decrypt data block are:\n \t=======\t\n"); + for (p = 0; p < ENDATA_LEN; p++) { + DEBUG("0x%2x ", *(bdata + p)); + if (p % 16 == 0) + DEBUG("\n"); + } + DEBUG("\n \t========\t\n"); + for (p = ENDATA_LEN; p < (ENDATA_LEN + ENDATA_LEN + 48 ); p++) { + DEBUG("0x%2x ", *(bdata + p)); + if (p % 16 == 0) + DEBUG("\n"); + } + + DEBUG("\n plain text are:\n"); + for (p = 0; p < ENDATA_LEN; p++) { + DEBUG("0x%2x ", plain_data[p]); + if (p % 16 == 0) + DEBUG("\n"); + } + DEBUG("\n"); +#endif + + for (p = 0; p < ENDATA_LEN-1; p++) { + if (*(bdata+p) != plain_data[p]) { + DEBUG("Verify salt in decrypt error on pointer %d\n", p); + return FASTBOOT_LOCK_ERROR; + } + } + + return plain_data[ENDATA_LEN-1]; +} + +int encrypt_lock_store(unsigned char lock, unsigned char* bdata) { + unsigned int p = 0; + int ret; + int salt_len = generate_salt(bdata); + if (salt_len < 0) + return; + + //salt_len cannot be longer than endata block size. + if (salt_len >= ENDATA_LEN) + salt_len = ENDATA_LEN - 1; + + p = ENDATA_LEN - 1; + + //Set lock value + *(bdata + p) = lock; + + caam_open(); + ret = caam_gen_blob((uint32_t)bdata, (uint32_t)(bdata + ENDATA_LEN), ENDATA_LEN); + if (ret != 0) { + printf("error in caam_gen_blob:0x%x\n", ret); + return -1; + } + + +#ifdef FASTBOOT_LOCK_DEBUG + int i = 0; + DEBUG("encrypt plain_text:\n"); + for (i = 0; i < ENDATA_LEN; i++) { + DEBUG("0x%2x\t", *(bdata+i)); + if (i % 16 == 0) + printf("\n"); + } + printf("\nto:\n"); + for (i=0; i < ENDATA_LEN + 48; i++) { + DEBUG("0x%2x\t", *(bdata + ENDATA_LEN + i)); + if (i % 16 == 0) + printf("\n"); + } + printf("\n"); + +#endif + //protect value + *(bdata + p) = 0xff; + return 0; +} + +#endif + +static char mmc_dev_part[16]; +char* get_mmc_part(int part) { + u32 dev_no = mmc_get_env_devno(); + sprintf(mmc_dev_part,"%x:%x",dev_no, part); + return mmc_dev_part; +} + +/* + * The enabling value is stored in the last byte of target partition. + */ +inline unsigned char lock_enable_parse(unsigned char* bdata) { + DEBUG("lock_enable_parse: 0x%x\n", *(bdata + SECTOR_SIZE -1)); + return *(bdata + SECTOR_SIZE -1); +} + +/* + * Set status of the lock&unlock to FSL_FASTBOOT_FB_PART + * Currently use the very first Byte of FSL_FASTBOOT_FB_PART + * to store the fastboot lock&unlock status + */ +int fastboot_set_lock_stat(unsigned char lock) { + block_dev_desc_t *fs_dev_desc; + disk_partition_t fs_partition; + unsigned char *bdata; + + bdata = (unsigned char *)memalign(ALIGN_BYTES, SECTOR_SIZE); + memset(bdata, 0, SECTOR_SIZE); + + int status; + status = get_device_and_partition(FSL_FASTBOOT_FB_DEV, + get_mmc_part(FSL_FASTBOOT_FB_PART_NUM), + &fs_dev_desc, &fs_partition, 1); + if (!status) { + printf("%s:error in getdevice partition.\n", __FUNCTION__); + return -1; + } + DEBUG("%s %s partition.start=%d, size=%d\n",FSL_FASTBOOT_FB_DEV, + get_mmc_part(FSL_FASTBOOT_FB_PART_NUM), fs_partition.start, fs_partition.size); + + status = encrypt_lock_store(lock, bdata); + if (status < 0) + return -1; + status = fs_dev_desc->block_write(fs_dev_desc->dev, fs_partition.start, 1, bdata); + if (!status) { + printf("%s:error in block write.\n", __FUNCTION__); + return -1; + } + + + + return 0; +} + +unsigned char fastboot_get_lock_stat() { + + block_dev_desc_t *fs_dev_desc; + disk_partition_t fs_partition; + unsigned char *bdata; + + bdata = (unsigned char *)memalign(ALIGN_BYTES, SECTOR_SIZE); + + int status; + status = get_device_and_partition(FSL_FASTBOOT_FB_DEV, + get_mmc_part(FSL_FASTBOOT_FB_PART_NUM), + &fs_dev_desc, &fs_partition, 1); + + if (!status) { + printf("%s:error in getdevice partition.\n", __FUNCTION__); + return FASTBOOT_LOCK_ERROR; + } + DEBUG("%s %s partition.start=%d, size=%d\n",FSL_FASTBOOT_FB_DEV, + get_mmc_part(FSL_FASTBOOT_FB_PART_NUM), fs_partition.start, fs_partition.size); + + status = fs_dev_desc->block_read(fs_dev_desc->dev, fs_partition.start, 1, bdata); + if (!status) { + printf("%s:error in block read.\n", __FUNCTION__); + return FASTBOOT_LOCK_ERROR; + } + + return decrypt_lock_store(bdata); +} + + +/* Return the last byte of of FSL_FASTBOOT_PR_DATA + * which is managed by PresistDataService + */ + +#ifdef CONFIG_BRILLO_SUPPORT +//Brillo has no presist data partition +unsigned char fastboot_lock_enable() { + return FASTBOOT_UL_ENABLE; +} +#else +unsigned char fastboot_lock_enable() { + block_dev_desc_t *fs_dev_desc; + disk_partition_t fs_partition; + unsigned char *bdata; + + bdata = (unsigned char *)memalign(ALIGN_BYTES, SECTOR_SIZE); + + int status; + status = get_device_and_partition(FSL_FASTBOOT_FB_DEV, + get_mmc_part(FSL_FASTBOOT_PR_DATA_PART_NUM), + &fs_dev_desc, &fs_partition, 1); + if (!status) { + printf("%s:error in getdevice partition.\n", __FUNCTION__); + return FASTBOOT_UL_ERROR; + } + + //The data is stored in the last blcok of this partition. + lbaint_t target_block = fs_partition.start + fs_partition.size - 1; + DEBUG("target_block.start=%d, size=%d target_block=%d\n", fs_partition.start, fs_partition.size, target_block); + status = fs_dev_desc->block_read(fs_dev_desc->dev, target_block, 1, bdata); + if (!status) { + printf("%s: error in block read\n", __FUNCTION__); + return FASTBOOT_UL_ERROR; + } + int i = 0; + DEBUG("\n PRIST last sector is:\n"); + for (i = 0; i < SECTOR_SIZE; i++) { + DEBUG("0x%x ", *(bdata + i)); + if (i % 32 == 0) + DEBUG("\n"); + } + DEBUG("\n"); + return lock_enable_parse(bdata); + +} +#endif + +int display_lock(int lock, int verify) { + struct stdio_dev *disp; + disp = stdio_get_by_name("vga"); + if (disp != NULL) { + if (lock == FASTBOOT_UNLOCK) { + disp->puts(disp, "\n============= NOTICE ============\n"); + disp->puts(disp, "| |\n"); + disp->puts(disp, "| Your device is NOT locked. |\n"); + disp->puts(disp, "| |\n"); + disp->puts(disp, "=================================\n"); + } else { + if (verify == -1) { + disp->puts(disp, "\n============= NOTICE ============\n"); + disp->puts(disp, "| |\n"); + disp->puts(disp, "| Your device is NOT protected. |\n"); + disp->puts(disp, "| |\n"); + disp->puts(disp, "=================================\n"); + } else if (verify == 1) { + disp->puts(disp, "\n============= NOTICE ============\n"); + disp->puts(disp, "| |\n"); + disp->puts(disp, "| Boot verify failed! |\n"); + disp->puts(disp, "| |\n"); + disp->puts(disp, "=================================\n"); + } + } + return 0; + } + else + printf("not found VGA disp console.\n"); + + return -1; + +} + +int fastboot_wipe_data_partition() { + block_dev_desc_t *fs_dev_desc; + disk_partition_t fs_partition; + int status; + status = get_device_and_partition(FSL_FASTBOOT_FB_DEV, + get_mmc_part(FSL_FASTBOOT_DATA_PART_NUM), &fs_dev_desc, &fs_partition, 1); + if (!status) { + printf("error in get device partition for wipe /data\n"); + return -1; + } + DEBUG("fs->start=%x, size=%d\n", fs_partition.start, fs_partition.size); + status = fs_dev_desc->block_erase(fs_dev_desc->dev, fs_partition.start , fs_partition.size ); + if (status != fs_partition.size ) { + printf("erase not complete\n"); + return -1; + } + mdelay(2000); + + return 0; +} diff --git a/drivers/usb/gadget/fastboot_lock_unlock.h b/drivers/usb/gadget/fastboot_lock_unlock.h new file mode 100644 index 0000000..007da57 --- /dev/null +++ b/drivers/usb/gadget/fastboot_lock_unlock.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FASTBOOT_LOCK_UNLOCK_H +#define FASTBOOT_LOCK_UNLOCK_H + +#define ALIGN_BYTES 64 /*armv7 cache line need 64 bytes aligned */ + +//#define FASTBOOT_LOCK_DEBUG +#define FASTBOOT_ENCRYPT_LOCK + +#ifdef FASTBOOT_LOCK_DEBUG +#define DEBUG(format, ...) printf(format, ##__VA_ARGS__) +#else +#define DEBUG(format, ...) +#endif + +enum { + FASTBOOT_UNLOCK, + FASTBOOT_LOCK, + FASTBOOT_LOCK_ERROR, + FASTBOOT_LOCK_NUM +}; + +enum { + FASTBOOT_UL_DISABLE, + FASTBOOT_UL_ENABLE, + FASTBOOT_UL_ERROR, + FASTBOOT_UL_NUM +}; + +unsigned char fastboot_get_lock_stat(); + +int fastboot_set_lock_stat(unsigned char lock); + +int fastboot_wipe_data_partition(); + +unsigned char fastboot_lock_enable(); + +int display_lock(int lock, int verify); +#endif -- cgit v1.1