auditor

An aarch64 constant-time memory access auditing tool.
git clone git://git.ppad.tech/auditor.git
Log | Files | Refs | README | LICENSE

commit 191611b72312b0990f0e4488c2c61ce47bcd1c3a
parent f1f3facd8d49e27fc1f2d90ed222d42025838043
Author: Jared Tobin <jared@jtobin.io>
Date:   Thu, 26 Feb 2026 17:14:54 +0400

docs: modernize README with current features

Update documentation to cover:
- Taint analysis with inter-procedural support
- Taint configuration files (secret, public, secret_pointee, STG slots)
- NCT scan mode with symbol-focused analysis
- GHC runtime filtering
- Utility commands (list-symbols, filter, zsymbol)
- Updated limitations section

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

Diffstat:
MREADME.md | 149+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 124 insertions(+), 25 deletions(-)

diff --git a/README.md b/README.md @@ -3,23 +3,27 @@ ![](https://img.shields.io/badge/license-MIT-brightgreen) A Haskell tool for static analysis of GHC-generated AArch64 assembly, -focused on constant-time memory access auditing for cryptographic code. +focused on constant-time auditing for cryptographic code. ## Overview -ppad-auditor parses AArch64 assembly and performs taint analysis to -identify memory accesses that may leak secret data through -timing side-channels. It flags loads and stores where: +ppad-auditor provides two analysis modes: -- The base register may contain secret-derived data -- An index register may contain secret-derived data +1. **Taint analysis** (default): Tracks how secret data flows through + registers and memory, flagging loads/stores where the address may + depend on secret values (cache timing side-channels). -The tool assumes GHC's calling convention, where certain registers -(X19-X22, SP) are treated as public (stack/heap pointers), and tracks -how taint propagates through arithmetic and data movement instructions -across basic blocks. +2. **NCT scan** (`--scan-nct`): Identifies non-constant-time + instructions (variable-time division, conditional branches, etc.) + that may leak secrets through execution timing. -## Usage +The tool understands GHC's calling conventions, treating registers like +X19-X22 and SP as public pointers, and tracking taint propagation +through arithmetic, data movement, and function calls. + +## Taint Analysis + +Basic usage: ``` $ auditor -i input.s @@ -36,38 +40,133 @@ Memory accesses: 37 Violations: 2 ``` -Use `-q` for quiet mode (violations only), `-j` for JSON output, or -`-p` for inter-procedural analysis (computes function summaries). +### Inter-procedural Analysis -## Limitations +Use `-p` to enable inter-procedural analysis, which computes function +summaries and propagates taint across call boundaries: + +``` +$ auditor -i input.s -p +``` + +### Taint Configuration + +Seed specific registers or STG stack slots as secret using a JSON +config file: + +```json +{ + "_my_function_info$def": { + "secret": ["X0", "X1"], + "public": ["X2"], + "secret_pointee": ["X3"], + "stg_secret": [8, 16], + "stg_public": [24] + } +} +``` + +- `secret`: Registers containing secret scalar values +- `public`: Registers to mark as public +- `secret_pointee`: Registers that are public pointers to secret data + (loads through them produce secret values) +- `stg_secret` / `stg_public`: STG stack slot offsets (X20-relative) + +Apply with: + +``` +$ auditor -i input.s -p --taint-config config.json +``` + +### Display Options + +- `-u`: Show unknown violations (only secret violations shown by + default) +- `-q`: Quiet mode (violations only, no summary) +- `-j`: JSON output format +- `--assume-stg-private`: Treat untracked STG stack slots as private + (default assumes they're public closure pointers) + +## NCT Scan + +Scan for non-constant-time instructions without taint analysis: + +``` +$ auditor -i input.s --scan-nct +``` + +This identifies: +- Variable-time arithmetic (udiv, sdiv without DIT) +- Conditional branches (b.cond, cbz, cbnz, tbz, tbnz) +- Register-indexed memory accesses + +### Symbol-Focused Scanning + +Analyze a specific function and its callees: -This is an early-stage tool with known limitations: +``` +$ auditor -i input.s --scan-nct --symbol _my_func_info +``` + +Or use human-readable z-encoded symbols: + +``` +$ auditor -i input.s --scan-nct --zsymbol "pkg-1.0:Module.Name:function" +``` + +Use `-c` to show callers instead of callees (reverse reachability). + +### GHC Runtime Filtering + +GHC runtime patterns (heap checks, stack checks, closure evaluation) +are hidden by default. Show them with: + +``` +$ auditor -i input.s --scan-nct --show-ghc-runtime +``` + +## Utility Commands + +List all function symbols: + +``` +$ auditor -i input.s --list-symbols +``` + +Filter symbols by pattern: + +``` +$ auditor -i input.s --list-symbols --filter "multiply" +``` + +## Limitations -- **No inter-procedural analysis**: Function calls reset taint state - for caller-saved registers; callees are analyzed independently even - when defined in the same file -- **Conservative**: Unknown taint is treated as potentially secret +- **Conservative analysis**: Unknown taint is treated as potentially + secret, which may cause over-reporting +- **GHC-specific**: Assumes GHC's STG calling convention and register + usage; may not work well with other compilers +- **No alias analysis**: Heap accesses use coarse tracking; complex + pointer aliasing may cause false positives/negatives -These limitations mean the tool may over-report violations. Manual -review of flagged accesses is required. +Manual review of flagged accesses is recommended. ## Development -You'll require [Nix][nixos] with [flake][flake] support enabled. Enter a -development shell with: +Requires [Nix][nixos] with [flake][flake] support. Enter a development +shell: ``` $ nix develop ``` -Then build and test: +Build and test: ``` $ cabal build $ cabal test ``` -To audit some assembly: +Audit some assembly: ``` $ cabal run auditor -- -i path/to/file.s