From 3c6b779323a5d3d7bcdeb614d6f7635a973d21ae Mon Sep 17 00:00:00 2001 From: James Hilliard Date: Mon, 9 Nov 2026 15:53:57 -0700 Subject: [PATCH] tools: Add BCM2712 RAM authenticity check 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. Return distinct statuses for matching, mismatched, and unavailable capacity information. Explain that matching capacity cannot establish that the RAM is original. --- tools/rpi-ram-authenticity-check | 76 ++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100755 tools/rpi-ram-authenticity-check diff --git a/tools/rpi-ram-authenticity-check b/tools/rpi-ram-authenticity-check new file mode 100755 index 00000000..ead65bba --- /dev/null +++ b/tools/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