summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWang Haoran <Haoran.Wang@freescale.com>2016-07-12 14:21:21 +0800
committerWang Haoran <Haoran.Wang@freescale.com>2016-07-21 12:14:21 +0800
commit22bc64d46b54e54ee58f2aece8b4ddbf9fc973e5 (patch)
treee6bd0c049ac4612f98de374a750135fa24f6b401
parentdf5b0bb553dd84cf3d417ebf5c161192a19dcc0a (diff)
downloadu-boot-imx-22bc64d46b54e54ee58f2aece8b4ddbf9fc973e5.zip
u-boot-imx-22bc64d46b54e54ee58f2aece8b4ddbf9fc973e5.tar.gz
u-boot-imx-22bc64d46b54e54ee58f2aece8b4ddbf9fc973e5.tar.bz2
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 <Haoran.Wang@freescale.com>
-rw-r--r--drivers/usb/gadget/Makefile1
-rw-r--r--drivers/usb/gadget/f_fastboot.c176
-rw-r--r--drivers/usb/gadget/fastboot_lock_unlock.c360
-rw-r--r--drivers/usb/gadget/fastboot_lock_unlock.h68
4 files changed, 600 insertions, 5 deletions
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 40de834..327574a 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
@@ -1723,18 +1730,41 @@ use_given_ptn:
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,
@@ -2171,12 +2201,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");
+ strcpy(response, "FAILValue not set");
} else if (!strcmp_l1("product", cmd)) {
strncat(response, "Freescale i.MX", chars_left);
- } else {
+ }
+#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);
}
fastboot_tx_write_str(response);
@@ -2354,6 +2395,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)
{
@@ -2367,6 +2506,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
@@ -2468,6 +2626,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",
@@ -2477,10 +2641,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 <fsl_fastboot.h>
+#include "fastboot_lock_unlock.h"
+
+#include <common.h>
+#include <linux/types.h>
+#include <part.h>
+#include <ext_common.h>
+#include <stdio_dev.h>
+
+#ifdef FASTBOOT_ENCRYPT_LOCK
+
+#include <hash.h>
+#include <fsl_caam.h>
+
+//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