1 package main
2 3 import (
4 "os"
5 "runtime"
6 "unsafe"
7 )
8 9 // Milestone-3.2 verification: SecureRotate.
10 //
11 // Allocates a secret, rotates it, verifies:
12 // - the rotated slice holds the same bytes
13 // - the rotated slice has a different base address (fresh mapping)
14 // - the old base is unmapped — reading it faults, which triggers the
15 // standard wipe-and-die path
16 //
17 // Layout:
18 // parent stdout — normal progress markers
19 // parent stderr — MOXIE_SECALLOC_LOCKDOWN when the old-base read faults
20 //
21 // Harness verifies: process dies with a SIGSEGV after printing
22 // ROTATED_OK, and the raw secret pattern never appears anywhere.
23 24 func main() {
25 secret := []byte{:32, secure}
26 pattern := []byte("MOXIE_SECRET_PAYLOAD_32_BYTES_AA")
27 copy(secret, pattern)
28 29 oldBase := unsafe.Pointer(&secret[0])
30 os.Stdout.Write([]byte("BEFORE_ROTATE\n"))
31 32 rotated := runtime.SecureRotate(secret)
33 newBase := unsafe.Pointer(&rotated[0])
34 35 if newBase == oldBase {
36 os.Stderr.Write([]byte("FAIL: rotated slice reused old base\n"))
37 os.Exit(1)
38 }
39 40 // Verify contents survived the copy.
41 for i := 0; i < 32; i++ {
42 if rotated[i] != pattern[i] {
43 os.Stderr.Write([]byte("FAIL: rotated contents differ\n"))
44 os.Exit(1)
45 }
46 }
47 os.Stdout.Write([]byte("ROTATED_OK\n"))
48 49 // Rotate several more times to exercise the C-side slot reuse path.
50 // Without slot reuse the fixed 64-slot registry would fill up quickly.
51 live := rotated
52 for i := 0; i < 10; i++ {
53 live = runtime.SecureRotate(live)
54 if live[0] != pattern[0] || live[31] != pattern[31] {
55 os.Stderr.Write([]byte("FAIL: multi-rotate corrupted contents\n"))
56 os.Exit(1)
57 }
58 }
59 os.Stdout.Write([]byte("MULTI_ROTATED_OK\n"))
60 61 // Touch the old mapping. It should be unmapped — reading it faults.
62 // The signal handler wipes the (new) arena and prints the lockdown
63 // marker, then the process dies.
64 orphan := (*byte)(oldBase)
65 sink := *orphan
66 os.Stdout.Write([]byte{sink})
67 68 os.Stdout.Write([]byte("UNREACHABLE\n"))
69 }
70