Skip to content

Commit

Permalink
The swd task measures the SP when SP resets
Browse files Browse the repository at this point in the history
swd:
  - detects JTAG/dongle and SP_RESET
  - can drive SP_RESET to stop SP and initiate measurement procedure.
  - on JTAG dongle present or other failure, don't record a bogus FWID, just reset the log.
  - on SP reset detection, injects a blob to measure the SP.
  - on powered JTAG dongle detection, resets attestation log.
  - swd logs the result to attest task.
  - the hiffy command `db_reset_sp` is a conditional feature for debugging and testing.

endoscope: An injectable code blob covered by the RoT signature.
  - configure STM32H7 clocks in endoscope for best performance (thanks Cliff).
  - Use instruction/data tightly coupled memory (ITCM/DTCM) for better performance.
  - Build the injectable SP measurement blob as a cargo `bindeps` artifact.

attest:
  - Add `reset`, and `reset_and_record` to the attest task.
  - Only tasks listed in `[tasks.attest.config]` are allowed to reset the log.
  - Unauthorized tasks get Err(ClientError::AccessViolation.

build/lpc55pins:
  - Modify build/lpc55pins to generate separate GPIO pin setup functions for named pins.
    This allows easier switching between pin configurations at runtime.
  • Loading branch information
lzrd committed Feb 17, 2025
1 parent e54c94e commit 1dcbf79
Show file tree
Hide file tree
Showing 26 changed files with 2,512 additions and 108 deletions.
3 changes: 3 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ xtask = "run --package xtask --"
# overridden within xtask for Hubris programs, so this only affects host tools like
# xtask.
rustflags = ["-Zallow-features=proc_macro_diagnostic,asm_const,naked_functions,used_with_arg"]

[unstable]
bindeps = true
34 changes: 34 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,30 @@ opt-level = "z" # smaller optimizations
[profile.dev]
opt-level = 1 # no optimizations was just too painful in terms of flash size

# Per-package profiles do not currently allow lto, panic, or rpath.
# This costs us an extra 456 bytes in the endoscope blob that is injected
# into the SP to measure its active flash bank.
[profile.release.package.endoscope]
codegen-units = 1
debug = 2
#lto = true
opt-level = "z"
#panic = "abort"

[profile.dev.package.endoscope]
codegen-units = 1
debug = 2
#lto = true
opt-level = "z"
#panic = "abort"

[profile.bench.package.endoscope]
codegen-units = 1
debug = 2
#lto = true
opt-level = "z"
#panic = "abort"

[patch."https://github.com/oxidecomputer/hubris".userlib]
path = "sys/userlib"

Expand Down
38 changes: 15 additions & 23 deletions app/oxide-rot-1/app-dev.toml
Original file line number Diff line number Diff line change
Expand Up @@ -103,20 +103,19 @@ pins = [
{ name = "CHIP_SELECT", pin = { port = 1, pin = 1}, alt = 5},
# ROT_IRQ = P0_18 = FUN0
{ name = "ROT_IRQ", pin = { port = 0, pin = 18}, alt = 0, direction = "output"},
# SP_RESET = P0_9 = FUN0
{ name = "SP_RESET", pin = { port = 0, pin = 9}, alt = 0, direction = "input"},
]

[tasks.swd]
name = "drv-lpc55-swd"
priority = 4
max-sizes = {flash = 16384, ram = 4096}
max-sizes = {flash = 32768, ram = 9120}
uses = ["flexcomm5", "iocon"]
start = true
stacksize = 1000
task-slots = ["gpio_driver", "syscon_driver"]
notifications = ["spi-irq", "timer"]
interrupts = {"flexcomm5.irq" = "spi-irq"}
stacksize = 1280
task-slots = ["gpio_driver", "syscon_driver", "attest"]
notifications = ["spi-irq", "timer", "sp_reset-irq", "jtag_detect-irq"]
interrupts = {"flexcomm5.irq" = "spi-irq", "pint.irq0" = "sp_reset-irq", "pint.irq1" = "jtag_detect-irq" }
features = ["enable_ext_sp_reset"]

[tasks.swd.config]
# MOSI = PIO0_8
Expand All @@ -136,8 +135,10 @@ in_cfg = [
pins = [
# SCK
{ pin = { port = 0, pin = 7 }, alt = 3 },
{ name = "SP_TO_ROT_JTAG_DETECT_L", pin = { port = 0, pin = 20 }, alt = 0, direction = "input" },
{ name = "ROT_TO_SP_RESET_L", pin = { port = 0, pin = 13 }, alt = 0, value = true, direction = "output", opendrain = "opendrain" },
{ name = "SP_TO_ROT_JTAG_DETECT_L", pin = { port = 0, pin = 20 }, alt = 0, direction = "input", mode = "nopull", pint = 1 },
# SP NRST has an internal 30-50k pull-up in SP
{ name = "ROT_TO_SP_RESET_L_IN", pin = { port = 0, pin = 13 }, alt = 0, direction = "input", mode = "nopull", pint = 0 },
{ name = "ROT_TO_SP_RESET_L_OUT", pin = { port = 0, pin = 13 }, alt = 0, direction = "output", mode = "nopull", opendrain = "opendrain", setup = false },
]
spi_num = 5

Expand All @@ -149,26 +150,17 @@ start = true
stacksize = 2600
task-slots = ["swd"]

# We intentionally do not start this task to avoid conflicts with the SP
# debug connection.
[tasks.sp_measure]
name = "task-sp-measure"
priority = 6
max-sizes = {flash = 131072, ram = 8192}
task-slots = ["swd"]
stacksize = 2048

[tasks.sp_measure.config]
binary_path = "../../target/gimlet-c/dist/default/final.bin"

[tasks.attest]
name = "task-attest"
priority = 5
max-sizes = {flash = 35072, ram = 16384}
priority = 3
max-sizes = {flash = 35400, ram = 16384}
stacksize = 12304
start = true
extern-regions = ["dice_alias", "dice_certs"]

[tasks.attest.config]
permit_log_reset = ["swd", "hiffy"]

[signing.certs]
signing-certs = ["../../support/fake_certs/fake_certificate.der.crt"]
root-certs = ["../../support/fake_certs/fake_certificate.der.crt"]
Expand Down
25 changes: 15 additions & 10 deletions app/oxide-rot-1/app.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ start = true
[tasks.update_server]
name = "lpc55-update-server"
priority = 3
max-sizes = {flash = 26080, ram = 17000, usbsram = 4096}
stacksize = 8192
start = true
sections = {bootstate = "usbsram"}
Expand Down Expand Up @@ -68,6 +69,7 @@ task-slots = ["syscon_driver"]
[tasks.sprot]
name = "drv-lpc55-sprot-server"
priority = 6
max-sizes = {flash = 54016, ram = 32768}
uses = ["flexcomm8", "bootrom"]
features = ["spi0", "sp-ctrl"]
start = true
Expand All @@ -88,20 +90,18 @@ pins = [
{ name = "CHIP_SELECT", pin = { port = 1, pin = 1}, alt = 5},
# ROT_IRQ = P0_18 = FUN0
{ name = "ROT_IRQ", pin = { port = 0, pin = 18}, alt = 0, direction = "output"},
# SP_RESET = P0_9 = FUN0
{ name = "SP_RESET", pin = { port = 0, pin = 9}, alt = 0, direction = "input"},
]

[tasks.swd]
name = "drv-lpc55-swd"
priority = 4
max-sizes = {flash = 16384, ram = 4096}
max-sizes = {flash = 32768, ram = 9120}
uses = ["flexcomm5", "iocon"]
start = true
stacksize = 1000
task-slots = ["gpio_driver", "syscon_driver"]
notifications = ["spi-irq", "timer"]
interrupts = {"flexcomm5.irq" = "spi-irq"}
stacksize = 1536
task-slots = ["gpio_driver", "syscon_driver", "attest"]
notifications = ["spi-irq", "timer", "sp_reset-irq", "jtag_detect-irq"]
interrupts = {"flexcomm5.irq" = "spi-irq", "pint.irq0" = "sp_reset-irq", "pint.irq1" = "jtag_detect-irq" }

[tasks.swd.config]
# MOSI = PIO0_8
Expand All @@ -121,8 +121,10 @@ in_cfg = [
pins = [
# SCK
{ pin = { port = 0, pin = 7 }, alt = 3 },
{ name = "SP_TO_ROT_JTAG_DETECT_L", pin = { port = 0, pin = 20 }, alt = 0, direction = "input" },
{ name = "ROT_TO_SP_RESET_L", pin = { port = 0, pin = 13 }, alt = 0, value = true, direction = "output", opendrain = "opendrain" },
{ name = "SP_TO_ROT_JTAG_DETECT_L", pin = { port = 0, pin = 20 }, alt = 0, direction = "input", mode = "nopull", pint = 1 },
# SP NRST has an internal 30-50k pull-up in SP
{ name = "ROT_TO_SP_RESET_L_IN", pin = { port = 0, pin = 13 }, alt = 0, direction = "input", mode = "nopull", pint = 0 },
{ name = "ROT_TO_SP_RESET_L_OUT", pin = { port = 0, pin = 13 }, alt = 0, direction = "output", mode = "nopull", opendrain = "opendrain", setup = false },
]
spi_num = 5

Expand All @@ -136,12 +138,15 @@ task-slots = ["swd"]

[tasks.attest]
name = "task-attest"
priority = 5
priority = 3
max-sizes = {flash = 35400, ram = 16384}
stacksize = 12304
start = true
extern-regions = ["dice_alias", "dice_certs"]

[tasks.attest.config]
permit_log_reset = ["swd"]

[signing.certs]
signing-certs = ["../../support/fake_certs/fake_certificate.der.crt"]
root-certs = ["../../support/fake_certs/fake_certificate.der.crt"]
Expand Down
11 changes: 10 additions & 1 deletion drv/lpc55-swd/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,33 @@ idol-runtime = { workspace = true }
lpc55-pac = { workspace = true }
num-traits = { workspace = true }
zerocopy = { workspace = true }
bitflags = { workspace = true }

attest-api = { path = "../../task/attest-api" }
drv-lpc55-gpio-api = { path = "../lpc55-gpio-api" }
drv-lpc55-spi = { path = "../lpc55-spi" }
drv-lpc55-syscon-api = { path = "../lpc55-syscon-api" }
drv-sp-ctrl-api = { path = "../sp-ctrl-api" }
ringbuf = { path = "../../lib/ringbuf" }
userlib = { path = "../../sys/userlib", features = ["panic-messages"] }
endoscope-abi = { path = "../../lib/endoscope-abi" }

[build-dependencies]
anyhow = { workspace = true }
build-lpc55pins = { path = "../../build/lpc55pins" }
build-util = { path = "../../build/util" }
anyhow = { workspace = true }
call_rustfmt = { path = "../../build/call_rustfmt" }
endoscope-abi = { path = "../../lib/endoscope-abi" }
endoscope = { path = "../../lib/endoscope", artifact="bin:endoscope", target = "thumbv7em-none-eabihf", features = ["soc_stm32h753"]}
goblin = { workspace = true }
idol = { workspace = true }
quote = { workspace = true }
rustc-demangle = { workspace = true }
serde = { workspace = true }

[features]
no-ipc-counters = ["idol/no-counters"]
enable_ext_sp_reset = []

# This section is here to discourage RLS/rust-analyzer from doing test builds,
# since test builds don't work for cross compilation.
Expand Down
Loading

0 comments on commit 1dcbf79

Please sign in to comment.