[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/bsp/lk/app/blxboot/avb.c b/src/bsp/lk/app/blxboot/avb.c
new file mode 100644
index 0000000..fbeea72
--- /dev/null
+++ b/src/bsp/lk/app/blxboot/avb.c
@@ -0,0 +1,406 @@
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include <lib/bio.h>
+#include <lib/dl_commands.h>
+/* VERIFIED BOOT 2 */
+#include <libavb/libavb.h>
+#include <libavb_ab/libavb_ab.h>
+
+#include <platform/mmc_rpmb.h>
+#include <sys/types.h>
+#include <string.h>
+
+#include "blxboot_ab.h"
+
+static AvbIOResult mt_read_from_partition(AvbOps *ops,
+        const char *partition,
+        int64_t offset,
+        size_t num_bytes,
+        void *buffer,
+        size_t *out_num_read)
+{
+    bdev_t *bdev;
+    off_t part_size;
+    size_t read_bytes;
+
+    bdev = bio_open_by_label(partition) ? : bio_open(partition);
+    if (!bdev) {
+        dprintf(CRITICAL, "Partition [%s] is not exist.\n", partition);
+        return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
+    }
+
+    part_size = bdev->total_size;
+
+    if (offset < 0) {
+        if (-offset > part_size) {
+            bio_close(bdev);
+            return AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
+        }
+
+        offset += part_size;
+    }
+
+    if (offset+num_bytes > (uint64_t)part_size) {
+        bio_close(bdev);
+        return AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
+    }
+
+    read_bytes = bio_read(bdev, buffer, offset, num_bytes);
+
+    if (out_num_read != NULL)
+        *out_num_read = read_bytes;
+
+    bio_close(bdev);
+    return AVB_IO_RESULT_OK;
+}
+
+static AvbIOResult mt_write_to_partition(AvbOps *ops,
+        const char *partition,
+        int64_t offset,
+        size_t num_bytes,
+        const void *buffer)
+{
+    bdev_t *bdev;
+    off_t part_size;
+    size_t write_bytes;
+
+    bdev = bio_open_by_label(partition) ? : bio_open(partition);
+    if (!bdev) {
+        dprintf(CRITICAL, "Partition [%s] is not exist.\n", partition);
+        return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
+    }
+
+    part_size = bdev->total_size;
+
+    if (offset < 0) {
+        if (-offset > part_size) {
+            bio_close(bdev);
+            return AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
+        }
+
+        offset += part_size;
+    }
+
+    if (offset+num_bytes > (uint64_t)part_size) {
+        bio_close(bdev);
+        return AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
+    }
+
+    write_bytes = bio_write(bdev, buffer,offset, num_bytes);
+
+    if (write_bytes != num_bytes) {
+        bio_close(bdev);
+        return AVB_IO_RESULT_ERROR_IO;
+    }
+
+    bio_close(bdev);
+    return AVB_IO_RESULT_OK;
+}
+
+#ifdef AVB_ENABLE_ANTIROLLBACK
+typedef struct {
+    uint64_t rollback_indexes[AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS];
+} rollback_indexes_t;
+#define VERIDX_IN_PRMB 0
+/*antirollback index is stored in rpmb region block 1*/
+static AvbIOResult mt_read_rollback_index(AvbOps *ops,
+        size_t rollback_index_location,
+        uint64_t *out_rollback_index)
+{
+    int ret=0;
+    unsigned char blk[256] = {0};
+    ret = mmc_rpmb_block_read(VERIDX_IN_PRMB,blk);
+    if (ret != 0 ) {
+        *out_rollback_index = 0;
+        return AVB_IO_RESULT_OK;
+    }
+    rollback_indexes_t *indexes = (rollback_indexes_t *)blk;
+    *out_rollback_index=indexes->rollback_indexes[rollback_index_location];
+#if 0
+    dprintf(CRITICAL, "indexes read: %08llx %08llx %08llx %08llx\n",
+            indexes->rollback_indexes[0], indexes->rollback_indexes[1],
+            indexes->rollback_indexes[2], indexes->rollback_indexes[3]);
+#endif
+    return AVB_IO_RESULT_OK;
+}
+
+static AvbIOResult mt_write_rollback_index(AvbOps *ops,
+        size_t rollback_index_location,
+        uint64_t rollback_index)
+{
+    int ret=0;
+    unsigned char blk[256] = {0};
+    ret = mmc_rpmb_block_read(VERIDX_IN_PRMB,blk);
+    if (ret != 0 ) {
+        return AVB_IO_RESULT_ERROR_IO;
+    }
+    rollback_indexes_t *indexes = (rollback_indexes_t *)blk;
+    indexes->rollback_indexes[rollback_index_location] = rollback_index;
+#if 0
+    dprintf(CRITICAL, "indexes write: %08llx %08llx %08llx %08llx\n",
+            indexes->rollback_indexes[0], indexes->rollback_indexes[1],
+            indexes->rollback_indexes[2], indexes->rollback_indexes[3]);
+#endif
+    ret = mmc_rpmb_block_write(VERIDX_IN_PRMB,(unsigned char *)indexes);
+    if (ret != 0 ) {
+        return AVB_IO_RESULT_ERROR_IO;
+    }
+    return AVB_IO_RESULT_OK;
+}
+#else
+static AvbIOResult mt_read_rollback_index(AvbOps *ops,
+        size_t rollback_index_location,
+        uint64_t *out_rollback_index)
+{
+    *out_rollback_index = 0;
+    return AVB_IO_RESULT_OK;
+}
+
+static AvbIOResult mt_write_rollback_index(AvbOps *ops,
+        size_t rollback_index_location,
+        uint64_t rollback_index)
+{
+    return AVB_IO_RESULT_OK;
+}
+#endif
+
+#define INDEX_RPMB_UNLOCK 1
+#define AVB_DEVICE_UNLOCK 0x5a
+static AvbIOResult mt_read_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked)
+{
+    if (out_is_unlocked != NULL) {
+        *out_is_unlocked = false;
+    }
+
+#if defined(AVB_ENABLE_ANTIROLLBACK) || defined(AVB_ENABLE_DEVICE_STATE_CHANGE)
+    unsigned char blk[256]= {0};
+    int ret = -1;
+
+    ret=mmc_rpmb_block_read(INDEX_RPMB_UNLOCK,&blk[0]);
+    if (ret != 0) {
+        dprintf(CRITICAL, "mmc_rpmb_block_read fail %d.\n", ret);
+        return AVB_IO_RESULT_ERROR_IO;
+    }
+
+    if (blk[0] == AVB_DEVICE_UNLOCK)
+        *out_is_unlocked = true;
+#endif
+
+    dprintf(CRITICAL, "mt_read_is_device_unlocked return: %d.\n", *out_is_unlocked);
+
+    return AVB_IO_RESULT_OK;
+}
+
+static AvbIOResult mt_get_unique_node_for_partition(AvbOps *ops,
+        const char *partition,
+        char *guid_buf,
+        size_t guid_buf_size)
+{
+
+    strlcpy(guid_buf, "/dev/ubiblock0_0", guid_buf_size);
+    return AVB_IO_RESULT_OK;
+
+}
+static AvbIOResult mt_get_unique_guid_for_partition(AvbOps *ops,
+        const char *partition,
+        char *guid_buf,
+        size_t guid_buf_size)
+{
+    bdev_t *bdev;
+
+    bdev = bio_open_by_label(partition) ? : bio_open(partition);
+    if (!bdev) {
+        dprintf(CRITICAL, "Partition [%s] is not exist.\n", partition);
+        return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
+    }
+
+    strlcpy(guid_buf, bdev->unique_uuid, guid_buf_size);
+    bio_close(bdev);
+    return AVB_IO_RESULT_OK;
+}
+
+#include <libfdt.h>
+#include <image.h>
+extern const unsigned char blob[];
+static const unsigned char *get_pubkey_in_blob(void)
+{
+    int sig_node;
+    int noffset;
+    const void *sig_blob=&blob[0];
+    sig_node = fdt_subnode_offset(sig_blob, 0, FDT_SIG_NODE);
+    for (noffset = fdt_first_subnode(sig_blob, sig_node);
+            noffset >= 0;
+            noffset = fdt_next_subnode(sig_blob, noffset)) {
+        return (const unsigned char *)fdt_getprop(sig_blob, noffset, BLOB_MOD_NODE, NULL);
+    }
+    return NULL;
+}
+
+static AvbIOResult mt_validate_vbmeta_public_key(AvbOps *ops,
+        const uint8_t *public_key_data,
+        size_t public_key_length,
+        const uint8_t *public_key_metadata,
+        size_t public_key_metadata_length,
+        bool *out_is_trusted)
+{
+    unsigned char *pubkey_in_blob;
+    unsigned char *pubkey_in_footer;
+    AvbRSAPublicKeyHeader *header;
+
+    header = (AvbRSAPublicKeyHeader *)public_key_data;
+    pubkey_in_blob = (unsigned char *)get_pubkey_in_blob();
+    if (!pubkey_in_blob) {
+        avb_error("Public key is NULL in blob\n");
+        return AVB_IO_RESULT_ERROR_NO_SUCH_VALUE;
+    }
+    pubkey_in_footer = (unsigned char *)(public_key_data+sizeof(AvbRSAPublicKeyHeader));
+    if (memcmp(pubkey_in_blob,pubkey_in_footer,avb_be32toh(header->key_num_bits)/32)==0) {
+        *out_is_trusted = true;
+    } else {
+        *out_is_trusted = false;
+    }
+
+    return AVB_IO_RESULT_OK;
+}
+
+static AvbOps avbops;
+
+static AvbABOps avbabops = {
+    .ops = &avbops,
+
+    .read_ab_metadata = avb_ab_data_read,
+    .write_ab_metadata = avb_ab_data_write,
+};
+
+static AvbIOResult mt_get_size_of_partition(AvbOps *ops,
+        const char *partition,
+        uint64_t *out_size_num_bytes)
+{
+    bdev_t *bdev;
+
+    bdev = bio_open_by_label(partition) ? : bio_open(partition);
+    *out_size_num_bytes = (uint64_t)bdev->total_size;
+    return AVB_IO_RESULT_OK;
+}
+
+static AvbOps avbops = {
+    .ab_ops = &avbabops,
+
+    .read_from_partition = mt_read_from_partition,
+    .write_to_partition = mt_write_to_partition,
+    .validate_vbmeta_public_key = mt_validate_vbmeta_public_key,
+    .read_rollback_index = mt_read_rollback_index,
+    .write_rollback_index = mt_write_rollback_index,
+    .read_is_device_unlocked = mt_read_is_device_unlocked,
+    .get_size_of_partition = mt_get_size_of_partition,
+#ifdef BOOT_DEV_NAND
+    .get_unique_guid_for_partition = mt_get_unique_node_for_partition,
+#else
+    .get_unique_guid_for_partition = mt_get_unique_guid_for_partition,
+#endif
+};
+
+bool is_device_unlocked(void)
+{
+    AvbIOResult io_ret;
+    bool is_device_unlocked;
+    io_ret = avbops.read_is_device_unlocked(&avbops, &is_device_unlocked);
+    if (io_ret != AVB_IO_RESULT_OK) {
+        //any error treat as locked
+        return false;
+    }
+    return is_device_unlocked;
+}
+
+void *get_partition_data(const char *part_name, AvbSlotVerifyData *verifyData)
+{
+    size_t i=0;
+
+    if ((part_name == NULL) || (verifyData == NULL))
+        return NULL;
+
+    for (; i<verifyData->num_loaded_partitions; i++) {
+        if (avb_strcmp(part_name,verifyData->loaded_partitions[i].partition_name)==0) {
+            return verifyData->loaded_partitions[i].data;
+        }
+    }
+    return NULL;
+}
+
+AvbSlotVerifyResult avb_update_rollback_indexes(AvbOps *ops,AvbSlotVerifyData *verifyData)
+{
+    size_t n = 0;
+    AvbIOResult io_ret;
+    AvbSlotVerifyResult ret = AVB_SLOT_VERIFY_RESULT_OK;
+    /* Update stored rollback index such that the stored rollback index
+    * is the largest value supporting all currently bootable slots. Do
+    * this for every rollback index location.
+    */
+    for (n = 0; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
+        uint64_t rollback_index_value = 0;
+
+        rollback_index_value = verifyData->rollback_indexes[n];
+        if (rollback_index_value != 0) {
+            uint64_t current_rollback_index_value;
+            io_ret = ops->read_rollback_index(ops, n, &current_rollback_index_value);
+            if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
+                ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+                goto out;
+            } else if (io_ret != AVB_IO_RESULT_OK) {
+                avb_error("Error getting rollback index for slot.\n");
+                ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+                goto out;
+            }
+            if (current_rollback_index_value != rollback_index_value) {
+                io_ret = ops->write_rollback_index(ops, n, rollback_index_value);
+                if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
+                    ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+                    goto out;
+                } else if (io_ret != AVB_IO_RESULT_OK) {
+                    avb_error("Error setting stored rollback index.\n");
+                    ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+                    goto out;
+                }
+            }
+        }
+    }
+out:
+    return ret;
+}
+
+AvbSlotVerifyResult android_verified_boot_2_0(const char *part_name,
+                                              AvbSlotVerifyData **verifyData)
+{
+    AvbSlotVerifyResult verify_result;
+    const char *requested_partitions[] = { part_name, NULL };
+    const char *ab_suffix = get_suffix() ? : "";
+
+    verify_result = avb_slot_verify(&avbops,requested_partitions,ab_suffix,is_device_unlocked(),AVB_HASHTREE_ERROR_MODE_RESTART,verifyData);
+    dprintf(CRITICAL, "avb boot verification result is %s\n",avb_slot_verify_result_to_string(verify_result));
+    if (verify_result == AVB_SLOT_VERIFY_RESULT_OK) {
+        verify_result = avb_update_rollback_indexes(&avbops,*verifyData);
+        dprintf(CRITICAL, "avb boot rollback indexes result is %s\n",avb_slot_verify_result_to_string(verify_result));
+    }
+    return verify_result;
+}
+