Files
2026-08-24 10:03:24 +08:00

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 "$@"