📄 mkcommon.pm
字号:
{
if ($line =~ /^([0-9a-f]{8})\s+g\s+\*ABS\*\s+[0-9a-f]{8}\s+$symbol/)
{
$addr{$symbol} = hex($1);
if (scalar(values(%addr)) == scalar(@interestingSyms))
{
last READ;
}
}
}
}
close(SYMINFO);
# If we didn't see all the interesting symbols, we can only assume this app
# will be running in 29-bit mode and fall-through to using the usual P0
# masking.
if (scalar(keys(%addr)) == scalar(@interestingSyms))
{
if ($addr{".physrambase"} != ($addr{"___rambase"} &&
$addr{".physrambase"} != ($addr{"___rambase"} & 0x1FFFFFFF)))
{
# The physical RAM base is not an identity mapping or a P0 version of
# ___rambase (the usable RAM base), so we must be talking virtual memory
# and will probably have to calculate the physical address of $inAddr...
# If $inAddr is not in the range of RAM, we'll have to assume it is
# a physical address already as we can't know the physical <-> virtual
# mapping.
if (overlaps($inAddr, $inAddr + 1, $addr{"___rambase"},
$addr{"___rambase"} + $addr{"___ramsize"}))
{
$physAddr = ($inAddr - $addr{"___rambase"}) + $addr{".physrambase"};
}
}
}
}
if (!defined($physAddr))
{
$physAddr = $inAddr & 0x1FFFFFFF;
}
return $physAddr;
}
#
# Sub to read chip specific info like the boot sector gap low and high
# addresses, the Cryptocore version, and how many of the config_table entry
# fields are being signed with signed blocks from a chip info file (1st arg)
# These are returned in an array
sub getChipInfo($$;$)
{
my $chipInfoFile = shift(@_);
my $chip = shift(@_);
my $flashStart = undef;
if (@_ > 0)
{
$flashStart = shift(@_);
}
if (!(-f $chipInfoFile))
{
# When there is no chipinfo file present, don't complain, but return an
# empty list. If the values are needed we will complain later.
return ();
}
# Store values to be returned
my $host_boot_gap_low_ind = 0;
my $host_boot_gap_high_ind = 1;
my $cryptocore_version_ind = 2;
my $cte_signing_level_ind = 3;
my @retArray = ();
open(IN_FILE, $chipInfoFile) || die("could not open $chipInfoFile for " .
"reading ($!), stopped");
# Read to the correct chip
my $line;
my $atChip = 0;
while (!$atChip && ($line = <IN_FILE>))
{
if ($line =~ /^\[$chip\]/i)
{
$atChip = 1;
}
}
if ($atChip)
{
# Read host_boot_gap_low and high
while ($atChip && ($line = <IN_FILE>))
{
if ($line =~ /^\s*host_boot_gap_low\s+(0[Xx][0-9A-Fa-f]+)(\s+relative)?/)
{
$retArray[$host_boot_gap_low_ind] = hex($1);
if (defined($2) && defined ($flashStart) && $2 =~ /relative/)
{
# Gap address is relative to given $flashStart (boot gap above boot
# vector assumed).
$retArray[$host_boot_gap_low_ind] += $flashStart
}
# Must be 32 byte aligned
if ($retArray[$host_boot_gap_low_ind] % 32)
{
die("host_boot_gap_low for $chip in $chipInfoFile must be 32 byte aligned, stopped");
}
}
elsif ($line =~ /^\s*host_boot_gap_high\s+(0[Xx][0-9A-Fa-f]+)(\s+relative)?/)
{
$retArray[$host_boot_gap_high_ind] = hex($1);
if (defined($2) && defined ($flashStart) && $2 =~ /relative/)
{
# Gap address is relative to given $flashStart (boot gap above boot
# vector assumed).
$retArray[$host_boot_gap_high_ind] += $flashStart;
}
# Must be 32 byte aligned
if ($retArray[$host_boot_gap_high_ind] % 32)
{
die("host_boot_gap_high for $chip in $chipInfoFile must be 32 byte aligned, stopped");
}
}
elsif ($line =~ /^cryptocore_version\s+(\S+)/)
{
$retArray[$cryptocore_version_ind] = $1;
# Supported Cryptocore version check
if ($retArray[$cryptocore_version_ind] < 1.0 ||
$retArray[$cryptocore_version_ind] > 2.0)
{
die("cryptocore_version for $chip in $chipInfoFile is " .
"$retArray[$cryptocore_version_ind], but only Cryptocore " .
"versions 1.0 to 2.0 are supported, stopped");
}
}
elsif($line =~ /^public_exponent\s+(-?[0-9]+)/)
{
# Use global as all signing done in this module
$publicExponent = $1;
}
elsif($line =~ /^cte_signing_level\s+([0-9]+)/)
{
$retArray[$cte_signing_level_ind] = $1;
if ($retArray[$cte_signing_level_ind] < 1 ||
$retArray[$cte_signing_level_ind] > 4)
{
die("cte_signing_level for $chip in $chipInfoFile must between 1 " .
"and 4 - see comments in the file for more information, stopped");
}
}
elsif($line =~ /^stc_addr\s+(0[Xx][0-9A-Fa-f]+)/)
{
die("Sales Type Check address in $chipInfoFile is no longer supported - use command line options, stopped");
}
elsif($line =~ /^vcc_addr\s+(0[Xx][0-9A-Fa-f]+)/)
{
die("Version Control Check address in $chipInfoFile is no longer supported - use command line options, stopped");
}
elsif ($line =~ /^\[[^]]+\]/)
{
$atChip = 0;
}
}
}
else
{
close(IN_FILE);
listChips($chipInfoFile);
die("chip information for chip $chip not found, stopped");
}
close(IN_FILE);
if (!defined($retArray[$host_boot_gap_low_ind]) ||
!defined($retArray[$host_boot_gap_high_ind]))
{
die("chip information for chip $chip incomplete - ensure " .
"host_boot_gap_low and host_boot_gap_high are specified in " .
"$chipInfoFile, stopped");
}
# Set defaults if not specified in file
if (!defined($retArray[$cryptocore_version_ind]))
{
$retArray[$cryptocore_version_ind] = 1.5;
}
if (!defined($retArray[$cte_signing_level_ind]))
{
$retArray[$cte_signing_level_ind] = 4;
}
return @retArray;
}
#
# List chip types from given chip info file
#
sub listChips($)
{
my $chipInfoFile = shift(@_);
open(IN_FILE, $chipInfoFile) || die("could not open $chipInfoFile for reading ($!), stopped");
print("Defined chips in $chipInfoFile are:\n");
my $line;
while ($line = <IN_FILE>)
{
if ($line =~ /^\[([^\]]+)\]/)
{
print(" $1\n");
}
}
close(IN_FILE);
}
#
# Sub to run the signing tool given the key filename, the name of the file
# containing the block to sign and the filename to put the signature in
#
# We use siggen in binary mode (faster, smaller files, and we're already in the
# write format compared to using big endian ASCII word lists - the other input
# type accepted)
#
# We also allow the key generation command line, but -genkey would be in
# $blockToSignFilename and the number of bits in $sigFilename).
#
sub runSigningTool($$$$$$$)
{
my $keyFile = shift(@_);
my $blockToSignFilename = shift(@_);
my $sigFilename = shift(@_);
my $sigVCCAddr = shift(@_);
my $sigVCCValue = shift(@_);
my $sigSTCAddr = shift(@_);
my $sigSTCValue = shift(@_);
my @cmdLine;
# Run siggen, passing the name of the temporary file containing the block to
# be signed, the name of the key file and the name of the signature file to
# generate
my $err = 0;
@cmdLine = ($::SIGGEN_TOOL, $blockToSignFilename, $keyFile, $sigFilename);
if ($keyFile ne "-genkey")
{
push(@cmdLine, "-b");
}
if (defined($sigSTCValue) && defined($sigSTCAddr) && $sigSTCAddr != 0)
{
push(@cmdLine, "-stc", $sigSTCAddr, $sigSTCValue);
}
if (defined($sigVCCValue) && defined($sigVCCAddr) && $sigVCCAddr != 0)
{
push(@cmdLine, "-vcc", $sigVCCAddr, $sigVCCValue);
}
if (defined($publicExponent) && $publicExponent != $DEFAULT_PUBLIC_EXPONENT)
{
push(@cmdLine, "-e", $publicExponent);
}
push(@cmdLine, "-z$verboseOutput") if ($verboseOutput);
if ($siggen_on_path)
{
open(OLDERR, ">&STDERR");
close(STDERR);
print("Running command: " . join(" ", @cmdLine) . "\n") if ($verboseOutput > 1);
$err = system(@cmdLine);
open(STDERR, ">&OLDERR");
close(OLDERR);
if ($err)
{
warn("Warning: $::SIGGEN_TOOL execution failed (may not be on path). " .
"Trying location of $::THIS_SCRIPT...\n");
$siggen_on_path = 0;
}
}
if ($err || !$siggen_on_path)
{
my $oldErr = $err;
my $siggenFullPath = $::PATH_TO_THIS_SCRIPT;
$siggenFullPath = "./" if ($siggenFullPath eq "");
if (-e $siggenFullPath . "$::SIGGEN_TOOL")## && -x $siggenFullPath . "$SIGGEN_TOOL")
{
$cmdLine[0] = $siggenFullPath . "$::SIGGEN_TOOL";
print("Running command: " . join(" ", @cmdLine) . "\n") if ($verboseOutput > 1);
$err = system(@cmdLine);
}
if ($err)
{
print("\n");
die("error attempting to run signing tool: " . $! . "\nstopped");
}
elsif ($oldErr)
{
print("Signature generation succeeded!\n");
}
}
}
#
# Sub which fills undefined values with 0 in a given list (returning a new list
# if 1st argument is non-zero)
# Prevents use of undefined value errors when script is launched with the -w
# switch (but does increase memory usage for a sparce array)
# A 3rd argument may optionally be specified to specify a value to insert in
# undefined entries other than 0
sub noUndef($$;$)
{
my $noModsToInputList = shift(@_);
my $inListRef = shift(@_);
my $fillValue = 0;
$fillValue = shift(@_) if (scalar(@_) > 0);
my $outListRef;
my @newList = ();
if ($noModsToInputList)
{
$outListRef = \@newList;
}
else
{
$outListRef = $inListRef;
}
for (my $count = 0; $count < scalar(@$inListRef); $count++)
{
if (!defined($inListRef->[$count]))
{
$outListRef->[$count] = $fillValue;
}
elsif ($noModsToInputList)
{
$outListRef->[$count] = $inListRef->[$count];
}
}
return $outListRef;
}
#
# Sub to convert an int to little endian bytes
#
sub intToLittleEndBytes($)
{
my @bytes = unpack("C4", pack("V", shift(@_)));
return @bytes;
}
#
# Sub to convert a hex string to a byte array
# Returns a reference to the array
sub hexStrToByteArray($)
{
my $str = shift(@_);
my @byteArray = map(hex, unpack("A2" x (length($str) / 2), $str));
return \@byteArray;
}
#
# Sub to pad a list up to the given number of entries (with 0 entries)
# Returns a new list
sub padList($$)
{
my $num = shift(@_);
my $arrayRef = shift(@_);
my @list = @$arrayRef;
my $pad = $num - scalar(@list);
if ($pad > 0)
{
push(@list, (0) x $pad);
}
return \@list;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -