diff --git a/api/api.go b/api/api.go index 2c74e4b..e5545e8 100644 --- a/api/api.go +++ b/api/api.go @@ -45,6 +45,8 @@ const ( U2FHID_ARMORY_OTA // Set HAB fuse to built-in SRK hash U2FHID_ARMORY_HAB + // Fetch latest debug/console logs + U2FHID_ARMORY_CONSOLE_LOGS ) var emptyResponse []byte diff --git a/cmd/witnessctl/api.go b/cmd/witnessctl/api.go index dbe94c7..e678531 100644 --- a/cmd/witnessctl/api.go +++ b/cmd/witnessctl/api.go @@ -78,6 +78,15 @@ func (d Device) hab() error { return nil } +func (d Device) consoleLogs() (string, error) { + buf, err := d.u2f.Command(api.U2FHID_ARMORY_CONSOLE_LOGS, nil) + if err != nil { + return "", err + } + + return string(buf), nil +} + func (d Device) sendUpdateHeader(signature []byte, total int) (err error) { update := &api.AppletUpdate{ Total: uint32(total), diff --git a/cmd/witnessctl/witnessctl.go b/cmd/witnessctl/witnessctl.go index 852e70a..83b2010 100644 --- a/cmd/witnessctl/witnessctl.go +++ b/cmd/witnessctl/witnessctl.go @@ -55,8 +55,9 @@ type Config struct { hidPath string - status bool - hab bool + status bool + consoleLogs bool + hab bool otaELF string otaSig string @@ -79,6 +80,7 @@ func init() { flag.StringVar(&conf.hidPath, "d", "", "HID path of witness device to act upon (use -s to list devices)") flag.BoolVar(&conf.status, "s", false, "get witness status") + flag.BoolVar(&conf.consoleLogs, "l", false, "get witness console/debug logs") flag.BoolVar(&conf.hab, "H", false, "set HAB fuses") flag.StringVar(&conf.otaELF, "o", "", "trusted applet payload") flag.StringVar(&conf.otaSig, "O", "", "trusted applet signature") @@ -160,6 +162,15 @@ func main() { } log.Printf("%s\n\n", s.Print()) } + case conf.consoleLogs: + for _, d := range conf.devs { + log.Printf("👁️‍🗨️ @ %s", d.usb.Path) + s, err := d.consoleLogs() + if err != nil { + log.Printf("Failed to get console logs on %q: %c", d.usb.Path, err) + } + log.Printf("%s\n\n", s) + } case len(conf.otaELF) > 0 || len(conf.otaSig) > 0: if len(conf.devs) != 1 { log.Fatal("Please specify which device to OTA using -d") diff --git a/go.mod b/go.mod index 5d6a1c2..2e4dc5b 100644 --- a/go.mod +++ b/go.mod @@ -36,6 +36,7 @@ require ( github.com/mattn/go-runewidth v0.0.15 // indirect github.com/pierrec/lz4/v4 v4.1.14 // indirect github.com/rivo/uniseg v0.2.0 // indirect + github.com/smallnest/ringbuffer v0.0.0-20230728150354-35801fa39d0e // indirect github.com/stretchr/testify v1.8.2 // indirect github.com/transparency-dev/formats v0.0.0-20230920083814-0f75b1d4e813 // indirect github.com/u-root/u-root v0.11.0 // indirect diff --git a/go.sum b/go.sum index b6ff886..540aa0d 100644 --- a/go.sum +++ b/go.sum @@ -47,6 +47,8 @@ github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/smallnest/ringbuffer v0.0.0-20230728150354-35801fa39d0e h1:KHiRfgBfn0d3lv2kXs4iayASb6TdInNNIHe75zX0sqg= +github.com/smallnest/ringbuffer v0.0.0-20230728150354-35801fa39d0e/go.mod h1:mXcZNMJHswhQDDJZIjdtJoG97JIwIa/HdcHNM3w15T0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= diff --git a/trusted_os/console.go b/trusted_os/console.go index 077c837..c957996 100644 --- a/trusted_os/console.go +++ b/trusted_os/console.go @@ -51,6 +51,10 @@ func printk(c byte) { // ensure that any serial output is supressed before UART2 disabling } +func getConsoleLogs() []byte { + return nil +} + func inspect(buf []byte, _ any) error { return nil } diff --git a/trusted_os/ctl.go b/trusted_os/ctl.go index 58bfdfc..b0fdb3c 100644 --- a/trusted_os/ctl.go +++ b/trusted_os/ctl.go @@ -154,6 +154,11 @@ func (ctl *controlInterface) HAB(_ []byte) []byte { return api.EmptyResponse() } +func (ctl *controlInterface) ConsoleLogs(_ []byte) (res []byte) { + logs := getConsoleLogs() + return []byte(logs) +} + func (ctl *controlInterface) Start() { device := &usb.Device{} serial := fmt.Sprintf("%X", imx6ul.UniqueID()) diff --git a/trusted_os/debug.go b/trusted_os/debug.go index c48e972..1361e98 100644 --- a/trusted_os/debug.go +++ b/trusted_os/debug.go @@ -30,14 +30,16 @@ import ( usbarmory "github.com/usbarmory/tamago/board/usbarmory/mk2" "github.com/usbarmory/tamago/soc/nxp/usb" + "github.com/usbarmory/GoTEE/monitor" usbserial "github.com/usbarmory/imx-usbserial" - "github.com/usbarmory/GoTEE/monitor" + "github.com/smallnest/ringbuffer" ) const debug = true var serial *usbserial.UART +var logBuffer *ringbuffer.RingBuffer func init() { // TODO(al): Probably want to reinstate this check after wave0! @@ -46,17 +48,23 @@ func init() { panic("fatal error, debug firmware not allowed on secure booted units") } */ + logBuffer = ringbuffer.New(1 << 20) } //go:linkname printk runtime.printk func printk(c byte) { usbarmory.UART2.Tx(c) + logBuffer.WriteByte(c) if serial != nil { serial.WriteByte(c) } } +func getConsoleLogs() []byte { + return logBuffer.Bytes() +} + func configureUART(device *usb.Device) (err error) { if LAN == nil { return diff --git a/trusted_os/usb_hid.go b/trusted_os/usb_hid.go index 96c6c78..3293cec 100644 --- a/trusted_os/usb_hid.go +++ b/trusted_os/usb_hid.go @@ -121,5 +121,9 @@ func configureHID(device *usb.Device, ctl *controlInterface) (err error) { return } + if err = hid.AddMapping(api.U2FHID_ARMORY_CONSOLE_LOGS, ctl.ConsoleLogs); err != nil { + return + } + return }