236 lines
6.3 KiB
Bash
Executable File
236 lines
6.3 KiB
Bash
Executable File
#
|
|
# Copyright (C) 2025 Amlogic, Inc. All rights reserved.
|
|
#
|
|
|
|
#!/bin/bash
|
|
|
|
EXEC_BASEDIR=$(dirname $(readlink -f $0))
|
|
BASEDIR_TOP=$(readlink -f ${EXEC_BASEDIR}/..)
|
|
VENDOR_KEYTOOL=${EXEC_BASEDIR}/../binary-tool/vendor-keytool
|
|
#
|
|
# Settings
|
|
#
|
|
VERSION=0.1
|
|
|
|
# Check file
|
|
check_file() {
|
|
if [ ! -f "$2" ]; then echo Error: Unable to open $1: \""$2"\"; exit 1 ; fi
|
|
}
|
|
|
|
# Check file is size or exit. $1: file, $2: size
|
|
check_size() {
|
|
local filesize=$(wc -c < "$1")
|
|
if [ $filesize -ne $2 ]; then
|
|
echo "Error: File \"$1\" incorrect size. Was $filesize, expected $2"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Check optional file argument exists and is given size
|
|
# $1 arg name
|
|
# $2 size
|
|
# $3 file
|
|
check_opt_file() {
|
|
if [ -n "$3" ]; then
|
|
check_file "$1" "$3"
|
|
local filesize=$(wc -c < "$3")
|
|
if [ $filesize -ne $2 ]; then
|
|
echo "Incorrect size $filesize != $2 for $1 $3"
|
|
exit 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
check_opt_boolean() {
|
|
if [ -n "$2" ]; then
|
|
if [ "$2" != "true" ] && [ "$2" != "false" ]; then
|
|
echo Error: invalid value $1: \""$2"\"
|
|
exit 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
usage() {
|
|
cat << EOF
|
|
Usage: $(basename $0) --help
|
|
$(basename $0) --version
|
|
$(basename $0) [--input base.efuse.bin] \\
|
|
[--dvuk dvuk.bin] \\
|
|
|
|
-o pattern.efuse
|
|
|
|
EOF
|
|
exit 1
|
|
}
|
|
|
|
#typedef struct{
|
|
# unsigned int nMRKType; //RDVG,EDVG,RDVU,EDVU 0x47564452, 0x47564445
|
|
# unsigned char szReserved[12]; //reserved
|
|
# unsigned char szTimeStamp[16];
|
|
# unsigned char szMRK[16];
|
|
# unsigned char szContent[32]; //80
|
|
#}t_mrk;
|
|
|
|
#typedef struct{
|
|
# unsigned char szSHA2[32];
|
|
# unsigned int nMagic; //MRKT 0X544B524D
|
|
# unsigned char byVer; //1
|
|
# unsigned char bySoC; //A1:0x2C; C1:0x30
|
|
# unsigned short nTotalSize;
|
|
# unsigned char szReserved1[8];
|
|
# unsigned char szTimeUpdate[16];
|
|
# t_mrk arrMRK[4];
|
|
#}t_mrk_table;
|
|
|
|
#define AML_MRK_TABLE_MAGIC (0x544B524D)
|
|
#define AML_MRK_RDVGK_MAGIC (0x47564452) //raw DVGK
|
|
#define AML_MRK_EDVGK_MAGIC (0x47564445) //encrypt DVGK
|
|
#define AML_MRK_RDVUK_MAGIC (0x55564452) //raw DVUK
|
|
#define AML_MRK_EDVGK_MAGIC (0x55564445) //encrypt DVUK
|
|
|
|
#enum {
|
|
# e_t_RDVGK = 0,
|
|
# e_t_EDVGK,
|
|
# e_t_RDVUK,
|
|
# e_t_EDVUK,
|
|
#};
|
|
|
|
append_uint32_le() {
|
|
local input=$1
|
|
local output=$2
|
|
local v=
|
|
local vrev=
|
|
v=$(printf %08x $input)
|
|
# 00010001
|
|
vrev=${v:6:2}${v:4:2}${v:2:2}${v:0:2}
|
|
|
|
echo $vrev | xxd -r -p >> $output
|
|
}
|
|
|
|
append_uint16_le() {
|
|
local input=$1
|
|
local output=$2
|
|
local v=
|
|
local vrev=
|
|
v=$(printf %04x $input)
|
|
# 00010001
|
|
vrev=${v:2:2}${v:0:2}
|
|
|
|
echo $vrev | xxd -r -p >> $output
|
|
}
|
|
|
|
function generate_efuse_device_pattern() {
|
|
local argv=("$@")
|
|
local i=0
|
|
|
|
local patt=$(mktemp --tmpdir)
|
|
local wrlock=$(mktemp --tmpdir)
|
|
local license0=$(mktemp --tmpdir)
|
|
local efusebit=$(mktemp --tmpdir)
|
|
local mrk_table=$(mktemp --tmpdir)
|
|
local mrk_table_hdr=$(mktemp --tmpdir)
|
|
local mrk_table_dvuk=$(mktemp --tmpdir)
|
|
local mrk_table_sha=$(mktemp --tmpdir)
|
|
local patt_final=$(mktemp --tmpdir)
|
|
|
|
# Parse args
|
|
while [ $i -lt $# ]; do
|
|
arg="${argv[$i]}"
|
|
#echo "i=$i argv[$i]=${argv[$i]}"
|
|
i=$((i + 1))
|
|
case "$arg" in
|
|
--input)
|
|
input="${argv[$i]}" ;;
|
|
-o)
|
|
output="${argv[$i]}" ;;
|
|
--dvuk)
|
|
dvuk="${argv[$i]}" ;;
|
|
*)
|
|
echo "Unknown option $arg"; exit 1
|
|
;;
|
|
esac
|
|
i=$((i + 1))
|
|
done
|
|
|
|
# Verify args
|
|
if [ -z "$output" ]; then echo Error: Missing output file option -o; exit 1; fi
|
|
|
|
check_opt_file input 1024 "$input"
|
|
check_opt_file dvuk 16 "$dvuk"
|
|
# Generate empty eFUSE pattern data
|
|
if [ -n "$input" ]; then
|
|
dd if="$input" of=$patt count=256 bs=1 &> /dev/null
|
|
dd if="$input" of=$mrk_table skip=256 bs=1 count=384 &> /dev/null
|
|
else
|
|
dd if=/dev/zero of=$patt count=256 bs=1 &> /dev/null
|
|
dd if=/dev/urandom of=$mrk_table skip=256 bs=1 count=384 &> /dev/null
|
|
fi
|
|
dd if=/dev/zero of=$patt_final count=1024 bs=1 &> /dev/null
|
|
|
|
# Construct wrlock bits
|
|
b_1d=$(xxd -ps -s29 -l1 $patt)
|
|
|
|
if [ "$dvuk" != "" ]; then
|
|
# Create mrk_table
|
|
# nMagic, byVer, bySoC, nTotalSize
|
|
dd if=/dev/zero of=$mrk_table_hdr bs=1 count=32 conv=notrunc >& /dev/null
|
|
append_uint32_le 0x544B524D $mrk_table_hdr
|
|
echo 01 | xxd -r -p >> $mrk_table_hdr
|
|
echo 2C | xxd -r -p >> $mrk_table_hdr
|
|
append_uint16_le 384 $mrk_table_hdr
|
|
dd if=/dev/urandom of=$mrk_table_hdr seek=40 bs=1 count=8 conv=notrunc &> /dev/null
|
|
echo -n "$(date +%Y%m%d%H%M%S%S)" >> $mrk_table_hdr
|
|
dd if=$mrk_table_hdr of=$mrk_table bs=1 count=64 conv=notrunc &> /dev/null
|
|
|
|
append_uint32_le 0x55564452 $mrk_table_dvuk
|
|
dd if=/dev/urandom of=$mrk_table_dvuk seek=4 bs=1 count=12 conv=notrunc &> /dev/null
|
|
echo -n "$(date +%Y%m%d%H%M%S%S)" >> $mrk_table_dvuk
|
|
dd if="$dvuk" of="$mrk_table_dvuk" bs=1 seek=32 count=16 conv=notrunc >& /dev/null
|
|
dd if=/dev/urandom of=$mrk_table_dvuk seek=48 bs=1 count=32 conv=notrunc &> /dev/null
|
|
dd if=$mrk_table_dvuk of=$mrk_table bs=1 seek=224 count=80 conv=notrunc &> /dev/null
|
|
|
|
b_1d="$(printf %02x $(( 0x$b_1d | 0x08 )))"
|
|
|
|
# Hash payload
|
|
openssl dgst -sha256 -binary $mrk_table > $mrk_table_sha
|
|
dd if=$mrk_table_sha of=$mrk_table bs=1 count=32 conv=notrunc &> /dev/null
|
|
fi
|
|
|
|
echo $b_1d | xxd -r -p > $efusebit
|
|
dd if=$efusebit of=$patt bs=1 seek=29 count=1 conv=notrunc >& /dev/null
|
|
|
|
dd if=$patt of=$patt_final bs=1 count=256 conv=notrunc >& /dev/null
|
|
dd if=$mrk_table of=$patt_final bs=1 seek=256 count=384 conv=notrunc >& /dev/null
|
|
|
|
${EXEC_BASEDIR}/aml_encrypt_a1 --efsproc --input $patt_final --output $output --option=debug
|
|
|
|
rm -f $patt
|
|
rm -f $wrlock
|
|
rm -f $license0
|
|
rm -f $efusebit
|
|
rm -f $mrk_table
|
|
rm -f $mrk_table_hdr
|
|
rm -f $mrk_table_dvuk
|
|
rm -f $mrk_table_sha
|
|
rm -f $patt_final
|
|
}
|
|
|
|
parse_main() {
|
|
case "$@" in
|
|
--help)
|
|
usage
|
|
;;
|
|
--version)
|
|
echo "$(basename $0) version $VERSION"
|
|
;;
|
|
*-o*)
|
|
generate_efuse_device_pattern "$@"
|
|
;;
|
|
*)
|
|
usage "$@"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
parse_main "$@"
|