Skip to content

Commit

Permalink
Support both LAN and USB models (#40)
Browse files Browse the repository at this point in the history
* support both LAN and USB models
* add applet stack trace dump when debugging
* panic on accidental signing of debug firmware
* increase ENET ring buffer size
* fix dependencies
* fix IRQ clearing
* fix USB operation with higher RingSize
  • Loading branch information
abarisani authored Aug 16, 2023
1 parent d220e97 commit 3db29ad
Show file tree
Hide file tree
Showing 14 changed files with 400 additions and 113 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ The following table summarizes currently supported SoCs and boards.

| SoC | Board | SoC package | Board package |
|--------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------|--------------------------------------------------------------------------------------|
| NXP i.MX6UL | [USB armory Mk II LAN](https://github.com/usbarmory/usbarmory/wiki) | [imx6ul](https://github.com/usbarmory/tamago/tree/master/soc/nxp/imx6ul) | [usbarmory/mk2](https://github.com/usbarmory/tamago/tree/master/board/usbarmory) |
| NXP i.MX6UL | [USB armory Mk II LAN](https://github.com/usbarmory/usbarmory/wiki) | [imx6ul](https://github.com/usbarmory/tamago/tree/master/soc/nxp/imx6ul) | [usbarmory/mk2](https://github.com/usbarmory/tamago/tree/master/board/usbarmory) |
| NXP i.MX6ULL | [USB armory Mk II](https://github.com/usbarmory/usbarmory/wiki) | [imx6ul](https://github.com/usbarmory/tamago/tree/master/soc/nxp/imx6ul) | [usbarmory/mk2](https://github.com/usbarmory/tamago/tree/master/board/usbarmory) |

## Purpose

Expand Down
7 changes: 5 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ require (
github.com/usbarmory/armory-boot v0.0.0-20230724181259-b0947883370d
github.com/usbarmory/armory-witness-log v0.0.0-20230119085953-e0606f8bd081
github.com/usbarmory/crucible v0.0.0-20230412092556-269c90b0067e
github.com/usbarmory/imx-usbnet v0.0.0-20230626092818-ef791923688e
github.com/usbarmory/imx-usbserial v0.0.0-20230503192150-40b6298b31f8
github.com/usbarmory/tamago v0.0.0-20230724190245-6f2dec2f8412
github.com/usbarmory/tamago v0.0.0-20230814171810-6cd63c1accf5
golang.org/x/crypto v0.8.0
golang.org/x/mod v0.10.0
google.golang.org/protobuf v1.30.0
gvisor.dev/gvisor v0.0.0-20230614190805-57027c7d31f8
)

require (
Expand All @@ -26,7 +28,7 @@ require (
github.com/fatih/color v1.13.0 // indirect
github.com/ghodss/yaml v1.0.0 // indirect
github.com/go-errors/errors v1.4.2 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/btree v1.0.1 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
Expand All @@ -38,6 +40,7 @@ require (
golang.org/x/net v0.9.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.7.0 // indirect
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)
19 changes: 14 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ github.com/go-errors/errors v1.0.2/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWE
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/gsora/fidati v0.0.0-20220824075547-eeb0a5f7d6c3 h1:klG3scbSLaGIvJO1p9wdTaHonsCSAcvNrX8vfa8LRd4=
github.com/gsora/fidati v0.0.0-20220824075547-eeb0a5f7d6c3/go.mod h1:pqELFmXT+lU57T8pIGwPSOODIvRv/r/lwxlJX0UupvY=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
Expand Down Expand Up @@ -69,19 +70,23 @@ github.com/transparency-dev/merkle v0.0.1 h1:T9/9gYB8uZl7VOJIhdwjALeRWlxUxSfDEys
github.com/transparency-dev/merkle v0.0.1/go.mod h1:B8FIw5LTq6DaULoHsVFRzYIUDkl8yuSwCdZnOZGKL/A=
github.com/u-root/u-root v7.0.0+incompatible h1:u+KSS04pSxJGI5E7WE4Bs9+Zd75QjFv+REkjy/aoAc8=
github.com/u-root/u-root v7.0.0+incompatible/go.mod h1:RYkpo8pTHrNjW08opNd/U6p/RJE7K0D8fXO0d47+3YY=
github.com/usbarmory/armory-boot v0.0.0-20230724181259-b0947883370d h1:oIdJllwCnP/ZPfdrB5fB+zH3+NM+EFW8lCNiRhVKw1s=
github.com/usbarmory/armory-boot v0.0.0-20230724181259-b0947883370d/go.mod h1:2+FV8fn4y14BkPvrUdZ35mxQuMb1JcDxOZy6lFvHzj8=
github.com/usbarmory/GoTEE v0.0.0-20230717085113-1beadf7e5429 h1:GNph1FFN4d/LwR2naucFsnT3Ti3kuTaZNWNXpp6uAvQ=
github.com/usbarmory/GoTEE v0.0.0-20230717085113-1beadf7e5429/go.mod h1:164CE5Gb+PiM6cxhYpyPg9FlpqttRFwUZ+KiTonK4Ak=
github.com/usbarmory/armory-boot v0.0.0-20230724181259-b0947883370d h1:oIdJllwCnP/ZPfdrB5fB+zH3+NM+EFW8lCNiRhVKw1s=
github.com/usbarmory/armory-boot v0.0.0-20230724181259-b0947883370d/go.mod h1:2+FV8fn4y14BkPvrUdZ35mxQuMb1JcDxOZy6lFvHzj8=
github.com/usbarmory/armory-witness-log v0.0.0-20230119085953-e0606f8bd081 h1:jNYBY/QlWc6OY306INg9OYoUSRJnsaPW9mxbYIwG4ck=
github.com/usbarmory/armory-witness-log v0.0.0-20230119085953-e0606f8bd081/go.mod h1:xNL8XYc/6ffU/mYldaJDqaMEtwC6B4DAjkFHV+Jm2jQ=
github.com/usbarmory/crucible v0.0.0-20230412092556-269c90b0067e h1:6hKgQCr5x22jR8SLQ9W6+X2YitRqBAmfCSuIqYskh4c=
github.com/usbarmory/crucible v0.0.0-20230412092556-269c90b0067e/go.mod h1:8CtxsBNuSD2E0f23kH74XcHlenwMnn/RmTQ1wn4Lwtw=
github.com/usbarmory/imx-usbnet v0.0.0-20230626092818-ef791923688e h1:x2vSKye5+66g7OSPSazNSA/QHJjw+MBhJcvTAUvPfO8=
github.com/usbarmory/imx-usbnet v0.0.0-20230626092818-ef791923688e/go.mod h1:eT+4LgXX1S+pyzpTtg0P5vCqvzQA4/kA1b/kmiMqQbE=
github.com/usbarmory/imx-usbserial v0.0.0-20230503192150-40b6298b31f8 h1:VPruqXJEJxTweSRyx3NIkiIqQl9ppZHp4wZnL8+Y0aI=
github.com/usbarmory/imx-usbserial v0.0.0-20230503192150-40b6298b31f8/go.mod h1:XfTrYj8Ik3ljit1cSHTcsXs7lyJ/QMsplPDX8+g5s7c=
github.com/usbarmory/tamago v0.0.0-20220823080407-04f05cf2a5a3/go.mod h1:Lok79mjbJnhoBGqhX5cCUsZtSemsQF5FNZW+2R1dRr8=
github.com/usbarmory/tamago v0.0.0-20230724190245-6f2dec2f8412 h1:nlsiJoU3RcHkAjEwIquGcqq+MCe96h8u83MPHTjKiwY=
github.com/usbarmory/tamago v0.0.0-20230724190245-6f2dec2f8412/go.mod h1:uCPXcPo8SZulhZPz8irfVqzwVlPZ45w7CTJxkfxueGA=
github.com/usbarmory/tamago v0.0.0-20230804144655-4d2d9a7a0e03 h1:Sm6ApuOX0IROgN34ZlVFXwCsNBA+MH8xSaagwEQ5mT8=
github.com/usbarmory/tamago v0.0.0-20230804144655-4d2d9a7a0e03/go.mod h1:uCPXcPo8SZulhZPz8irfVqzwVlPZ45w7CTJxkfxueGA=
github.com/usbarmory/tamago v0.0.0-20230814171810-6cd63c1accf5 h1:cu+znyiHqWwvmoPM6uplHt+bOkn5hc+133/kwg15ywk=
github.com/usbarmory/tamago v0.0.0-20230814171810-6cd63c1accf5/go.mod h1:uCPXcPo8SZulhZPz8irfVqzwVlPZ45w7CTJxkfxueGA=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ=
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
Expand All @@ -102,6 +107,8 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44=
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
Expand All @@ -114,3 +121,5 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gvisor.dev/gvisor v0.0.0-20230614190805-57027c7d31f8 h1:cycLSWR8fzi6P+jQ9vaD82frUFZ0UU1kDZt1YPWFFhA=
gvisor.dev/gvisor v0.0.0-20230614190805-57027c7d31f8/go.mod h1:sQuqOkxbfJq/GS2uSnqHphtXclHyk/ZrAGhZBxxsq6g=
4 changes: 4 additions & 0 deletions rpmb/rpmb.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ type RPMB struct {
// dummyBlock argument is an unused sector, required for CVE-2020-13799
// mitigation to invalidate uncommitted writes.
func Init(card *usdhc.USDHC, key []byte, dummyBlock uint16) (p *RPMB, err error) {
if card == nil {
return nil, fmt.Errorf("no MMC card set")
}

if !card.Info().MMC {
return nil, fmt.Errorf("no MMC card detected")
}
Expand Down
7 changes: 5 additions & 2 deletions trusted_os/console.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (
_ "unsafe"

"github.com/usbarmory/tamago/soc/nxp/imx6ul"
"github.com/usbarmory/tamago/soc/nxp/usb"
)

// The Trusted OS does not log any sensitive information to the serial console,
Expand Down Expand Up @@ -52,6 +51,10 @@ func printk(c byte) {
// ensure that any serial output is supressed before UART2 disabling
}

func configureUART(device *usb.Device) error {
func inspect(buf []byte, _ any) error {
return nil
}

func configureUART(_ any) error {
return nil
}
39 changes: 20 additions & 19 deletions trusted_os/ctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@ type controlInterface struct {
func getStatus() (s *api.Status) {
version, _ := parseVersion(Version)

miiStatus := Network.ReadPHYRegister(usbarmory.PHY_ADDR, MII_STATUS)

s = &api.Status{
Serial: fmt.Sprintf("%X", imx6ul.UniqueID()),
HAB: imx6ul.SNVS.Available(),
Expand All @@ -60,8 +58,13 @@ func getStatus() (s *api.Status) {
Runtime: fmt.Sprintf("%s %s/%s", runtime.Version(), runtime.GOOS, runtime.GOARCH),
}

if miiStatus&(1<<STATUS_LINK) > 0 {
s.Link = true
switch {
case LAN != nil:
miiStatus := LAN.ReadPHYRegister(usbarmory.PHY_ADDR, MII_STATUS)
s.Link = miiStatus&(1<<STATUS_LINK) > 0
case USB != nil:
mode, err := usbarmory.FrontPortMode()
s.Link = err != nil && mode == usbarmory.STATE_ATTACHED_SRC
}

return
Expand Down Expand Up @@ -92,12 +95,14 @@ func (ctl *controlInterface) Config(req []byte) (res []byte) {
if _, err = loadApplet(taELF, ctl); err != nil {
return api.ErrorResponse(err)
}
} else {
log.Printf("SM received configuration update w/o applet running")
}

return api.EmptyResponse()
}

func (ctl *controlInterface) Start(irq bool) {
func (ctl *controlInterface) Start() {
device := &usb.Device{}
serial := fmt.Sprintf("%X", imx6ul.UniqueID())

Expand All @@ -113,24 +118,20 @@ func (ctl *controlInterface) Start(irq bool) {
log.Fatal(err)
}

Control.Device = device

if !imx6ul.Native {
if Control == nil {
return
}

Control.Init()
Control.Device = device
Control.DeviceMode()

if irq {
imx6ul.GIC.EnableInterrupt(Control.IRQ, true)

Control.EnableInterrupt(usb.IRQ_URI) // reset
Control.EnableInterrupt(usb.IRQ_PCI) // port change detect
Control.EnableInterrupt(usb.IRQ_UI) // transfer completion
} else {
Control.Reset()
// never returns
Control.Start(device)
irqHandler[Control.IRQ] = func() {
Control.ServiceInterrupts()
}

Control.EnableInterrupt(usb.IRQ_URI) // reset
Control.EnableInterrupt(usb.IRQ_PCI) // port change detect
Control.EnableInterrupt(usb.IRQ_UI) // transfer completion

imx6ul.GIC.EnableInterrupt(Control.IRQ, true)
}
151 changes: 148 additions & 3 deletions trusted_os/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,170 @@
package main

import (
"bytes"
"debug/elf"
"debug/gosym"
"errors"
"fmt"
"log"
_ "unsafe"

"github.com/usbarmory/tamago/arm"
usbarmory "github.com/usbarmory/tamago/board/usbarmory/mk2"
"github.com/usbarmory/tamago/soc/nxp/imx6ul"
"github.com/usbarmory/tamago/soc/nxp/usb"

"github.com/usbarmory/imx-usbserial"

"github.com/usbarmory/GoTEE/monitor"
)

const debug = true

var serial usbserial.UART
var serial *usbserial.UART

func init() {
if imx6ul.SNVS.Available() {
panic("fatal error, debug firmware not allowed on secure booted units")
}
}

//go:linkname printk runtime.printk
func printk(c byte) {
usbarmory.UART2.Tx(c)
serial.WriteByte(c)

if serial != nil {
serial.WriteByte(c)
}
}

func configureUART(device *usb.Device) (err error) {
serial.Device = device
if LAN == nil {
return
}

serial = &usbserial.UART{
Device: device,
}

return serial.Init()
}

func fileLine(buf []byte, pc uint32) (s string) {
exe, err := elf.NewFile(bytes.NewReader(buf))

if err != nil {
return
}

addr := exe.Section(".text").Addr

lineTableData, err := exe.Section(".gopclntab").Data()

if err != nil {
return
}

lineTable := gosym.NewLineTable(lineTableData, addr)

if err != nil {
return
}

symTableData, err := exe.Section(".gosymtab").Data()

if err != nil {
return
}

symTable, err := gosym.NewTable(symTableData, lineTable)

if err != nil {
return
}

file, line, _ := symTable.PCToLine(uint64(pc))

return fmt.Sprintf("%s:%d", file, line)
}

func lookupSym(buf []byte, name string) (*elf.Symbol, error) {
f, err := elf.NewFile(bytes.NewReader(buf))

if err != nil {
return nil, err
}

syms, err := f.Symbols()

if err != nil {
return nil, err
}

for _, sym := range syms {
if sym.Name == name {
return &sym, nil
}
}

return nil, errors.New("symbol not found")
}

// segfault schedules the execution context to its fatal error function in
// order to have applet dump its own stack trace and exit. The target must be a
// GOOS=tamago applet which imports the runtime.CallOnG0 symbol, runtime.Exit
// must be set to graceful termination.
//
// Example of required applet main statements:
//
// ```
// func init() {
// runtime.Exit = applet.Exit
// ...
// }
//
// func main() {
// ...
// runtime.CallOnG0()
// }
//
// ```
func segfault(buf []byte, ctx *monitor.ExecCtx) (err error) {
var sym *elf.Symbol

if sym, err = lookupSym(taELF, "runtime.fatalthrow"); err != nil {
return fmt.Errorf("could not find runtime.fatalthrow symbol, %v", err)
}

ctx.R0 = uint32(ctx.ExceptionVector)
ctx.R1 = uint32(sym.Value)
ctx.R2 = 0
ctx.R3 = ctx.R15

if sym, err = lookupSym(taELF, "runtime.CallOnG0"); err != nil {
return fmt.Errorf("could not find runtime.CallOnG0 symbol, %v", err)
}

ctx.R15 = uint32(sym.Value)

log.Printf("SM invoking applet %s handler pc:%#.8x", arm.VectorName(ctx.ExceptionVector), ctx.R3)

err = ctx.Run()

log.Printf("SM applet stopped sp:%#.8x lr:%#.8x pc:%#.8x err:%v", ctx.R13, ctx.R14, ctx.R15, err)

return
}

func inspect(buf []byte, ctx *monitor.ExecCtx) (err error) {
// print caller
log.Printf("\t%s", fileLine(buf, ctx.R15)) // PC
log.Printf("\t%s", fileLine(buf, ctx.R14)) // LR

switch ctx.ExceptionVector {
case arm.UNDEFINED, arm.PREFETCH_ABORT, arm.DATA_ABORT:
return segfault(buf, ctx)
}

return
}
Loading

0 comments on commit 3db29ad

Please sign in to comment.