[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/meta/meta-mediatek/classes/lk-image.bbclass b/meta/meta-mediatek/classes/lk-image.bbclass
new file mode 100644
index 0000000..f7e0ec6
--- /dev/null
+++ b/meta/meta-mediatek/classes/lk-image.bbclass
@@ -0,0 +1,499 @@
+inherit hsm-sign-env
+
+python __anonymous () {
+        depends = d.getVar("DEPENDS", True)
+        depends = "%s u-boot-mkimage-native dtc-native openssl-native" % depends
+        d.setVar("DEPENDS", depends)
+}
+
+# split input string to multiple quadbyte word (with 0x prefix for each word)
+# input:
+#   $1: input string, e.g., 0123456789ABCDEF...
+#   $2: "swap", to do byte swap in each quadbyte; otherwise, no swap
+# output:
+#   standard output: 0x67452301 0xEFCDAB89 ... if $2 = "swap"
+#                    0x01234567 0x89ABCDEF ... otherwise
+split_str_to_quadbytes() {
+        quadbytes=""
+
+        if [ $2 = "swap" ]; then
+                sed_cmd="sed s,\(..\)\(..\)\(..\)\(..\),\4\3\2\1,g"
+        else
+                sed_cmd="sed s,\(..\)\(..\)\(..\)\(..\),\1\2\3\4,g"
+        fi
+
+        if [ ! -z "$1" ]; then
+                for i in $(seq 1 8 ${#1}); do
+                        end_idx=`echo "${i} + 7" | bc`
+                        qb=`echo ${1} | cut -c${i}-${end_idx} | ${sed_cmd}`
+                        quadbytes="${quadbytes} 0x${qb}"
+                done
+                # trim leading space
+                awk '{$quadbytes=$quadbytes};1'
+        fi
+
+        echo $quadbytes
+}
+
+# Emit fit header
+# input param:
+#        $1: fit its
+fitimage_emit_fit_header() {
+        cat << EOF >> $1
+/dts-v1/;
+
+/ {
+        description = "bl";
+        #address-cells = <1>;
+EOF
+}
+
+# Emit the fitimage image section
+# input param:
+#        $1: fit its
+#        $2: path to padding binary
+#        $3: path to lk binary
+#        $4: lk load address
+#        $5: lk entry address
+#        $6: hash algorithm
+fitimage_emit_fit_image_section() {
+        cat << EOF >> $1
+
+        images {
+                bl@1 {
+                        description = "bl";
+                        padding = /incbin/("${2}");
+                        data = /incbin/("${3}");
+                        type = "kernel";
+                        compression = "none";
+                        load = <${4}>;
+                        entry = <${5}>;
+                        hash@1 {
+                                algo = "${6}";
+                        };
+                };
+        };
+EOF
+}
+
+# Emit fitimage configuration section
+# input param:
+#        $1: fit its
+#        $2: hash algorithm
+#        $3: rsa algorithm
+#        $4: key name hint
+#        $5: aes iv
+fitimage_emit_fit_conf_section() {
+        if [ "${ACK_EN}" = "yes" ]; then
+                # split aes iv to N 32-bit words
+                quadbytes=$(split_str_to_quadbytes ${5} noswap)
+                ack_iv_prop="ack_iv = <${quadbytes}>;"
+        else
+                ack_iv_prop=
+        fi
+
+        cat << EOF >> $1
+
+        configurations {
+                default = "conf@1";
+                conf@1 {
+                        description = "bl";
+                        kernel = "bl@1";
+                        ${ack_iv_prop}
+                        signature@1 {
+                                algo = "${2},${3}";
+                                key-name-hint = "${4}";
+                                sign-images = "kernel";
+                        };
+                };
+        };
+EOF
+}
+
+# Emit fitimage trusted-key-certificate oem section
+# input param:
+#        $1: fit its
+fitimage_emit_fit_tkc_oem_section() {
+        cat << EOF >> $1
+
+        trusted-key-certificate {
+                sign-node {
+                        device-check = "skip-device-id-check";
+                        device-id = "N0cI//dxndWXnsh11WzSKG9tPPfs";
+                        trusted-key {
+                                key-name-hint = "TierPubKey";
+                        };
+                };
+        };
+EOF
+}
+
+# Emit fitimage trusted-key-certificate tier section
+# input param:
+#        $1: fit its
+#        $2: TKC.dtsi
+fitimage_emit_fit_tkc_tier_section() {
+        cat << EOF >> $1
+
+        /include/ "$2"
+EOF
+}
+
+# Emit fitimage fit end
+# input param:
+#        $1: fit its
+fitimage_emit_fit_end() {
+        cat << EOF >> $1
+};
+EOF
+}
+
+# get_fit_data_offset: get data offset from fit image
+# input param:
+#        $1: fit image
+get_fit_data_offset() {
+        FIT_IMAGE=$1
+
+        TMPF=$(mktemp ${WORKDIR}/dump-fit-img.XXXXXX)
+
+        # dump fit image
+        fdtdump -d ${FIT_IMAGE} > ${TMPF}
+
+        # get props
+        LINE=$(grep -n '^ *data' ${TMPF} | grep -o '^[0-9]*')
+        LINE=`expr ${LINE} - 1`
+        ADDR=$(grep -n "^// [[:xdigit:]]*: value" ${TMPF} | grep "^${LINE}://" | \
+             grep -o " [[:xdigit:]]*" | grep -o "[[:xdigit:]]*")
+
+        # remove temp files
+        rm -f ${TMPF}
+
+        echo ${ADDR}
+}
+
+# check_fit_image: check fit image and also check load/entry address if 2nd
+#                  param was present
+# input param:
+#        $1: fit image
+#        $2: if present, will also check load and entry validity
+check_fit_image() {
+        FIT_IMAGE=$1
+        CHECK_OPT=$2
+
+        # check default cfg
+        CFG=$(fdtget ${FIT_IMAGE} /configurations default)
+        if [ "${CFG}" = "" ]; then
+                echo "ERROR: no default in /configurations"
+                exit 1
+        fi
+
+        # check image name
+        IMG_NAME=$(fdtget ${FIT_IMAGE} /configurations/${CFG} kernel)
+        if [ "${IMG_NAME}" = "" ]; then
+                echo "ERROR: no image name (kernel prop) in /configurations/${CFG}"
+                exit 1
+        fi
+
+        # check data
+        DATA=$(fdtget ${FIT_IMAGE} /images/${IMG_NAME} data)
+        if [ "${DATA}" = "" ]; then
+                echo "ERROR: no data in /images/${IMG_NAME}"
+                exit 1
+        fi
+
+        # check load
+        LOAD_D=$(fdtget ${FIT_IMAGE} /images/${IMG_NAME} load)
+        if [ "$LOAD_D" = "" ]; then
+                echo "ERROR: no load in /images/${IMG_NAME}"
+                exit 1
+        fi
+
+        # check entry
+        ENTRY_D=$(fdtget ${FIT_IMAGE} /images/${IMG_NAME} entry)
+        if [ "$ENTRY_D" = "" ]; then
+                echo "ERROR: no entry in /images/${IMG_NAME}"
+                exit 1
+        fi
+
+        if [ "${CHECK_OPT}" != "" ]; then
+                OFFSET=$(get_fit_data_offset ${FIT_IMAGE})
+                LOAD=$(printf "%x" ${LOAD_D})
+                if [ "`expr ${LOAD} : '.*\(....\)'`" != "${OFFSET}" ]; then
+                        echo ERROR: load ${LOAD} is not align with data offset ${OFFSET}
+                        exit 1
+                fi
+
+                LEN=$(echo ${DATA} | wc -w)
+                ENTRY=$(printf "%x" ${ENTRY_D})
+                END_D=`echo "${LOAD_D} + ${LEN} * 4" | bc`
+                END=$(printf "%x" ${END_D})
+                if [ ${ENTRY_D} -lt ${LOAD_D} -o ${END_D} -le ${ENTRY_D} ]; then
+                        echo ERROR: entry ${ENTRY} is not in data ${LOAD} - ${END}
+                        exit 1
+                fi
+        fi
+}
+
+# generate fit image: generate lk image in fit format
+# input param:
+#        $1: fit image its file
+#        $2: key dir
+#        $3: output file
+gen_fit_image() {
+        FIT_ITS=$1
+        KEYDIR=$2
+        OUT=$3
+        DTB=$(mktemp ${WORKDIR}/dtb.XXXXXX)
+        KEYDTSI=$(mktemp ${WORKDIR}/key.XXXXXX.dtsi)
+        KEYITS=$(mktemp ${WORKDIR}/key-fit-image.XXXXXX.its)
+
+        if [ "${SBC_SIGN_ALGO}" = "ecc" ]; then
+                case "${SBC_ECC_ALGO}" in
+                        nistp256)
+                                HSM_SBC_KEY=${SBC_KEY_ECC256}
+                                ;;
+                        nistp384)
+                                HSM_SBC_KEY=${SBC_KEY_ECC384}
+                                ;;
+                        nistp521)
+                                HSM_SBC_KEY=${SBC_KEY_ECC521}
+                                ;;
+                        *)
+                                echo ${SBC_ECC_ALGO} ": not supported."
+                                exit 1
+                                ;;
+                esac
+        else
+                case "${SBC_RSA_ALGO}" in
+                        rsa2048 | rsassa-pss2048)
+                                HSM_SBC_KEY=${SBC_KEY}
+                                ;;
+                        rsa3072 | rsassa-pss3072)
+                                HSM_SBC_KEY=${SBC_KEY_RSA3072}
+                                ;;
+                        rsa4096 | rsassa-pss4096)
+                                HSM_SBC_KEY=${SBC_KEY_RSA4096}
+                                ;;
+                        *)
+                                echo ${SBC_RSA_ALGO} ": not supported."
+                                exit 1
+                                ;;
+                esac
+        fi
+        echo "HSM_SBC_KEY name is ${HSM_SBC_KEY}"
+
+        echo "/dts-v1/; / {};" | dtc -O dtb > ${DTB}
+        if [ "${TKC_SUPPORT}" = "oem" ]; then
+                ${HSM_ENV} HSM_KEY_NAME=${HSM_SBC_KEY} ${FIT_IMG_TOOL} -f ${FIT_ITS} -k ${KEYDIR} -K ${DTB} -g ${TKC_PUBLIC_KEY_TIER} ${OUT}
+        elif [ "${TKC_SUPPORT}" = "tier" ]; then
+                ${HSM_ENV} HSM_KEY_NAME=${HSM_SBC_KEY} ${FIT_IMG_TOOL} -f ${FIT_ITS} -k ${KEYDIR} -K ${DTB} -u ${TKC_PUBLIC_KEY_OEM} ${OUT}
+        else
+                ${HSM_ENV} HSM_KEY_NAME=${HSM_SBC_KEY} ${FIT_IMG_TOOL} -f ${FIT_ITS} -k ${KEYDIR} -K ${DTB} ${OUT}
+        fi
+
+        dtc -I dtb ${DTB} | tail -n+2 > ${KEYDTSI}
+
+        sed "s,\/dts-v1\/;,\0\n\/include\/ \"${KEYDTSI}\"," < ${FIT_ITS} > ${KEYITS}
+        ${HSM_ENV} HSM_KEY_NAME=${HSM_SBC_KEY} ${FIT_IMG_TOOL} -f ${KEYITS} -k ${KEYDIR} ${OUT}
+
+        # remove temporary files
+        rm -f ${DTB} ${KEYDTSI} ${KEYITS}
+}
+
+# gen_sbc_key_hash
+# input param:
+#        $1: fit image
+gen_sbc_key_hash() {
+        FDT_IMG=$1
+        TMP_FILE=$(mktemp ${WORKDIR}/col_rgn.XXXXXX.bin)
+
+        DEF_CONF=`fdtget -t s ${FDT_IMG} /configurations default`
+        SIG_NODE=`fdtget -l ${FDT_IMG} /configurations/${DEF_CONF}`
+        KEY_HINT=`fdtget -t s ${FDT_IMG} /configurations/${DEF_CONF}/${SIG_NODE} key-name-hint`
+        SHAX=`fdtget -t s ${FDT_IMG} /configurations/${DEF_CONF}/${SIG_NODE} algo | cut -d, -f1`
+        ${WORKDIR}/fit-lk/extract_region ${FDT_IMG} ${TMP_FILE} /signature/key-${KEY_HINT}
+        KEY_HASH=`${SHAX}sum ${TMP_FILE} | cut -d " " -f 1`
+        echo "Hash algo: ${SHAX}"
+        echo "key_hash: ${KEY_HASH}"
+
+        key_hash_str=$(split_str_to_quadbytes ${KEY_HASH} swap)
+
+        idx=0
+        for qb in $key_hash_str; do
+                echo "keyhash_${idx}: ${qb}"
+                idx=`echo "${idx} + 1" | bc`
+        done
+
+        rm -f ${TMP_FILE}
+}
+
+# print_aes_key_iv
+#   $1: aes key
+#   $2: aes iv
+print_aes_key_iv() {
+        # print aes keys
+        echo "AES_KEY(AC_KEY)=${1}"
+        quadbytes=$(split_str_to_quadbytes ${1} swap)
+        idx=0
+        for qb in $quadbytes; do
+                echo "AC_KEY${idx}: ${qb}"
+                idx=`echo "${idx} + 1" | bc`
+        done
+
+        # print aes iv
+        echo "AES_IV=${2}"
+        quadbytes=$(split_str_to_quadbytes ${2} noswap)
+        echo "prop ack_iv=<${quadbytes}>"
+}
+
+gen_lk_fit_header() {
+        # generate temp files
+        BL_BIN=$(mktemp ${WORKDIR}/bl.XXXXXX.bin)
+        FIT_LK_IMG=${WORKDIR}/fit-lk.img
+        FIT_ITS=$(mktemp ${WORKDIR}/fit-bl-image.XXXXXX.its)
+        KEYDIR=${WORKDIR}/lk-key
+        PADDING=$(mktemp ${WORKDIR}/padding.XXXXXX.bin)
+
+        if [ "${ACK_EN}" = "yes" ]; then
+                # output AES encrypted BL image to working directory
+                openssl enc -e -aes-128-cbc -in ${LK_OUT}/build-${LK_PROJECT}/${LK_BINARY} \
+                        -out ${BL_BIN} -K ${AES_KEY} -iv ${AES_IV}
+        else
+                # copy raw lk binary to working directory
+                cp ${LK_OUT}/build-${LK_PROJECT}/${LK_BINARY} ${BL_BIN}
+        fi
+
+        # generate a zero-size padding binary
+        touch ${PADDING}
+
+        # prepare rsa key
+        mkdir -p ${KEYDIR}
+
+        if [ "${SBC_SIGN_ALGO}" = "ecc" ]; then
+                case "${SBC_ECC_ALGO}" in
+                        nistp256)
+                                cp -f ${MTK_KEY_DIR}/${SBC_KEY_ECC256}_priv.pem ${KEYDIR}/dev_priv.key
+                                cp -f ${MTK_KEY_DIR}/${SBC_KEY_ECC256}_public.pem ${KEYDIR}/dev_public.key
+                                ;;
+                        nistp384)
+                                cp -f ${MTK_KEY_DIR}/${SBC_KEY_ECC384}_priv.pem ${KEYDIR}/dev_priv.key
+                                cp -f ${MTK_KEY_DIR}/${SBC_KEY_ECC384}_public.pem ${KEYDIR}/dev_public.key
+                                ;;
+                        nistp521)
+                                cp -f ${MTK_KEY_DIR}/${SBC_KEY_ECC521}_priv.pem ${KEYDIR}/dev_priv.key
+                                cp -f ${MTK_KEY_DIR}/${SBC_KEY_ECC521}_public.pem ${KEYDIR}/dev_public.key
+                                ;;
+                        *)
+                                echo ${SBC_ECC_ALGO} ": not supported."
+                                exit 1
+                                ;;
+                esac
+        else
+                case "${SBC_RSA_ALGO}" in
+                        rsa2048 | rsassa-pss2048)
+                                cp -f ${MTK_KEY_DIR}/${SBC_KEY}.crt ${KEYDIR}/dev.crt
+                                cp -f ${MTK_KEY_DIR}/${SBC_KEY}.pem ${KEYDIR}/dev.key
+                                ;;
+                        rsa3072 | rsassa-pss3072)
+                                cp -f ${MTK_KEY_DIR}/${SBC_KEY_RSA3072}.crt ${KEYDIR}/dev.crt
+                                cp -f ${MTK_KEY_DIR}/${SBC_KEY_RSA3072}.pem ${KEYDIR}/dev.key
+                                ;;
+                        rsa4096 | rsassa-pss4096)
+                                cp -f ${MTK_KEY_DIR}/${SBC_KEY_RSA4096}.crt ${KEYDIR}/dev.crt
+                                cp -f ${MTK_KEY_DIR}/${SBC_KEY_RSA4096}.pem ${KEYDIR}/dev.key
+                                ;;
+                        *)
+                                echo ${SBC_RSA_ALGO} ": not supported."
+                                exit 1
+                                ;;
+                esac
+        fi
+
+        # key for trusted-key-certificate
+        if [ "${TKC_SUPPORT}" = "oem" ]; then
+                if [ "${SBC_SIGN_ALGO}" = "ecc" ]; then
+                        cp -f ${MTK_KEY_DIR}/${TKC_PUBLIC_KEY_TIER}.pem ${KEYDIR}/tier_public.key
+                elif [ "${SBC_SIGN_ALGO}" = "rsa" ]; then
+                        cp -f ${MTK_KEY_DIR}/${TKC_PUBLIC_KEY_TIER}.crt ${KEYDIR}/tier_public.crt
+                fi
+        elif [ "${TKC_SUPPORT}" = "tier" ]; then
+                if [ "${SBC_SIGN_ALGO}" = "ecc" ]; then
+                        cp -f ${MTK_KEY_DIR}/${TKC_PUBLIC_KEY_OEM}.pem ${KEYDIR}/oem_public.key
+                elif [ "${SBC_SIGN_ALGO}" = "rsa" ]; then
+                        cp -f ${MTK_KEY_DIR}/${TKC_PUBLIC_KEY_OEM}.crt ${KEYDIR}/oem_public.crt
+                fi
+        fi
+
+        # generate base its file
+        fitimage_emit_fit_header ${FIT_ITS}
+
+        # if TKC is supportted, place it here
+        if [ "${TKC_SUPPORT}" = "oem" ]; then
+                fitimage_emit_fit_tkc_oem_section ${FIT_ITS} ${SBC_HASH_ALGO} ${SBC_ECC_ALGO} dev
+        elif [ "${TKC_SUPPORT}" = "tier" ]; then
+                fitimage_emit_fit_tkc_tier_section ${FIT_ITS} ${MTK_KEY_DIR}/TKC.dtsi
+        fi
+
+        fitimage_emit_fit_image_section ${FIT_ITS} ${PADDING} ${BL_BIN} \
+                ${LK_LOADADDRESS} ${LK_ENTRYPOINT} ${IMAGE_HASH_ALGO}
+
+        if [ "${SBC_SIGN_ALGO}" = "ecc" ]; then
+                fitimage_emit_fit_conf_section ${FIT_ITS} ${SBC_HASH_ALGO} ${SBC_ECC_ALGO} dev ${AES_IV}
+        else
+                fitimage_emit_fit_conf_section ${FIT_ITS} ${SBC_HASH_ALGO} ${SBC_RSA_ALGO} dev ${AES_IV}
+        fi
+
+        fitimage_emit_fit_end ${FIT_ITS}
+
+        # 1st pass: generate fit-lk image to get padding size
+        gen_fit_image ${FIT_ITS} ${KEYDIR} ${FIT_LK_IMG}
+        check_fit_image ${FIT_LK_IMG}
+
+        # get data offset and calculate padding size
+        # padding size = lk load offset - data offset
+        DATA_OFFSET=$(get_fit_data_offset ${FIT_LK_IMG})
+        DATA_OFFSET_HEX=0x${DATA_OFFSET}
+        DATA_OFFSET_D=$(printf "%d" ${DATA_OFFSET_HEX})
+        LK_LOAD_OFFSET_D=$(printf "%d" ${LK_LOAD_OFFSET})
+        PADDING_SIZE=`echo "${LK_LOAD_OFFSET_D} - ${DATA_OFFSET_D}" | bc`
+
+        rm -f ${PADDING}
+        dd if=/dev/zero of=${PADDING} bs=1 count=${PADDING_SIZE}
+
+        # 2nd pass: generate final fit-lk image
+        gen_fit_image ${FIT_ITS} ${KEYDIR} ${FIT_LK_IMG}
+        check_fit_image ${FIT_LK_IMG} all
+
+        cp ${FIT_LK_IMG} ${WORKDIR}/${LK_IMAGE}
+
+        # gen key hash for convenience
+        gen_sbc_key_hash ${FIT_LK_IMG}
+
+        # output aes key and iv for reference
+        if [ "${ACK_EN}" = "yes" ]; then
+                print_aes_key_iv ${AES_KEY} ${AES_IV}
+        fi
+
+        # remove temp files
+        rm -f ${BL_BIN} ${FIT_ITS} ${PADDING}
+        rm -rf ${KEYDIR}
+}
+
+gen_lk_gfh_header() {
+        cp ${LK_OUT}/build-${LK_PROJECT}/${LK_BINARY} ${WORKDIR}/temp_gfh
+
+        if [ "${SECURE_BOOT_ENABLE}" = "yes" ]; then
+                cp ${MTK_KEY_DIR}/${SBC_KEY}.pem ${KEY_DIR}/root_prvk.pem
+        fi
+
+        python ${PBP_DIR}/pbp.py -g ${GFH_DIR}/${TARGET_PLATFORM}/gfh_conf.ini \
+               -i ${KEY_DIR}/lk_key.ini -func sign \
+               -o ${WORKDIR}/temp_gfh ${WORKDIR}/temp_gfh
+
+        if [ "${BOOTDEV_TYPE}" != "nand" ]; then
+                python ${DEV_INFO_HDR_TOOL} \
+                       ${BOOTDEV_TYPE} ${WORKDIR}/temp_gfh ${WORKDIR}/${LK_IMAGE}
+        else
+                cp ${WORKDIR}/temp_gfh ${WORKDIR}/${LK_IMAGE}
+        fi
+}