From faec832e84ffa6eed2f1ee3a41d517890a13eb15 Mon Sep 17 00:00:00 2001 From: James Hilliard Date: Tue, 10 Nov 2026 01:32:13 -0700 Subject: [PATCH] Add BCM2712 RAM authenticity check and raspinfo integration Compare the RAM capacity in the running board revision with the factory revision in OTP row 32. Report possible RAM tampering or replacement and advise contacting the seller to arrange a return. Install the standalone checker through CMake and document its usage, exit statuses, and limitations. Matching capacity cannot establish that the RAM is original. Include the check in raspinfo on BCM2712 devices when the tool is installed. Capture warnings in the saved report and continue collecting diagnostics when RAM differs or the check is unavailable. --- CMakeLists.txt | 1 + README.md | 2 + raspinfo/README.md | 5 ++ raspinfo/raspinfo | 13 ++++ rpi-ram-authenticity-check/CMakeLists.txt | 7 ++ rpi-ram-authenticity-check/README.md | 28 +++++++ .../rpi-ram-authenticity-check | 76 +++++++++++++++++++ 7 files changed, 132 insertions(+) create mode 100644 rpi-ram-authenticity-check/CMakeLists.txt create mode 100644 rpi-ram-authenticity-check/README.md create mode 100755 rpi-ram-authenticity-check/rpi-ram-authenticity-check diff --git a/CMakeLists.txt b/CMakeLists.txt index 86750a1..a9a5deb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/README.md b/README.md index 1da5939..64fcb15 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/raspinfo/README.md b/raspinfo/README.md index 2c9eb35..143d7f7 100644 --- a/raspinfo/README.md +++ b/raspinfo/README.md @@ -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. diff --git a/raspinfo/raspinfo b/raspinfo/raspinfo index d3cee29..99b1965 100755 --- a/raspinfo/raspinfo +++ b/raspinfo/raspinfo @@ -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 "------------------" diff --git a/rpi-ram-authenticity-check/CMakeLists.txt b/rpi-ram-authenticity-check/CMakeLists.txt new file mode 100644 index 0000000..99fc7e8 --- /dev/null +++ b/rpi-ram-authenticity-check/CMakeLists.txt @@ -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}) diff --git a/rpi-ram-authenticity-check/README.md b/rpi-ram-authenticity-check/README.md new file mode 100644 index 0000000..202fb3e --- /dev/null +++ b/rpi-ram-authenticity-check/README.md @@ -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`. diff --git a/rpi-ram-authenticity-check/rpi-ram-authenticity-check b/rpi-ram-authenticity-check/rpi-ram-authenticity-check new file mode 100755 index 0000000..ead65bb --- /dev/null +++ b/rpi-ram-authenticity-check/rpi-ram-authenticity-check @@ -0,0 +1,76 @@ +#!/bin/sh + +# Compare BCM2712's reported RAM capacity with its factory revision in OTP. +set -ef + +usage() { + cat <&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