Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ add_subdirectory(piolib)
add_subdirectory(raspinfo)
add_subdirectory(rpieepromab)
add_subdirectory(rpi-gpu-usage)
add_subdirectory(rpi-ram-authenticity-check)
add_subdirectory(vcgencmd)
add_subdirectory(vclog)
add_subdirectory(vcmailbox)
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ A collection of scripts and simple applications
secure-boot provisioner.
* [rpi-gpu-usage](rpi-gpu-usage/) - A tool for showing the per-process usage of the V3D GPU
on Raspberry Pi 4 and 5.
* [rpi-ram-authenticity-check](rpi-ram-authenticity-check/) - A read-only RAM authenticity
check for BCM2712 devices, comparing reported capacity with the factory configuration.
* [splashasm](splashasm/) - A tool for writing spi & i2c dumps for fast display at boot
* [vcgencmd](vcgencmd/) - A tool to send commands to the VideoCore firmware and
display the results.
Expand Down
5 changes: 5 additions & 0 deletions raspinfo/README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
# raspinfo
Short script to dump information about the Pi. Use it for annotating bug reports.

On BCM2712 devices, includes the output of
[`rpi-ram-authenticity-check`](../rpi-ram-authenticity-check/) when installed.
RAM mismatch warnings and unavailable checks are recorded in `raspinfo.txt`
without stopping the rest of the report.
13 changes: 13 additions & 0 deletions raspinfo/raspinfo
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,19 @@ cat /proc/cpuinfo | tail -3

echo "Throttled flag : "`vcgencmd get_throttled`

if grep -q bcm2712 /proc/device-tree/compatible 2>/dev/null; then
echo
echo "RAM authenticity"
echo "----------------"
echo
if command -v rpi-ram-authenticity-check > /dev/null; then
rpi-ram-authenticity-check 2>&1 || :
else
echo "rpi-ram-authenticity-check not found"
fi
echo
fi


echo "Camera Information"
echo "------------------"
Expand Down
7 changes: 7 additions & 0 deletions rpi-ram-authenticity-check/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 3.10...3.27)

include(GNUInstallDirs)

project(rpi-ram-authenticity-check)

install(PROGRAMS rpi-ram-authenticity-check DESTINATION ${CMAKE_INSTALL_BINDIR})
28 changes: 28 additions & 0 deletions rpi-ram-authenticity-check/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# rpi-ram-authenticity-check

Read-only RAM authenticity check for BCM2712 devices (the Pi 5 family).
Compares the RAM capacity in the running board revision (from device tree or
`/proc/cpuinfo`) with the factory revision in OTP row 32.

Run `rpi-ram-authenticity-check` after installing utils, or directly from this
repository:

```sh
./rpi-ram-authenticity-check/rpi-ram-authenticity-check
```

Requires `vcgencmd` and access to `/dev/vcio`; run with `sudo` if access is denied.
Use `--help` for usage information.

A mismatch warns of possible RAM tampering or replacement and advises contacting
the seller to arrange a return. Matching capacity is reported as "RAM appears
authentic", but cannot detect a replacement with the same capacity.

Exit status:

* `0`: capacity matches.
* `1`: capacity differs.
* `2`: unable to check, including unsupported hardware or missing/invalid data.

When installed, the checker is also called by `raspinfo` on BCM2712 devices.
Its output, including warnings, is included in `raspinfo.txt`.
76 changes: 76 additions & 0 deletions rpi-ram-authenticity-check/rpi-ram-authenticity-check
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/bin/sh

# Compare BCM2712's reported RAM capacity with its factory revision in OTP.
set -ef

usage() {
cat <<EOF
Usage: rpi-ram-authenticity-check [-h | --help]

Compare the RAM capacity in the running board revision with the factory
capacity in BCM2712 OTP row 32. Requires vcgencmd and access to /dev/vcio.
This is a read-only capacity check; it cannot prove that the RAM is original
or detect a replacement with the same capacity.

Exit status: 0 = capacity matches, 1 = capacity differs, 2 = unable to check.
EOF
}

die() {
echo "Unable to check RAM: $*" >&2
exit 2
}

ramSizeFromRevision() {
case "$1" in
''|*[!0-9a-fA-F]*) return 1 ;;
esac
[ "${#1}" -le 8 ] || return 1
# Require a new-style BCM2712 revision before interpreting its RAM field.
[ $(((0x$1 >> 23) & 1)) -eq 1 ] &&
[ $(((0x$1 >> 12) & 15)) -eq 4 ] || return 1
ram_code=$(((0x$1 >> 20) & 7))
# Code 7 means "Other", not 32 GiB.
[ "${ram_code}" -lt 7 ] || return 1
echo "$((256 << ram_code))"
}

if [ "$#" -ne 0 ]; then
if [ "$#" -eq 1 ] && { [ "$1" = -h ] || [ "$1" = --help ]; }; then
usage
exit 0
fi
usage >&2
exit 2
fi

# Use the same running revision sources as rpi-eeprom-update. Do not fall
# back to OTP here: comparing the factory value with itself would miss changes.
dt_revision=/sys/firmware/devicetree/base/system/linux,revision
if [ -r "${dt_revision}" ]; then
[ "$(wc -c < "${dt_revision}")" -eq 4 ] || die "Invalid device-tree board revision."
board_revision=$(od -v -An -t x1 "${dt_revision}" | tr -d ' \n')
elif [ -r /proc/cpuinfo ]; then
board_revision=$(sed -n '/^Revision/s/^.*: \(.*\)/\1/p' /proc/cpuinfo)
else
die "No running board revision found."
fi
reported_mib=$(ramSizeFromRevision "${board_revision}") ||
die "The running board revision must describe a BCM2712 device with a known RAM capacity."

command -v vcgencmd > /dev/null || die "vcgencmd is required to read the factory RAM capacity."
otp_dump=$(vcgencmd otp_dump) || die "Failed to read OTP; check access to /dev/vcio."
# Row 32 is the BCM2712 factory revision; BCM2711 uses row 30.
factory_revision=$(printf '%s\n' "${otp_dump}" | sed -n 's/^32:\([0-9a-fA-F]\{8\}\)$/\1/p')
factory_mib=$(ramSizeFromRevision "${factory_revision}") ||
die "OTP row 32 does not contain a valid BCM2712 revision with a known RAM capacity."

echo "Factory RAM: ${factory_mib} MiB; reported RAM: ${reported_mib} MiB."
if [ "${factory_mib}" -eq "${reported_mib}" ]; then
echo "RAM appears authentic: capacity matches the factory configuration."
exit 0
fi

echo "WARNING: RAM capacity mismatch detected: possible RAM tampering or replacement." >&2
echo "Contact the seller to arrange a return." >&2
exit 1