[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
+}