Dear viewer, these subtitles were generated by a machine via the service Trint and therefore are (very) buggy. If you are capable, please help us to create good quality subtitles: https://c3subtitles.de/talk/1285 Thanks!
[Music]
next speaker was 12 years ago at a
conference in Berlin that shall rename
unnamed where he presented an automotive
car hacking talk before it was called
car hacking where he injected RDS
traffic and could reroute your
navigation system luckily he's no longer
breaking cars but instead well went on
building secure stuff and for one of
this the USB armory that you might have
heard of he has now come up with tamago
a full bare metal go runtime for your
secure software development needs please
give a warm round of applause to Andrea
Bargnani
can you guys hear me yeah okay thank you
for the introduction thank you for
reminding me how old am i and and yeah
so we still break cars but just just we
that's that's work now and not fun
anymore and the fun stuff is actually
this one so but we still we still break
cars actually so I worked for f-secure
just a little bit of introduction about
myself I work for f-secure and I some of
you might know me for a company which I
found it which is called Umbra stuff
which was acquired a couple of years ago
but I've secured I'm I'm one of the
offer of the USB armory and yeah as as
as it was mention introduction I work a
lot with hardware and abettor systems on
safety-critical systems such as
airplanes cars industrial systems and
and so forth and because I'm I'm I'm
getting old basically now I tend to like
to build things to make things rather
than only breaking them I think this is
a inevitable phase in the life of
information security researchers and
because you get all that you you get a
little bit tired of just pointing your
finger at things that are broken and and
at some point the industry becomes so
good at breaking things that I think
that we also should stop a little bit
and think about creating
tools hardware and software which can
really serve the non-security community
better into into solving all kind of
security issues because we see that
there are a lot of issues that they
never change despite the fact that we'll
almost see in 2020 and one of the
motivations for us into building open
hardware such as the USB armory and
tamago which is directly linked to the
USB armory as you will see it's also to
provide better tools tools that are
maintained that word that are clean that
are trusted and I think this is a phase
that a lot of information security
researchers at my age now are getting
through which again is just a guess
getting old
so the USB armor is an open hardware
computer which is meant to be a secure
Enclave in a very very small form-factor
just a USB device and and tamago is
based on our need to build software in a
better way for for this device so the
whole inspiration comes for the for the
journey of creating of creating this
hardware and and it comes form from from
a very simple scenario that we face
while testing all kind of a better
system so I'm a strong believer of the
fact that just like natural language I
mean if any of you want to code for a
specific device in whatever language you
like and you prefer you should be able
to do it and if that language for some
reason its implementation generates a
compiler which is not fast enough for
you to have a successful project on any
piece of hardware that is not
necessarily your fault or it shouldn't
be your fault in choosing the wrong
language it shouldn't be any wrong
language the language should be adapted
to your knee to your style as a
programmer as a developer we should in
an ideal world
care or not care at all about how the
compiler is optimized or not in an ideal
world all compilers should generate
machine code with the same efficiency
you know if you like to do math in
sequel queries or in
rust - assembly whatever in an ideal
world in like a Star Trek USS
enterprise-e world it should all
generate the same the same bytecode
because the intention that you're giving
to the code remains the same you want to
do the same operation however we don't
we do not live in an ideal world we live
in a real world and this means that
developers to make the choices that they
need to make in selecting framework and
languages they really need to be careful
about the implementation that the
language is reflecting the
implementation that the language is
supporting that the hardware that is
supporting and this is not idea so
usually there are very two distinct
scenarios we have hardware we test
hardware for a living that has lower
specifications microcontroller units
which are used because engineers want to
simplify our design or they want to save
money on the parts whatever the reasons
and the only practical choice or the
only real-world choice for programming
on these devices in an economy
production system is by using unsafe
lower level languages which is typically
means Mincey and so we tested in our
word cryptography tokens wallets
Hardware diodes that play a very
important role in to ensuring separation
of safety boundaries on things like cars
and planes and all your lower
specifications IOT and smart appliances
they all have firm worth at the spine
despite doing operations which are
pretty basic they're all written in a
language which is unsafe from an
implementation perspective on the other
hand if we have hardware with higher
level specifications we can code in
pretty much anything we want but but we
need the support of a complex operating
system to do that so if we have a system
on chip and we can run go Python
whatever higher-level language on it
we're just shifting complexity around so
the complexity and D let's say unsafe
Ness is taken away from us as a
programmers but it's distributed
everywhere else in the stack that allows
us to run that code because we're gonna
have a Linux system we're gonna have a
lot
drivers that maybe we don't want we're
gonna carry on millions of lines of code
that are not strictly necessary for the
task that we're doing and as we know
complexity is an enemy of of security
and if I want to program assist them in
a higher-level language I just don't
want to put all of that complexity under
a carpet and have it there running
underneath me I just wanted to go away
as a security person that's the reason
why I pick a higher-level language so we
face these two scenarios and none of
them is ideal and so also in this case
now we see a shift or system on chips
away from microcontrollers also in
avionics in in any kind of system which
needs to be a little bit more complex
your home router higher specification
IOT and smart appliances and we also see
which is quite common despite having
this power and the underlying OS we
still see see applications running in
users based on this system your
infotainment system is very likely to do
that even if there's no good reason for
doing so and we pop them all the time
because inevitably C is a hard language
to code with we should realize that no
matter if you are C lover or not it is
now vastly proven that is very difficult
to to to have production grade code done
by you know a lot of developers to be
safe because it just takes too much toll
on the effort for making it safe so our
penetration testing right from this kind
of system is always 100% and as we built
a system on chip base hardware we didn't
want to to face these situations we
didn't want to write bare metal code in
C and at the same time we didn't want to
have our higher level language
applications running under complex
operating systems and our goal in doing
this is to reduce the attack surface of
a metal system we don't want to carry
millions of lines of code that we feel
are unnecessary we want a system to
perform only the very minimum or what we
to do and we think that this can be done
by removing any dependency whatsoever on
C code or complex operating systems so
we want to avoid shifty complexity
around or having complexity hidden from
us and we want but we want to run a
higher-level language such as go
directly on the bare metal and that is
the motivation for tamago which is
directly inspired by creating the use
USB armory in the first place now of
course a lot of you I mean I would
assume that some of you know go here and
a lot of people are thinking why not
rust and we're gonna get to that but the
point here that we're gonna we're trying
to make with this project is why not
both we want people to have the choice
of using the language that they want and
since and since we want to use go that's
why we created this this framework so
why go so first of all disclaimer
because I know when we enter into this
these topics a lot of flame wars people
have feelings I have feelings you have
feelings everybody's feelings about
languages and so forth so this is not a
talk about saying that language X is
better than language y know I'm not here
to say that goal is better than rust I'm
here to say that we think that certain
languages which have less of a chance
now to succeed on bare metal
applications they can have this chance
so we want the ecosystem to be more
diverse and this is why we made this
effort but it's not to say or to force
you or to tell you that go is better to
rust in fact we want you to have the
choice and want to give a choice of goal
which wasn't present in the past so if
we look at speed versus safety access so
to speak also this is not to scale if
you know Russ if you're in lobbying Russ
you might decide to place the our of
Russ in a different location on the
chart and this is absolutely fine again
this is not to scale scale its
projective here but we all agree that if
you would draw a line go is something
which is of course lower than rust in in
its end result but it's easier to a
certain extent to learn the learning
curve is certainly easier more shallow
on code and then on rust Russ of course
is much better than si
of course it's a safe language and if we
go on the other side of the spectrum we
have C which gives you more control more
Hardware control but it's also hard work
to implement correctly and now we are a
situation where languages like NGO which
are fairly fast and there are much
faster than languages such as Python or
Ruby so they can really be used to
create binaries that run on embedded
systems however there are a little bit
attached from the hardware so if you
want to add a run on the bare metal or
make firmware that it's low level
they're not ideally suited for now so we
want to somewhat fix that at least for
for the go language and one of the
reasons why we want to do this is
because this is the typical setup of a
secure firmware that we make for other
the USB armory or other kind of a meta
systems we have a bootloader which is
secure booted by the hardware by the
system on chip so we have the first
stage of indication of the bootloader
and then typically the bootloader fanta
kate's and loads a Linux kernel image
because that's the operating system that
most people use and that's your Purdue
system which at bootstrap the whole
decryption procedure for let's say that
you have an encrypted partition and so
forth and maybe it has drivers it
communicates with the system on chip to
get some key material uniquely derived
from something stored only in that chip
so this is a typical chain of secure and
verified boot to achieve authentication
of all your code and also
confidentiality of the data and the
problem is that we're typically faced
with a scenario where we're developing
something let's say a cryptocurrency
wallet or whatever crypto related
firmware and now we code it in language
like go and we have very few lines of
coding go a few thousand lines of code
we use a standard a library of go for
everything for TLS for crypto so we
minimize the fur party dependencies and
we have a code which is clean and nice
however in order to boot this image on
something like the USB armory we need to
carry around a Linux image to do fairly
simple tasks such as the Krypton
something talking to the system on chip
doing USB and then launching our Co
application so in the end - ah
it's kind of an elegant the fact that we
spend so much time simply fining
cleaning up the code of the firmware and
then we need to carry a giant operating
system compared to what we need to do
and we need to update it very often
because despite the fact that you only
have a few drivers that expose you still
want to keep it up-to-date because you
never know and of course you also have
user space tools which mean you can try
to reduce them as much as you can use
busybox you use a framework for
generating compact Linux images such as
build route and so forth but feel it
feels it doesn't feel the right thing to
do this could be more optimized and
while this is an example for the USB
hammer it applies to pretty much all
kind of a medicine that we test and have
some sort of secure routing and so forth
they all follow the same pattern we're
using a system on chip so what we really
want to do is take go and move it down
there on the axis so we want to keep the
same ease of and speed ease and
efficiency in development but we want to
have more Hardware control which also
means that we want to kind of remove
this red box over there we want to take
away the millions of lines of code that
we don't own that we don't maintain that
we're kind of stuck with so this is the
idea of of tamago so of course this is
not a new concept this is known as
unique kernels or library operating
system which are single dress images
which typically run under the bare metal
and their focus is to reduce the attack
surface the problem however with
available unique kernels is their most
of them not all of them there are
so-called fat unit kernels because so
first of all a good chunk of them is
just again hiding complexity for you so
there's a good portion of unique kernel
projects that they give you an API and
documentation and they tell you Luke
you're going to develop your application
you're gonna compile it and then that's
gonna be executed but in the end they do
have an actual kernel underneath which
sometimes it's even derived from fairly
complex
operating systems such as nak bsd and
FreeBSD and the whole framework just
puts you it puts a lot of us proud
abstraction layers in the middle so that
you don't see the kernel you don't see
the wrong time and you just deploy your
application now this is all well and
good but from a security standpoint this
doesn't really solve the problem in fact
I think it creates the opposite problem
so while are we searching for this talk
I kind of looked at all the unicrone of
projects that are around and for most of
them it was really hard to find which
kernel they were running and the
documentation kind of gives you the
illusion that there are this magical
bare metal project but they're actually
not a lot of them they just pull in code
from that BSD of FreeBSD most of them
they are based on fur per party kernel
such as meaning us which is granted it's
it's it's it's a written in C still but
much shorter and smaller codebase that's
something like FreeBSD and also most of
them they are actually not focus on the
bare metal in the sense that they're not
focused on running on embedded systems
but their focus on running on the cloud
and so they all support hypervisor such
as Zen which is not what we want to do
on a meta system so for all of these
reasons the existing most of the
existing unit current projects they're
not really suited for embedded system
developments and they don't achieve what
we want to achieve which is kill see I
don't want any dependency on see written
code whatsoever while I've in my thermal
running and if I'm gonna have a
hypervisor or if I'm gonna have a kernel
written in C you know you can abstract
that as much as you want you can hide it
but it's really not gonna solve the need
that I have so this is really not what
we wanted the other problem is that this
when it comes to security
these unique owner projects and rightly
so they want to support arbitrary
application so they want you to be able
to compile your application in whatever
language you want and then to execute it
or they also want to be able to be kind
of OSS and then provide support from
to applications but the thing is if
you're having multiple applications and
different trust domains under a union
kernel or if you're running an
application which is written in an
unsafe language like in C you kind of
want an industry standard OS because you
kind of want outer space layout
randomization you do want a stock
inori's you what you do want all the
security features that are the good
parts of complex operating systems and
that are there for you so we think in
our approach that unique kernel such as
this one so or at least we are
interested only in unicorns that allows
us to run bare metal on embedded systems
and we want to run a single higher-level
language on that unicorn we're not
interesting to everything else because
for everything else we think that
actually maybe operating system are a
little bit better so we don't want to
focus on the cloud we don't want to rely
on an eye provider and and again I
explain why we choose go is what we use
a lot and so we wanted to give go a
chance because we think it has a shallow
learning curve so productivity can be
very good we'd go and in also primarily
it has a very strong cryptographic
library that we want to use and again
russ has already proven that as a role
in the bear mental ward so we it has
nothing to prove and it's gonna succeed
as well but goal doesn't have the chance
and that's what we want to give to go
this chance because we think it really
can and we're gonna we're gonna we're
gonna see why so in a nutshell what
we're getting to try to achieve because
the other message of this talk is that
it's important how you do it not only
what you do because anybody can run go
anybody can can understand that with the
right effort you can put go on the
merrimette oh it's fine but the problem
is how do you achieve that because
there's a there's an element of trust
there so and we're going to get to that
so tamago is the idea is that we want to
find the path of least resistance in
patching the go compiler we want a patch
which is absolutely minimal to cleanly
enable support on the bare metal so our
take is to provide a different OS
variable to to go so normally in go you
have got to specify whether you're under
Windows
Linux or other operating systems so we
created a separate goal as support in a
minimal patch to enable that on the ARM
architecture so that we can run the
runtime on bare metal so this is one
part of tamago the second half is a set
of packages that provide support for
hardware boards so the driver so to
speak so right now we have support for
the USB armory system-on-chip which is
actually a widely used system on chip so
it's not just specific to the USB armory
which is a member of the NXP imx6 family
and we're going to target more more
platforms in the future and our goal for
doing this is again to develop security
applications using the existing open
source tooling that we have for signing
secure boot images and so forth for for
the USB armory so there have been
similar go efforts in the past and there
are similar go efforts right now but for
a variety of reasons they all didn't
quite fit what we needed to do so we had
two projects mainly which are now
maintained there was a project called
bisquit which wanted to actually create
a kernel OS kernel ingo so the idea
there wasn't just to support grow
application or but to support any
application written in any language with
POSIX compliant interfaces and so forth
this is a maintain there's a lot of
complexity to the project because they
redo memory allocation and fretting and
so forth and they eject the existing go
ass Linux support despite not running so
for these reasons it wasn't exactly what
we were looking for
it was another project I maintained
which is called Girt which is an arm of
the patient of bisquit for running
actually only go up occations again in
Ajax go as Linux and as more complexity
to it that what we want so that's also
something that is not treated for what
we wanted there's an are a nice project
called admin OS which was presented I
think three years ago which is kind of
similar to tamago aware where it targets
the Zen I per visor and has limited
runtime support which is also some of
you know we don't want now of course if
you if you like go if you know a little
bit about about the ecosystem you of
course might know about tiny go which is
active and rocking it's a great project
however
for our purpose tiny goes not is not
quite what we wanted because it's a
complete different reimplementation of
the of the of the co compilers it's a
different companion or the original one
and because it targets microcontrollers
and not system on chips it provides a
different runtime with a more limited
language support so it's not quite
having like vanilla vanilla goes it has
a different a different focus and then a
brand new which was actually published a
few days ago we have embedded goal which
is a kind of a new project which targets
also microcontrollers and the thumb
architecture so it adds actually adds
new compiler support for it because arm
v7m is not native to go so it adds an
oos go as for the fum architecture so
again it does something a little bit
different than what we do but it's
actually quite an interesting project so
we're gonna keep a close eye on that so
all of these projects despite whether
they are maintained or not or whether
they are complex or not and they do what
we like or not they really helped us
improving that these can happen so
throughout our project we our our our
approach to it is not that we needed to
understand if this was possible we just
needed to understand if this was
possible without polluting the compiler
if it was possible to do cleanly enough
and all these processes gave the
assurance that this can be done so we're
really grateful to all the people that
put their effort into into these
projects so I'm are I working in
information security so to us and we are
kind of entering in for me at least
entering in a territory which is just
you know compiler and languages and so
forth so it says read a new domain for
us but we want to to bring over our core
principles which is enabling and they
believe trust and we see that there are
a lot of projects you know most of
unique kernel projects is something that
you would never see in production really
nice like from a technical perspective
they're really people that they they do
something they believe in they have
passion and they they push the
boundaries of technology but are you
gonna find those in production well not
not so much so we want something that is
done in a minimal clean and trusted way
that is good enough to be eventually
accepted upstream because
so our final goal so we wanted really to
find if we can link Apache original
companion in a very minimal way and much
of the effort has been placed in that we
didn't want to pollute the go runtime to
levels which we think as security people
that are unacceptable less is more that
was the model of our effort we want to
have the least number of modifications
still readable of course that it would
make sense so that we'd match the
existing style structure of the way the
go development team is working because
also this leads to code which is more
verifiable and it's more maintainable in
the future so we design it for an ID
protocol upstream inclusion in the
future so we're working for that and we
have a commitment to always sync against
the latest goal release in the end we
ended up with about three thousand lines
of code of compiler changes and that's
it in order to support runtime and
enable the additional goal ice
architecture we play strong emphasis on
reusing code which was already there
within the go compiler framework and the
final goal is for developers to be able
to use this just by having one import in
their code and that's it
if you don't need to use the hardware
you don't need to know about hardware
and we want to support unencumbered your
applications like no limitations ideally
zero limitations in the end and also the
compiler is only half the story we
provide drivers so that you can actually
run this on hardware which these days is
is relevant and by using also the
original go compiler we do inherit nice
properties such as you know go compiler
itself hosted can compile itself has
reproducible builds so these are all
nice things that we do want when
creating our for more code so we have
three different categories of go
compiler modifications that we've done
we have what we call glue code which is
merely code that just adds the tamago
keyword to a source code that needs to
be compiled so this code has no logic is
very benign it's just stubs and
definitions where we say there's a new
architecture and it's named tamago and
so we apply
all the lists which are required to
enable this this support so this is
about 350 lines of code across many
files so we changed many files but the
changes are really really tiny and
really they have no impact whatsoever on
the stability or security of the code
then we have a second set of changes
which is the bulk of it which is about
two thousand seven hundred lines of code
which is reusing existing code within
the go runtime to for execution on the
bare metal so I'll give you an example
and this is what I call the go
Frankenstein because it was like
creating a Frankenstein monster but it's
much better than what it sounds it's not
exactly as Frankenstein how actually
works so memory allocation a lot of
projects that try to put the Garant
among the bare metal they completely
implemented memory allocation of reading
and we just saw that this the memory
allocation for plan nine which is
included in go runtime I maintain and
with one line changed we can use that
run on the bare metal because at some
point a plan nine memory allocator just
use the vrka cisco to allocate memory
power running on our metal we have our
memory space so we can just you know
allocate pointers from it and so with
one line of change we can use all of
that code which is right there test
sentiment ain't for locking structures
and so forth so there's a locking code
within within go long which is for the
web assembly primarily and we can use it
identically and the nice thing about
this code is that it has three functions
which hook into the external OS and
we're gonna use those to implement
proper timer support and nice thing is
that we can keep a clean separation
between what we need to do to run things
on the Mary metal and what go already
has within its code and it's nice to do
that rather than just hacking and
changing go code it's nice to have nice
entry points for doing things which
touch the hardware a little more and
then we have an in-memory filesystem for
now but this is gonna change soon in the
next months because we're gonna add MMC
and fat support which is actually quite
easy to do but there's a memory file
system with not
which we just copy over we enable afford
time operating works and this is
actually the bulk so there's a there's a
lot of there's the highest number of
line of codes change because we because
of the way the compiler works we just
need to copy the mem underscore plan
nine go file into mem underscore tamago
in order to to use that code and then we
have new code which is about six hundred
lines of code in file find twelve files
which is tamago specific functionality
and it mainly provides initialization of
the arm core so this is all code which
is fairly standard you will find it in
in any US any boot loader and so forth
and then we have a code which provides
hooks with your application and the
board package to understand how big is
the memory and what's the offset of the
memory and so forth so all of the
changes like surprisingly it was real
surprise to us that go the go runtime is
almost free standing on its own with not
a lot of dependencies on the actual
operating systems apart from system
calls that we're gonna see now so this
is the extent of the modifications that
we need to do to run go on the bare
metal or at least to have a compiler
which allows us to to do that this is
the memory layout that we use or your go
application lives there in memory we
have a heap stack and interrupt back to
our table and so forth so all of this is
pretty standard and we use all the
available Ram depending on the board
that we have so because only go runtime
supports so basically there are there
are three components here we have the
support within the go runtime itself so
this is an example of what happens in
the file
OS tamago arm dot go and we see that we
have hooks we have variables and
functions which needs to be defined
externally by the application so we
don't want to put information about all
the different boards all the different
hardware and the hardware peripherals
within the go runtime we don't want to
pollute it with that so we have one
generic function for Hardware
initialization we have a function for
printing on the console and we have a
function for getting random data and and
forgetting takes which the run
time expects the external board package
to provide and the same goes with the
offset for the forum for where memory
starts what's the offset and what's the
size and then the rest of the code in in
this file is just architecture related
initialization so not specific to a
board but just arm initialization and so
forth so this is this is part of the
goal compiler modifications then we have
the system-on-chip package which is
actually very simple because the only
thing that it provides right now is in
relation to aux with the runtime the
variables where the memory starts and in
the offset of the stack and then we have
the board package which actually tells
what the size of the run because the
start of the memory is gonna be the same
for the a specific system-on-chip
but if you have different boards you
might have more RAM so the actual size
is specified in the board package and so
for instance here in the USB armory
package we say okay when I want anything
to be printed out on the console the
console for the USB armory is actually
the second UART the second serial port
so that's information belongs in the USB
USB armory
package so this allows us to have
minimal modifications in the go runtime
to have what belongs to system-on-chip
specific information in the system on
chip related package in this case the
imx6 ul package and any information is
specific to the board we have it in the
board Support Package so in this case
the USB armory so this is the clean way
for doing it
another example here so if we have a
timer definition so we didn't the go
runtime at some point going needs to get
ticks or to understand what's the time
and that's provided externally by the
imx6 package which provides support for
the generic timers for the for the USB
armory because that's what the
architecture provides and we can also of
course mix assembly when it's required
this is something that already happens
single it's not something that we're
doing only ourself is something which is
come on an accepted and it's the most
efficient way to deal with very low
level aspects such as getting timer
information so all of this is
initialization code which accounts for
about 500 lines of code so not so much
and again it follows existing patterns
in the go runtime so this is an our
example here we are at some point so we
were developing and we saw that code was
running slower than expected and we were
like oh wait a minute we need to change
the clock speed because this
system-on-chip by default is clocked at
about 400 megahertz and if you want to
run it at full speed not under maegor's
we actually have to do it ourselves like
the bootloader doesn't do it the
bootloader always sets the default
frequency and so we quickly coded ingo
within within our board package actually
within our system on chip package the
function for setting the frequency and
this is what a driver looks like and go
so we have our our functions for setting
registers so here we set the PLL
register we set two bits to 0 at this
offset it's kind of what you sorry it's
kind of what you would find in C but you
know just by just by using goal we can
wait for a value to to become 1 because
we're waiting for the lock on the clock
here we're removing the pipe ass that we
need it for changing clock we set a
divisor and so forth so you know you can
write drivers and go and then the
interesting thing about when using
memory safe languages on on the bare
metal is that every time you need to do
something which is not safe you have a
specific keyword for that so you can go
like in other high-level languages you
have the keyword unsafe so if you want
to scout and look for all of the
potentially dangerous places in the code
where you're doing something which has
point arithmetic you can just grab for
it you can just search unsafe and you're
gonna find all the occurrences and where
you're using the finding or do a pointer
arithmetic and because you do need to do
that for drivers but at least it's very
easy to identify those within the code
that's also something which we thought
was really nice about about about using
a higher-level language such as this one
concerning Cisco so the go runtime makes
direct use of Cisco's for
a lot of functions and this was our main
concern
do we need to emulate and about 50 seals
call system calls in order to have the
runtime working and it turns out that
only one is actually really needed which
is right which is the one that
eventually gets hooked with the print
Kay function so now we support the right
system only for standard output and
standard error and we use that to print
to the console because that's the only
thing that you actually need on bare
metal I mean you're either of writing on
our file descriptor which is handled in
a different manner within the go runtime
with the file system but if you want a
bright to standard output I mean on
these classes or devices you don't have
a screen so you have a console and
that's and that's what we do in the
board package and if anybody wants to do
something different with that in the
board package which again is outside
that compiler you can define whatever
print K method method you want so in the
end this is what it looks like so
normally you would have your go runtime
running under user space under a complex
OS the go runtime would make system
calls and then the kernel space with its
drivers will be able to serve them talk
to furry files and so forth with tamago
we live in a go ramping process your
package is linked with the runtime the
system-on-chip and the board packages
are also linked and these are the ones
that support the driver and the go
runtime every time a system call is made
which in this case the Rice's link on it
is just hooked to the actual driver
suppose within the go package but we are
all within we didn't go and we use the
vanilla go runtime with exception over
of a few initialization and runtime
support function which are only specific
to tamago which are the ones that are
actually serving system calls and and so
forth so this is this is the change and
again we're dramatically reducing not
only the lines of code count but we are
completely eliminating C because in this
set up the only C is actually the
bootloader which it goes away after boot
but anyway we're also working on
replacing that but there's no C involved
not a single line in all this so how do
you develop build and run this thing
well so in order to use it you right go
as you always did and you just import
the board package that's the only thing
that you need to do if you're not using
the drivers specifically that's the only
thing you need to do if you want to use
a driver like random number generator or
USB then you also need to import that as
you wouldn't go but to run basic
operation that's the only thing that you
need so that's the first step then you
compile we'd go build as usual with the
exception of a few flags to the linker
where we need to tell and this depends
on the board what the entry point is
going to be and where are we gonna have
the text of our the text segment of our
application but that's it so we have go
ice tamago arm7 will our charm and then
we just you use go build so tamago here
is a variable where we have just to go
to go run time compile with tamago
support and then this is you boot
bootloader you just load the resulting
elf that's it there's no intermediate
bootloader needed it just you would just
run this application as you would a
kernel so we implemented drivers
security oriented drivers for our system
and chip to prove ourselves that this
can actually be use and this was an
important part of the process so the
imac six ull which we use on the USB
armory has a few security drivers that
we needed to enable so the first one
that we developed was for the data
coprocessor which is the element that
allows you to do encryption and
decryption and key derivation with a
hardware unique key which is fused at
the first power up of the system one
chip within the chip it's use you cannot
read it you can only use it and it's
unique for each chip so we wrote a
driver for that the driver takes about
240 lines of code which is I think 10
times less than the Linux kernel module
for this and then if you load its
package you can just invoke the rive key
and you can derive a key using using the
hardware it also the text if you're
secure booted or not and also note the
nice thing
that we can use structures that we
create and go so they can be made see
compatible with a little effort so you
can use them too and pass them to the
actual hardware to the memory so that
data can be allocated so we just we just
allocate a structure here and then we
actually pass a pointer two things to
the structure and it just it just works
here at the bottom here we're actually
writing the address of our goal
allocated structure to register to the
hardware register and then the hardware
we're gonna fetch the structure and do
and do its work we wrote the driver for
the random number generator there's a
true random number generator within
within the system on chip which can be
used is useful for the very first boot
when you because this kind of Hardware
doesn't have a battery there's no real
time clock so the very first boot you
don't have any you need an initial seed
and this is this I could use for that
and so we also brought 150 lines a
driver for this and we hooked it to the
crypto run function of go so you just
use go normally and the random number
generators if you use crypto run they're
gonna come from this then I've wrote a
USB Driver which it's something that
makes you question your life choices I
tell you where you're at that point in
your life that you're writing almost 40
years old in your writing USB driver
however my only concern was breathing
and studying reference manual Odyssey
wasn't dealing with with C and memory
and so forth so actually go really
helped me keep in keeping me happy
because I could use go routines I could
use channel like we use mu taxes
whenever I wanted so it was a delight my
only problem was actually understanding
the reference manual and when developing
drivers would go there's only two
aspects that you need to care about
which are unusual for go programmers
because they never have to deal with
that you need a line structures in
memory because most hardware will refuse
to load data from an aniline pointer so
we created a class for that and to keep
the garbage collector epi you need to
carry around the underlying buffer which
allows us to do the buffer alignment but
again that's the only concern that you
really need to take care about and so we
have a full driver
we also for ever driver
we do every everytime we touch the
hardware we put the page number and the
name and the section of the reference
manual because trust me on that by
looking at code from the Linux kernel
and other projects there were so many
quirks that if there would have been
just one comment to the right page you
could save yourself hours of just
learning so if you want to learn about
system-on-chip and driver development we
also put all the references that you
need in order to understand what's going
on and I think that's something that's
missing a lot into into kernel modules
these days
USB networking is so once I had the USB
driver we implemented USB networking
into ours that was easy so half of the
code is just defining the scriptures and
then we define two functions for
transmitting and receiving Ethernet over
USB packets and we have the two
functions and we hope them to Google net
stack which is a very nice full go
tcp/ip stack made by Google and so we
just we just pull that in and now I'm
going to show you the demo of all of
this if the demo gods have been kind to
me so on the left side I'm gonna boot my
USB armory with tomorrow so this is
tamago running so what it did in in in
these few seconds the bootloader booted
directly into into go self-test of the
random number generator we changed the
clock speed we say hello because we're
polite we launch seven go routines we
derive the key we ratify me memory
we slept 400 milliseconds let's just
make sure that that timer implementation
is correct we we generated a few random
numbers we made a few CBSA's signatures
we signed Bitcoin transaction the go
routine completed then we allocated
about 1.5 gigabytes of memory just
because to check that garbage collection
works and now we are waiting for USB so
if I plug it in into my other USB armory
I have a USB armory connected to the USB
armory very meta so now the USB
descriptor is being has been evaluated
and now we already see network traffic
so if I connect
to my USB armory now so hello this is a
simple UDP echo server I can ask for a
random number I get in the back the
memory and I can also do this I can
stream Star Wars in ASCII
anything's not as move as you think it
should be the problem is not the armory
it's actually Windows which doesn't
support console very well so so so yeah
all of this except for the boot part
except for the bootloader all of you're
seeing here USB tcp/ip handling
streaming everything there's not a
single line of C code involved it is
pure go and little assembly and I think
that this is I think this is pretty cool
I don't know what you but yeah so
performance we'll see if the movie ends
while we go so performance as expected
the speed is the same compared to
running the single application under
Linux so this is an example of ECDSA
signatures from the goal compiler test
suite running under Linux on the same
hardware and running under tamago and
the times are actually identical because
you know and and this is this was
supposed to be it's supposed to be add
our identity or even faster because we
have less overhead from the operating
system doing content switching there are
a few limitations there very few and
we're working on them so first of all on
this Hardware single threaded so if you
have a tight loop and you have functions
in this tight loop which don't go back
to the runtime it's gonna be stuck
forever there this is not unique to us
this is what gold does every time you
have a maxbox one and your single
threaded so this is expected and roam on
and you can also avoid it by the way you
can you can force invocation to the
scheduler in tight loops but usually if
you have really tight loops that don't
do anything it's just because you're
testing tamago not because you're
actually doing real work we have to
implement filesystem storage services
and support in storage so we're gonna
we're gonna do that if you're import a
package that needs something which
requires an OS such as terminal console
and so forth is not going to work but
that's expected you can link if you want
C code but why would you after my talk
right but you can if you want as long as
it's free-standing
there's no ice there's no users there no
signals there's no environment variables
this is a feature not a bug
so with expression are the few surprises
again go is surprisingly adapt to run
on bare metal and now we're gonna use
this in the future to write the secure
firmware that we want we want to write
HSN's crypto currency wallet
authentication tokens trust and secure
monitors and much more this is the
baseline for developing secure
applications on this kind of hardware so
again we learn that we can reduce
complexity not just shift it around we
kill C completely at least in this very
specific implementation and again it's
all about enabling the choice of a
language which didn't have much chance
of the bare metal but now we think it
does and we just wanna in the next
months to build trust with this and
maybe have it accepted upstream so
thanks to all these people that enable
us to do this project and now I have two
minutes for questions help
just one couple of questions thank you
so much
Thank You Andrea perfect ending time
1337 so we still have 13 minutes for Q&A
so if you want to ask questions we have
three microphones please line up here
microphone 3 is actually equipped with
an induction loop if you're using
hearing aids and I get a signal we have
questions from the signal angel in the
very back from the internet hello I have
two questions from the internet from the
IRC the first one is does the garbage
collector somehow cause performance
issues on bare metal no not in our
experience and also when working on the
bare metal if you really want you can
also turn it off I mean that's something
that go always had you can turn off the
garbage collection if you want and you
can run it either at very specific times
or if your application is short-lived
and as predictable memory allocation you
can also decide not to run it at all it
really depends what you're doing in our
experience for the operations that we
need to do we never stumble into
problems and its performance and
behavior is pretty much the same that
you would see on normal application
running under normal eyes there's
actually no difference we're not
changing its behavior okay thank you the
next question
the next question and the last question
is is tamago suitable for real-time
applications and if so how much I think
that by disabling the garbage collection
possibly it can I'm not a big fan of
real-time operating systems in our work
experience every time somebody uses a
real-time operating system they have so
many bugs anyway that the real-time
parts wasn't really working really well
and actually they really didn't need it
but of course there are some application
and financial applications where you
really need it if you have the time and
effort for that rust is probably a much
better suited language for that having
said that I think there might be a
chance that by turning a garbage
collection of this can also be worried
because in the end the result is very
predictable
if you don't garbage collection off
next question from microphone number one
please thanks for thanks for a project
three small questions first do usually
look at the assembly which you have
after compiling on your place from
second go is very famous for fighting to
have some fighting of your applications
on your platform and the last one did
you find any bugs in go run time while
porting on new platform so yes we look
at the assembly we also use the go
assembler ourselves the generation is
identical again to what you are with
normal go on x86 or sorry with arm the
difference is that runs on the bare
metal so but the efficiency that you're
gonna get when compiled it is the same
because we're not touching that we're
not touching the go assembler we just
use it the second question was in
fuzzing so we want to use this to fuzz
USB actually one of our projects is to
implement a low-level USB fuzzer with
the use memory that can fuzz the hosts
we're also trying to understand how we
can integrate fuzzing of this externally
we'd go by using go fuzz but yes it's
something that we're thinking of and the
third one did you find any bugs in yes
I'm itself yes in fact if you look when
you get the slides just just look at
this slide there's a fun go bug in the
in the top right in the bottom right
corner about the garbage collection so
yeah we found at least one it's it's a
it's a weird property but yeah we found
one but we have were working with the
people that work on the go compiler for
a living and they're being so supportive
so so yeah but it's not a stopper knot I
mean we didn't find anything that was a
show stopper for us Thank You excellent
thank you we have another question from
the internet by our signal angel yes
there are three more questions I think
we have time for that one okay then we
take you get all three but just one not
the easiest one okay how suitable would
tomorrow be for writing code for other
microcontrollers for example 32 you for
so for microcontrollers just go with
time ago because the footprint of
applications built with the stander go
compiler is really large so tiny goal
which is a great project as a very good
reason to exist
so for microcontrollers pantego system
on chips tamago that's separation next
question microphone 3 please thank you
very much for the talk and photo work so
will you be supporting other targets as
well like amore mk1 and all winner chips
yes so we plan to support the armory
make one mark one and we also plan to
support the Raspberry Pi zero we're
actually working on that right now
because of course we don't want to just
report our hard work you think it's
important to to give the chance to other
projects of this and it's actually very
easy to support other pieces of a
hardware it's only a few days of work so
yes definitely and pull requests are
welcome okay back to the signal angel
alright another question is oh I got it
can this be run on other cortex our
class processors or is it the same use
tiny go it can be it can be executed on
any system on chip that has ARM
architecture support within the go
runtime so I would say that it would be
trivial to running on any arm v7 system
on chip and it should be very easily
adaptable to two other ones again the
number of modifications required and the
hardware installation make it so that
it's easy to port it to other platforms
so as long as we're talking about system
on chips with cortex it should be fairly
easy to do yeah thank you for the
question full answer I have more
questions
what would tomorrow also run on the USB
armory mk1 yes yes definitely so we're
gonna we're going to make sure that we
provide that support soon enough in a
very interested sea only develop
asked on Twitter what is about debugging
breakpoints register maps and register
many manipulation on the MCU using
tamago gdb works beautifully so we use
gdb we use breakpoints we can stop
anywhere we want we see the code just
like any other application otherwise we
would have gone insane so yes that works
okay next up microphone number two
please
you mentioned file system support yeah
are you using I think you mentioned fat
to use the there's a pure gold
implemented for this sorry no I'm
blanking the name the future project I
think is a full can you speak up a bit
please
oh yeah the the future implementation
and I think they're using a user space
driver for fat right it's all in go lose
fat pure golf at implementation they're
already out there's something load the
GERD project already has that and also
as the MMC support so we're gonna we're
gonna we're gonna try and and get that
and and put it in issue be it should be
very trivial effort and I just mentioned
in fact because it's a easy file system
format and usually on a better system
you just want to take a blob write it
read it you don't need fancy storage
thanks microphone number one please
thanks for the talk have you talked to
upstream about getting it into the main
line yes we're working on that we're
very anxious about it because we want
everything to be super clean but it is
our intention to give this the best
possible chance and we have contacts
upstream and this was quoted from the
very beginning with international make
things clean nice respectful on what's
already there in the Goron team we
didn't want to hijack things that are
not meant to be i jacked and that's our
ago because in yen I don't want to
maintain the compiler part I just want
to maintain the drivers and everything
else so yeah we're really trying hard to
make this in a in a state where it has
the best chance to be accepted upstream
no but I would hope by the end of next
year
tomorrow and why does it call it
tomorrow
so probably one
we called time ago it is called tomorrow
because tomorrow means AG in Japanese
and you have go and go leaves on bare
metal in its own shell and so it's
tamago and if you run it under QE moon
it's a tamagotchi thank you this is the
only reason why we do these projects we
first come up with a name and there were
like oh what can I do with that name
yeah do we have any more questions from
the internet no we do not
I think we have another question at
microphone number one how how is it two
days embedded system we often have some
screens mm-hmm well the USB armory has
no screen so it wasn't our focus right
now having said that there's no reason
why you couldn't implement a video
driver with this maybe won't be as
performant as he can but if you're doing
DMA right and you're clever enough of
course it can work but for now it's not
it's not our focus our focus now is
having smarter smart cards HSMs tokens
authentication tokens so we have
bluetooth on the USB armory we have USB
4 for now if we want a UI with the USB
armory
we either have a mobile app or you do it
for networking but yes maybe in the
future who knows are there any more
questions I guess not well then thank
you thank you
[Music]