307 lines
9.7 KiB
Plaintext
307 lines
9.7 KiB
Plaintext
|
|
||
|
python __anonymous () {
|
||
|
depends = d.getVar("DEPENDS", True)
|
||
|
depends = "%s u-boot-mkimage-native dtc-native" % depends
|
||
|
d.setVar("DEPENDS", depends)
|
||
|
}
|
||
|
|
||
|
# 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
|
||
|
fitimage_emit_fit_conf_section() {
|
||
|
cat << EOF >> $1
|
||
|
|
||
|
configurations {
|
||
|
default = "conf@1";
|
||
|
conf@1 {
|
||
|
description = "bl";
|
||
|
kernel = "bl@1";
|
||
|
signature@1 {
|
||
|
algo = "${2},${3}";
|
||
|
key-name-hint = "${4}";
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
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)
|
||
|
|
||
|
echo "/dts-v1/; / {};" | dtc -O dtb > ${DTB}
|
||
|
uboot-mkimage -f ${FIT_ITS} -k ${KEYDIR} -K ${DTB} ${OUT}
|
||
|
dtc -I dtb ${DTB} | tail -n+2 > ${KEYDTSI}
|
||
|
|
||
|
sed "s,\/dts-v1\/;,\0\n\/include\/ \"${KEYDTSI}\"," < ${FIT_ITS} > ${KEYITS}
|
||
|
uboot-mkimage -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}"
|
||
|
|
||
|
for i in $(seq 1 8 ${#KEY_HASH}); do
|
||
|
end_i=`echo "$i+7" | bc`
|
||
|
qb=`echo ${KEY_HASH} | cut -c${i}-${end_i} | \
|
||
|
sed 's,\(..\)\(..\)\(..\)\(..\),\4\3\2\1,g'`
|
||
|
idx=`echo "${i} / 8" | bc`
|
||
|
echo "keyhash_${idx}: 0x"$qb
|
||
|
done
|
||
|
|
||
|
rm -f ${TMP_FILE}
|
||
|
}
|
||
|
|
||
|
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)
|
||
|
|
||
|
# copy raw lk binary to working directory
|
||
|
cp ${LK_OUT}/build-${LK_PROJECT}/${LK_BINARY} ${BL_BIN}
|
||
|
|
||
|
# generate a zero-size padding binary
|
||
|
touch ${PADDING}
|
||
|
|
||
|
# prepare rsa key
|
||
|
mkdir -p ${KEYDIR}
|
||
|
|
||
|
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
|
||
|
|
||
|
# generate base its file
|
||
|
fitimage_emit_fit_header ${FIT_ITS}
|
||
|
fitimage_emit_fit_image_section ${FIT_ITS} ${PADDING} ${BL_BIN} \
|
||
|
${LK_LOADADDRESS} ${LK_ENTRYPOINT} ${IMAGE_HASH_ALGO}
|
||
|
fitimage_emit_fit_conf_section ${FIT_ITS} ${SBC_HASH_ALGO} ${SBC_RSA_ALGO} dev
|
||
|
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_D=`echo "ibase=16;obase=A;${DATA_OFFSET}" | bc`
|
||
|
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}
|
||
|
|
||
|
# 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
|
||
|
}
|