448 lines
11 KiB
Bash
Executable File
448 lines
11 KiB
Bash
Executable File
#!/bin/bash -e
|
|
|
|
# TODO: Almost product have enabled bl32.
|
|
# AVB Config should be set in AVB tools dir.
|
|
# include keys / product id / efuse
|
|
|
|
# For flash device, encryption-system remain space should be config
|
|
###################################################
|
|
RK_SCRIPTS_DIR="${RK_SCRIPTS_DIR:-$(dirname "$(realpath "$0")")}"
|
|
RK_SDK_DIR="${RK_SDK_DIR:-$RK_SCRIPTS_DIR/../../../..}"
|
|
UBOOT=$RK_SDK_DIR/u-boot
|
|
KERNEL=$RK_SDK_DIR/kernel
|
|
BUILDROOT=$RK_SDK_DIR/buildroot
|
|
RK_SIGN_TOOL=$RK_SDK_DIR/rkbin/tools/rk_sign_tool
|
|
RK_SIGN_INI=$RK_SDK_DIR/rkbin/tools/setting.ini
|
|
RK_AVB_TOOL_DIR=$RK_SDK_DIR/tools/linux/Linux_SecurityAVB/
|
|
RK_AVB_TOOL=$RK_AVB_TOOL_DIR/avb_user_tool.sh
|
|
###################################################
|
|
# 1 -> input misc # 2 -> output misc
|
|
# 3 -> size # 4 -> enc_key
|
|
|
|
check_var_in_list()
|
|
{
|
|
echo $2 | fgrep -wq $1 && return 0 || return 1
|
|
}
|
|
|
|
assert_var_in_list()
|
|
{
|
|
if ! check_var_in_list "$@" ; then
|
|
echo -e "\e[41;1;37m$1 not in List \"$2\" -- $(basename "${BASH_SOURCE[1]}") - ${FUNCNAME[1]}\e[0m"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
rk_security_setup_misc()
|
|
{
|
|
SRC=$1
|
|
DST=$2
|
|
size=$3
|
|
buf=$4
|
|
echo buf=$buf
|
|
|
|
big_end=$[size / 256]
|
|
lit_end=$[size - (big_end * 256)]
|
|
big_end=$(echo "ibase=10;obase=16;$big_end" | bc)
|
|
lit_end=$(echo "ibase=10;obase=16;$lit_end" | bc)
|
|
|
|
IMAGE_DIR="${RK_OUTDIR:-$UBOOT}/security"
|
|
mkdir -p "$IMAGE_DIR"
|
|
IMAGE="$IMAGE_DIR/misc-security.img"
|
|
rm -rf "$IMAGE"
|
|
|
|
ln -rsLf "$SRC" "$IMAGE_DIR/misc.img"
|
|
dd if="$IMAGE_DIR/misc.img" of="$IMAGE" bs=1k count=10
|
|
echo -en "\x$lit_end\x$big_end" >> "$IMAGE"
|
|
echo -n "$buf" >> "$IMAGE"
|
|
skip=$[10 * 1024 + size + 2]
|
|
dd if="$IMAGE_DIR/misc.img" of="$IMAGE" seek=$skip skip=$skip bs=1
|
|
ln -rsf "$IMAGE" "$DST"
|
|
}
|
|
|
|
rk_security_setup_createkeys()
|
|
{
|
|
mkdir -p $UBOOT/keys
|
|
cd $UBOOT/keys
|
|
|
|
$RK_SIGN_TOOL kk --bits 2048 --out ./
|
|
|
|
ln -rsf private_key.pem dev.key
|
|
ln -rsf public_key.pem dev.pubkey
|
|
# TODO: Some rk_sign_tool may create privateKey.pem / publicKey.pem
|
|
|
|
openssl req -batch -new -x509 -key $UBOOT/keys/dev.key \
|
|
-out $UBOOT/keys/dev.crt
|
|
|
|
if [ "$1" == "system-encryption" ]; then
|
|
openssl rand -out $UBOOT/keys/system_enc_key -hex 32
|
|
fi
|
|
}
|
|
|
|
rk_security_setup_system_verity()
|
|
{
|
|
target_image=$(readlink -f $1)
|
|
outdir=$(cd $(dirname $target_image);pwd)
|
|
security_system=$outdir/security_system.img
|
|
|
|
if [ -f "$outdir/security.info" ]; then
|
|
source $outdir/security.info
|
|
if [ "$(ls -l --time-style=long-iso $target_image | cut -d ' ' -f 6,7)" == "$touch" ]; then
|
|
echo "security_system.img not be updated!!!"
|
|
return 0
|
|
fi
|
|
fi
|
|
|
|
sectors=$(ls -l "$target_image" | awk '{printf $5}')
|
|
hash_offset=$[(sectors / 1024 / 1024 + 2) * 1024 * 1024]
|
|
tmp_file=$(mktemp)
|
|
cp "$target_image" "$security_system"
|
|
veritysetup --hash-offset=$hash_offset format "$security_system" "$security_system" > $tmp_file
|
|
|
|
echo "touch=\"$(ls -l --time-style=long-iso $target_image | cut -d ' ' -f 6,7)\"" > $outdir/security.info
|
|
echo "hash_offset=$hash_offset" >> $outdir/security.info
|
|
root_hash=$(cat $tmp_file)
|
|
echo "root_hash=$(echo ${root_hash##*:})" >> $outdir/security.info
|
|
# cat "$tmp_file" >> $outdir/info
|
|
rm $tmp_file
|
|
}
|
|
|
|
rk_security_setup_system_encryption()
|
|
{
|
|
target_image=$(readlink -f $1)
|
|
outdir=$(cd $(dirname $target_image);pwd)
|
|
security_system=$outdir/security_system.img
|
|
|
|
key=$(cat $UBOOT/keys/system_enc_key)
|
|
cipher=aes-cbc-plain
|
|
|
|
if [ -f "$outdir/security.info" ]; then
|
|
source $outdir/security.info
|
|
if [ "$(ls -l --time-style=long-iso $target_image | cut -d ' ' -f 6,7)" == "$touch" ]; then
|
|
echo "security_system.img not be updated!!!"
|
|
return 0
|
|
fi
|
|
fi
|
|
|
|
sectors=$(ls -l "$target_image" | awk '{printf $5}')
|
|
sectors=$[(sectors + (1 * 1024 * 1024) - 1) / 1024 / 1024 * 2048] # Align 1M / unit: 512 bytes
|
|
|
|
loopdevice=$(sudo -S losetup -f < $UBOOT/keys/root_passwd)
|
|
mappername=encfs-$(shuf -i 1-10000000000000000000 -n 1)
|
|
dd if=/dev/null of="$security_system" seek=$sectors bs=512
|
|
|
|
sudo -S losetup $loopdevice "$security_system" < $UBOOT/keys/root_passwd
|
|
sudo -S dmsetup create $mappername --table "0 $sectors crypt $cipher $key 0 $loopdevice 0 1 allow_discards" < $UBOOT/keys/root_passwd
|
|
sudo -S dd if="$target_image" of=/dev/mapper/$mappername conv=fsync < $UBOOT/keys/root_passwd
|
|
if sync; then
|
|
cnt=1
|
|
while true; do
|
|
if [ -b "/dev/mapper/$mappername" ]; then
|
|
if [ "$cnt" -lt 10 ]; then
|
|
echo "Try to remove mapper ... $cnt"
|
|
sudo -S dmsetup remove $mappername < $UBOOT/keys/root_passwd || true
|
|
cnt=$((cnt + 1))
|
|
sleep 1
|
|
else
|
|
echo "Timeout for remove mapper:$mappername"
|
|
echo "Please remove mapper manually"
|
|
echo " sudo dmsetup remove $mappername"
|
|
echo " sudo losetup -d $loopdevice"
|
|
return -1;
|
|
fi
|
|
else
|
|
echo "Removed mapper"
|
|
break;
|
|
fi
|
|
done
|
|
fi
|
|
sudo -S losetup -d $loopdevice < $UBOOT/keys/root_passwd
|
|
|
|
echo "touch=\"$(ls -l --time-style=long-iso $target_image | cut -d ' ' -f 6,7)\"" > $outdir/security.info
|
|
echo "sectors=$sectors" >> $outdir/security.info
|
|
echo "cipher=$cipher" >> $outdir/security.info
|
|
echo "key=$key" >> $outdir/security.info
|
|
}
|
|
|
|
rk_security_setup_system()
|
|
{
|
|
case $1 in
|
|
system-verity) shift; rk_security_setup_system_verity $@ ;;
|
|
system-encryption) shift; rk_security_setup_system_encryption $@ ;;
|
|
base) ;;
|
|
*) exit -1;;
|
|
esac
|
|
}
|
|
|
|
rk_security_setup_ramboot_prebuild()
|
|
{
|
|
check_method=$1
|
|
shift
|
|
init_in=$1
|
|
shift
|
|
security_file=$1
|
|
shift
|
|
optee_storage=$1
|
|
|
|
case $check_method in
|
|
system-encryption) echo encryption ;;
|
|
system-verity) echo verity ;;
|
|
base) return ;;
|
|
*) exit -1;;
|
|
esac
|
|
|
|
if [ ! -f "$init_in" ] || [ ! -f "$security_file" ]; then
|
|
echo -e "\e[41;1;37minit_in or security_file is missed\e[0m"
|
|
exit -1
|
|
fi
|
|
|
|
init_file="$(dirname $init_in)/init"
|
|
cp $init_in $init_file
|
|
|
|
if [ "$check_method" == "system-encryption" ]; then
|
|
source "$security_file"
|
|
sed -i "s/ENC_EN=/ENC_EN=true/" "$init_file"
|
|
sed -i "s/CIPHER=/CIPHER=$cipher/" "$init_file"
|
|
sed -i "s/SECURITY_STORAGE=RPMB/SECURITY_STORAGE=$optee_storage/" "$init_file"
|
|
else
|
|
source "$security_file"
|
|
sed -i "s/ENC_EN=/ENC_EN=false/" "$init_file"
|
|
sed -i "s/^OFFSET=/OFFSET=$hash_offset/" "$init_file"
|
|
sed -i "s/HASH=/HASH=$root_hash/" "$init_file"
|
|
fi
|
|
|
|
sed -i "s/# exec busybox switch_root/exec busybox switch_root/" "$init_file"
|
|
echo "Generate ramdisk init for security"
|
|
}
|
|
|
|
rk_security_setup_sign_tool()
|
|
{
|
|
CHIP=${1: 2: 4}
|
|
|
|
${RK_SIGN_TOOL} cc --chip $CHIP
|
|
${RK_SIGN_TOOL} lk --key $UBOOT/keys/dev.key --pubkey $UBOOT/keys/dev.pubkey
|
|
|
|
if [ "$2" != "--burn-key-hash" ]; then
|
|
sed -i "/sign_flag=/s/.*/sign_flag=/" ${RK_SIGN_INI}
|
|
else
|
|
sed -i "/sign_flag=/s/.*/sign_flag=0x20/" ${RK_SIGN_INI}
|
|
fi
|
|
}
|
|
|
|
rk_security_setup_uboot_avb_sign()
|
|
{
|
|
assert_var_in_list $1 "loader uboot trust"
|
|
|
|
if [ "$3" ]; then
|
|
cp $2 $3
|
|
DST=$3
|
|
else
|
|
DST=$2
|
|
fi
|
|
|
|
case $1 in
|
|
loader) ${RK_SIGN_TOOL} sl --loader $DST;;
|
|
uboot|trust) ${RK_SIGN_TOOL} si --img $DST;;
|
|
esac
|
|
}
|
|
|
|
rk_security_setup_avb_sign()
|
|
{
|
|
assert_var_in_list $1 "boot recovery"
|
|
|
|
STAGE=$1
|
|
SRC=$(realpath $2)
|
|
DST_DIR=$3
|
|
|
|
IMAGE_DIR="${RK_OUTDIR:-$UBOOT}/security"
|
|
mkdir -p "$IMAGE_DIR"
|
|
IMAGE="$IMAGE_DIR/$STAGE-security.img"
|
|
rm -rf "$IMAGE"
|
|
|
|
cd $RK_AVB_TOOL_DIR
|
|
$RK_AVB_TOOL -s -${STAGE} $SRC
|
|
|
|
cp ${RK_AVB_TOOL_DIR}/out/${STAGE}.img ${IMAGE_DIR}/${STAGE}-security.img
|
|
[ "$STAGE" != "boot" ] || \
|
|
cp ${RK_AVB_TOOL_DIR}/out/vbmeta.img ${IMAGE_DIR}/vbmeta.img
|
|
|
|
if [ "$DST_DIR" ]; then
|
|
DST_DIR=$(realpath $DST_DIR)
|
|
ln -rsf ${IMAGE} $DST_DIR/${STAGE}.img
|
|
[ "$STAGE" != "boot" ] || \
|
|
cp ${IMAGE_DIR}/vbmeta.img $DST_DIR/vbmeta.img
|
|
fi
|
|
|
|
cd -
|
|
}
|
|
|
|
rk_security_setup_sign()
|
|
{
|
|
assert_var_in_list $1 "boot recovery"
|
|
|
|
STAGE=$1
|
|
SRC=$(realpath $2)
|
|
DST_DIR=$3
|
|
|
|
IMAGE_DIR="${RK_OUTDIR:-$UBOOT}/security"
|
|
mkdir -p "$IMAGE_DIR"
|
|
IMAGE="$IMAGE_DIR/$STAGE-security.img"
|
|
rm -rf "$IMAGE"
|
|
|
|
cd $UBOOT
|
|
ln -rsLf "$SRC" "$IMAGE_DIR/$STAGE.img"
|
|
./scripts/fit.sh --${STAGE}_img "$(realpath $IMAGE_DIR/$STAGE.img)"
|
|
mv $STAGE.img "$IMAGE"
|
|
ln -rsf ${IMAGE} $DST_DIR/${STAGE}.img
|
|
cd "${RK_SDK_DIR:-..}"
|
|
}
|
|
|
|
# -----------------------------------
|
|
# For SDK
|
|
# -----------------------------------
|
|
build_security_system()
|
|
{
|
|
if [ -z "$1" ]; then
|
|
[ "$RK_ROOTFS_SYSTEM_BUILDROOT" ] || warning "rootfs is not buildroot!"
|
|
"$RK_SCRIPTS_DIR/mk-rootfs.sh"
|
|
else
|
|
image=$(readlink -f $(pwd)/$1)
|
|
if [ ! -f "$image" ]; then
|
|
error "No found $image"
|
|
return -1
|
|
fi
|
|
|
|
"$RK_SCRIPTS_DIR/mk-security.sh" system $RK_SECURITY_CHECK_METHOD $image
|
|
fi
|
|
|
|
[ -z "$RK_SECURITY_CHECK_SYSTEM_VERITY" ] ||
|
|
"$RK_SCRIPTS_DIR/mk-security.sh" security-ramboot $@
|
|
|
|
notice "Security system has updated"
|
|
finish_build $@
|
|
}
|
|
|
|
build_security_ramboot()
|
|
{
|
|
check_config RK_SECURITY_INITRD_CFG || false
|
|
|
|
message "=========================================="
|
|
message " Start building security ramboot(buildroot) $1"
|
|
message "=========================================="
|
|
|
|
if [ -z "$1" ]; then
|
|
if [ ! -r "$RK_FIRMWARE_DIR/rootfs.img" ]; then
|
|
notice "Rootfs is not ready, building it for security..."
|
|
"$RK_SCRIPTS_DIR/mk-rootfs.sh"
|
|
fi
|
|
security_info=$RK_OUTDIR/buildroot/images/security.info
|
|
else
|
|
image=$(readlink -f $(pwd)/$1)
|
|
if [ ! -f "$image" ]; then
|
|
error "No found $image"
|
|
return -1
|
|
fi
|
|
security_info=$(dirname "$image")/security.info
|
|
fi
|
|
|
|
if [ "$RK_SECURITY_OPTEE_STORAGE_SECURITY" ]; then
|
|
OPTEE_STORAGE=SECURITY
|
|
else
|
|
OPTEE_STORAGE=RPMB
|
|
fi
|
|
|
|
"$RK_SCRIPTS_DIR/mk-security.sh" ramboot_prebuild \
|
|
$RK_SECURITY_CHECK_METHOD \
|
|
$RK_SDK_DIR/buildroot/board/rockchip/common/security-ramdisk-overlay/init.in \
|
|
$security_info $OPTEE_STORAGE
|
|
|
|
DST_DIR="$RK_OUTDIR/security-ramboot"
|
|
IMAGE_DIR="$DST_DIR/images"
|
|
|
|
"$RK_SCRIPTS_DIR/mk-buildroot.sh" $RK_SECURITY_INITRD_CFG "$IMAGE_DIR"
|
|
|
|
if [ "$RK_USE_FIT_IMG" ]; then
|
|
"$RK_SCRIPTS_DIR/mk-ramboot.sh" "$DST_DIR" \
|
|
"$IMAGE_DIR/rootfs.$RK_SECURITY_INITRD_TYPE" \
|
|
"$RK_SECURITY_FIT_ITS"
|
|
else
|
|
"$RK_SCRIPTS_DIR/mk-ramboot.sh" "$DST_DIR" \
|
|
"$IMAGE_DIR/rootfs.$RK_SECURITY_INITRD_TYPE"
|
|
fi
|
|
|
|
"$RK_SCRIPTS_DIR/mk-security.sh" sign boot \
|
|
$DST_DIR/ramboot.img $RK_FIRMWARE_DIR/
|
|
notice "Security boot.img has update in output/firmware/boot.img"
|
|
|
|
finish_build $@
|
|
}
|
|
|
|
# Hooks
|
|
|
|
BUILD_CMDS="security-createkeys security-misc security-ramboot security-system"
|
|
HID_CMDS="createkeys misc system ramboot_prebuild sign"
|
|
|
|
build_avb_sign()
|
|
{
|
|
case $1 in
|
|
loader|uboot|trust)
|
|
rk_security_setup_sign_tool $RK_CHIP \
|
|
"$(test $RK_SECURITY_BURN_KEY && \
|
|
echo --burn-key-hash || \
|
|
echo --debug-key-hash)"
|
|
rk_security_setup_uboot_avb_sign $@ ;;
|
|
recovery)
|
|
rk_security_setup_avb_sign $@ \
|
|
$[ $(rk_partition_size_kb recovery) * 1024 ];;
|
|
*)
|
|
rk_security_setup_avb_sign $@;;
|
|
esac
|
|
}
|
|
|
|
build_hook()
|
|
{
|
|
item=$1
|
|
shift
|
|
|
|
case $item in
|
|
security-createkeys)
|
|
rk_security_setup_createkeys $RK_SECURITY_CHECK_METHOD;;
|
|
security-misc)
|
|
if [ "$RK_SECURITY_CHECK_SYSTEM_ENCRYPTION" ]; then
|
|
"$RK_SCRIPTS_DIR/mk-misc.sh"
|
|
fi
|
|
;;
|
|
security-ramboot) build_security_ramboot $@;;
|
|
security-system) build_security_system $@;;
|
|
esac
|
|
|
|
echo $HID_CMDS | fgrep "$item" -wq || return 0
|
|
append=$item
|
|
|
|
case $append in
|
|
sign)
|
|
test "$RK_SECUREBOOT_AVB" && \
|
|
build_avb_sign $@ || \
|
|
rk_security_setup_$append $@
|
|
;;
|
|
*) rk_security_setup_$append $@ ;;
|
|
esac
|
|
}
|
|
|
|
usage_hook()
|
|
{
|
|
usage_oneline "security-createkeys" "create keys for security"
|
|
usage_oneline "security-misc" "build misc with system encryption key"
|
|
usage_oneline "security-ramboot[:system_image]" "build security ramboot"
|
|
usage_oneline "security-system[:system_image]" "build security system"
|
|
}
|
|
|
|
clean_hook()
|
|
{
|
|
rm -rf $RK_OUTDIR/security*
|
|
}
|
|
|
|
[ -z "$RK_SESSION" ] || \
|
|
source "${RK_BUILD_HELPER:-$(dirname "$(realpath "$0")")/build-helper}"
|
|
|
|
[ -z "$1" ] || build_hook $@
|