-
Notifications
You must be signed in to change notification settings - Fork 53
Frequently Asked Questions (FAQ)
TamaGo is a framework that enables compilation and execution of unencumbered Go applications on bare metal ARM/RISC-V System-on-Chip (SoC) components.
The project spawns from the desire of reducing the attack surface of embedded systems firmware by removing any runtime dependency on C code and Operating Systems.
A lot of our custom USB armory projects entail developing Go applications executed under minimal Buildroot environments, typically we are asked to develop cryptocurrency wallets, HSMs, cryptographic provisioning dongles, secure storage, etc.
The USB armory and Go are perfect for such applications, but somewhat the burden of carrying over a full Linux kernel and runtime, albeit minimal, feels excessive and requires a fair deal of maintenance.
We love Go and we love for unencumbered Go applications to be executed without any C code supporting its execution, to decrease the overall attack surface, improve security and aid maintainability of the code.
For this reason TamaGo was born.
In Japanese tamago (卵) means "egg", given that we are surrounding Go just with the bare metal the name seemed appropriate. When running under QEMU emulation I guess you can call it TamaGotchi \(^O^)/.
The imx6 USB driver supports enumeration and bulk endpoints, example use cases are Mass Storage, Ethernet with full TCP/IP stack integration, CCID, U2F, Serial.
The imx6 Ethernet driver supports physical Ethernet devices.
The imx6 UART driver supports serial communication, allowing on the USB armory Mk II console or Bluetooth communication.
Nearly every standard Go application can be compiled/developed without limitations, see Compatibility for a few caveats.
Yes, there is support for interrupts on ARM.
As expected, performance is identical if not superior on a single core (for now there is no multi-core support in TamaGo).
On the USB armory Mk II TamaGo is currently capable of perform cryptographic operations leveraging, other than Go own libraries, on the NXP DCP/CAAM hardware cryptographic accelerators.
The following applications provide some examples:
- GoKey - OpenPGP/U2F smartcard
- GoTEE - Trusted Execution Environment w/ TrustZone
- ArmoredWitness - cross-ecosystem witness network
- armory-drive - USB encrypted drive
- armory-ums - USB mass storage interfacing
- armory-boot - secure primary boot loader
The wonderful TinyGo project targets microcontrollers with a new LLVM based Go compiler that minimizes the footprint of the resulting programs, to make them suitable for constrained MCU environments.
This entails that, inevitably, memory allocation, datatypes, and other Go specific behaviors are implemented in a different way and that the resulting language support differs from standard Go.
TamaGo modifications are minimal against the original Go compiler, runtime and the target application (only one import required), with a clean separation from other architectures.
The focus on more powerful hardware (SoC vs microcontrollers), with an extensive re-use of the original Go runtime and packages, entails that complete standard library support.
The Embedded Go project is a quite new effort, with a very similar approach to TamaGo but which targets the ARMv7-M/Thumb2 architecture by adding new compiler support for it within the Go runtime.
Similarly to TamaGo it adds a specific GOOS=noos
support but targeting microcontrollers, it supports threading (which is still not supported in TamaGo) and re-uses less existing Go runtime components than TamaGo.
The need to add a new GOARCH
, in addition to the new GOOS
and its threading re-implementation, makes it a somewhat more invasive (but with reasons!) patch than TamaGo other than currently targeting a different class of hardware.
The eggos project is a quite new effort, which targets x86 platforms. It re-uses the vanilla compiler by wrapping GOOS=linux
required syscalls back to Go. It represents a cool novel approach to bare metal Go unikernels on x86.
The Biscuit research OS is a research project that provides a full OS kernel written in Go, therefore meant to run non-Go software underneath.
The project definitely inspired TamaGo as it proven the possibility of adapting the Go runtime, on amd64 hardware, for bare metal execution.
However Biscuit scope is far larger than TamaGo, which remains a focused effort to purely run a monolithic Go application on the bare metal, requiring a less invasive approach.
Unlike Biscuit, which hijacks the GOOS=linux
support, TamaGo places strong
emphasis on code re-use from existing architectures already included within the
standard Go runtime while cleanly separating them with its own GOOS=tamago
.
Additionally TamaGo does not require any C intermediate bootloader or 3rd party initial bootloader (such as U-Boot), both needed by Biscuit, as the compiled application can be natively executed.
See Internals for more information.
The G.E.R.T. project is a Biscuit based modification which aims to achieve a similar goal to TamaGo.
The Go runtime modifications applied by G.E.R.T. are however fairly extensive for the required task, Biscuit concepts are adapted to the ARM architecture with a rather extensive overhaul of the runtime, also to include multi-threaded support which is not initially sought by TamaGo.
Unlike G.E.R.T, which hijacks the GOOS=linux
support like Biscuit does,
TamaGo places strong emphasis on code re-use from existing architectures
already included within the standard Go runtime while cleanly separating them
with its own GOOS=tamago
.
Additionally TamaGo does not require any C intermediate bootloader or 3rd party initial bootloader (such as U-Boot), both needed by G.E.R.T., as the compiled application can be natively executed.
G.E.R.T. greatly inspired TamaGo in proving the feasibility of an ARM port of Biscuit, however TamaGo provides a much simpler implementation with minimal modifications to the Go runtime.
See Internals for more information.
Well why not both? :)
Someone is already working on bare metal Rust for the USB armory Mk II.
The TamaGo project spawns from the desire of being able to use Go excellent cryptographic primitives on embedded systems, without carrying the burden of a full blown OS.
The TinyGo FAQ has an excellent response to this question.
The TamaGo modifications as clean and isolated as possible to allow easy upstream merging, despite this the Go core team declined our proposals for official inclusion (#37503, #46802).
For now TamaGo patches against the standard Go distribution remain maintained as an out-of-tree port, with our commitment to consistently keep them up to date.
On real hardware GDB and JTAG are available.
On emulated hardware, such as QEMU, GDB can also be used.
Additionally networked applications can use Go pprof as usual.
I want to compile on the USB armory Mk II itself, can I cross compile the TamaGo compiler for it to save time?
We prepare binary releases for this purpose, if you want to cross compile your own here's how to do it:
git clone https://github.com/usbarmory/tamago-go && \
cd tamago-go && git pull && git checkout latest && cd src && \
GOARCH=arm GOROOT_FINAL=/usr/local/tamago GOARM=7 ./make.bash && \
cd .. && mv bin/linux_arm/* bin/ && rmdir bin/linux_arm && \
rm -rf pkg/linux_amd64* && rm -rf pkg/tool/linux_amd64 && \
tar -c --transform 's+^./+/usr/local/tamago-go/+' --owner=0 --group=0 -f ../tamago-go$V.linux-armv7l.tar.gz -v -z --exclude .git .
Start developing drivers and send pull requests!
Of course!
This is precisely what we do at WithSecure Foundry