Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 8 additions & 25 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -67,18 +67,14 @@ GOFLAGS = -tags ${BUILD_TAGS} -trimpath -buildvcs=false -buildmode=exe \

#### primary targets ####

all: trusted_os_embedded_applet witnessctl
all: trusted_os witnessctl

# This target is only used for dev builds, since the proto definitions may
# change in development and require re-compilation of protos.
trusted_os: APP=trusted_os
trusted_os: DIR=$(CURDIR)/trusted_os
trusted_os: check_embed_env create_dummy_applet proto elf manifest

trusted_os_embedded_applet: APP=trusted_os
trusted_os_embedded_applet: DIR=$(CURDIR)/trusted_os
trusted_os_embedded_applet: check_embed_env copy_applet proto elf manifest imx
trusted_os_embedded_applet:
trusted_os: check_embed_env copy_applet proto elf manifest imx
trusted_os:

witnessctl: check_tamago
@echo "building armored-witness control tool"
Expand Down Expand Up @@ -192,28 +188,15 @@ check_embed_env:
exit 1; \
fi

build_applet:
cd witness_applet && make clean trusted_applet

copy_applet: LOG_URL=file://$(DEV_LOG_DIR)/log/
copy_applet:
@if [ "${APPLET_PATH}" == "" ]; then \
echo 'You need to set the APPLET_PATH variable to a valid path for the directory holding applet elf and proof bundle files (e.g. path to armored-witness-applet/bin)'; \
exit 1; \
fi
copy_applet: APPLET_PATH=witness_applet/bin
copy_applet: build_applet
mkdir -p ${CURDIR}/trusted_os/assets
cp ${APPLET_PATH}/trusted_applet.elf ${CURDIR}/trusted_os/assets/
cp ${APPLET_PATH}/trusted_applet_manifest ${CURDIR}/trusted_os/assets/
go run ./cmd/proofbundle \
--log_origin=${LOG_ORIGIN} \
--log_url=${LOG_URL} \
--log_pubkey_file=${LOG_PUBLIC_KEY} \
--manifest_pubkey_file=${APPLET_PUBLIC_KEY} \
--manifest_file=${CURDIR}/trusted_os/assets/trusted_applet_manifest \
--applet_file=${CURDIR}/trusted_os/assets/trusted_applet.elf \
--output_file=${CURDIR}/trusted_os/assets/trusted_applet.proofbundle

create_dummy_applet:
mkdir -p $(DIR)/assets
rm -f $(DIR)/assets/trusted_applet.elf && touch $(DIR)/assets/trusted_applet.elf
rm -f $(DIR)/assets/trusted_applet.proofbundle && touch $(DIR)/assets/trusted_applet.proofbundle

check_tamago:
@if [ "${TAMAGO}" == "" ] || [ ! -f "${TAMAGO}" ]; then \
Expand Down
3 changes: 1 addition & 2 deletions api/rpc/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,5 @@ type FirmwareUpdate struct {
// InstalledVersions represents the installed/running versions
// of the TrustedOS and applet.
type InstalledVersions struct {
OS semver.Version
Applet semver.Version
OS semver.Version
}
93 changes: 11 additions & 82 deletions trusted_os/flash.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,15 @@ import (
const (
expectedBlockSize = 512 // Expected size of MMC block in bytes
otaLimit = 31457280
taConfBlock = 0x200000
taBlockA = 0x200050
taBlockB = 0x2FD050

/*
* Trusted Applet is now embedded in the OS, so these constants are not used.
* Eventually we can reclaim these blocks.
taConfBlock = 0x200000
taBlockA = 0x200050
taBlockB = 0x2FD050
*/

osConfBlock = 0x5000
osBlockA = 0x5050
osBlockB = 0x102828
Expand All @@ -44,15 +50,10 @@ const (
)

const (
Firmware_Applet FirmwareType = iota
Firmware_OS
Firmware_OS FirmwareType = iota
)

var (
// appletLoadedFromBlock is set to the first block of MMC where the applet firmware was loaded from.
// This will be set by the read func below.
appletLoadedFromBlock int64

// osLoadedFromBlock is set to the first block of MMC the running OS firmware was loaded from.
// This will be set by the determineLoadedOS func below.
osLoadedFromBlock int64
Expand All @@ -63,8 +64,6 @@ type FirmwareType int

func (ft FirmwareType) String() string {
switch ft {
case Firmware_Applet:
return "applet"
case Firmware_OS:
return "OS"
}
Expand Down Expand Up @@ -132,47 +131,6 @@ func determineLoadedOSBlock(card Card) error {
return nil
}

// read reads the trusted applet bundle from internal storage, the
// applet and FT proofs are *not* verified by this function.
//
// This function will update appletLoadedFromBlock with the MMC block index
// the applet firmware image was loaded from.
func read(card Card) (fw *firmware.Bundle, err error) {
blockSize := card.Info().BlockSize
if blockSize != expectedBlockSize {
return nil, fmt.Errorf("h/w invariant error - expected MMC blocksize %d, found %d", expectedBlockSize, blockSize)
}

conf, err := readConfig(card, taConfBlock)
if err != nil {
return nil, fmt.Errorf("failed to read applet config: %v", err)
}

fw = &firmware.Bundle{
Checkpoint: conf.Bundle.Checkpoint,
Index: conf.Bundle.LogIndex,
InclusionProof: conf.Bundle.InclusionProof,
Manifest: conf.Bundle.Manifest,
}

fw.Firmware, err = card.Read(conf.Offset, conf.Size)
if err != nil {
return nil, fmt.Errorf("failed to read firmware: %v", err)
}

appletLoadedFromBlock = conf.Offset / expectedBlockSize
switch appletLoadedFromBlock {
case taBlockA:
log.Print("Loaded applet from slot A")
case taBlockB:
log.Print("Loaded applet from slot B")
default:
log.Printf("Loaded applet from unexpected block %d", appletLoadedFromBlock)
}

return
}

// flash writes a buffer to internal storage.
//
// Since this function is writing blocks to MMC, it will pad the passed in
Expand Down Expand Up @@ -237,25 +195,6 @@ func blinkenLights() (func(), func()) {
return blink, cancel
}

// updateApplet verifies an applet update and flashes it to internal storage
func updateApplet(storage Card, taELF []byte, pb config.ProofBundle) (err error) {
// First, verify everything is correct and that, as far as we can tell,
// we would succeed in loadering and launching this applet upon next boot.
bundle := firmware.Bundle{
Checkpoint: pb.Checkpoint,
Index: pb.LogIndex,
InclusionProof: pb.InclusionProof,
Manifest: pb.Manifest,
Firmware: taELF,
}
if _, err := AppletBundleVerifier.Verify(bundle); err != nil {
return err
}
log.Printf("SM verified applet bundle for update")

return flashFirmware(storage, Firmware_Applet, taELF, pb)
}

// updateOS verifies an OS update and flashes it to internal storage
func updateOS(storage Card, osELF []byte, pb config.ProofBundle) (err error) {
// First, verify everything is correct and that, as far as we can tell,
Expand All @@ -270,7 +209,7 @@ func updateOS(storage Card, osELF []byte, pb config.ProofBundle) (err error) {
if _, err := OSBundleVerifier.Verify(bundle); err != nil {
return err
}
log.Printf("SM verified applet bundle for update")
log.Printf("SM verified OS bundle for update")

return flashFirmware(storage, Firmware_OS, osELF, pb)
}
Expand All @@ -288,16 +227,6 @@ func flashFirmware(storage Card, t FirmwareType, elf []byte, pb config.ProofBund
confBlock := 0
elfBlock := 0
switch t {
case Firmware_Applet:
confBlock = taConfBlock
if appletLoadedFromBlock == taBlockA {
elfBlock = taBlockB
log.Print("SM will flash applet to slot B")
} else {
// If the running applet was loaded from applet slot B, or there was no valid config, store in slot A
elfBlock = taBlockA
log.Print("SM will flash applet to slot A")
}
case Firmware_OS:
confBlock = osConfBlock
if osLoadedFromBlock == osBlockA {
Expand Down
23 changes: 1 addition & 22 deletions trusted_os/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ package main
import (
"log"

"github.com/coreos/go-semver/semver"
"github.com/usbarmory/tamago/arm"
"github.com/usbarmory/tamago/bits"
"github.com/usbarmory/tamago/soc/nxp/imx6ul"
Expand All @@ -37,26 +36,6 @@ var irqHandler = make(map[int]func())

// defined in handler.s
func wakeHandler(g uint32, p uint32)
func wakeHandlerPreGo123(g uint32, p uint32)

// handlerCutover is the semver representation of the cut over between wakeHandler implementations above.
// Anything less that this should use the legacy PreGo123 version.
const handlerCutover = "1.23.0"

var (
// wHandler is the wakeHandler implementation to be used, 1.23+ by default.
wHandler = wakeHandler
wHandlerCutover = *semver.New(handlerCutover)
)

func configureWakeHandler(rtVersion semver.Version) {
if rtVersion.LessThan(wHandlerCutover) {
wHandler = wakeHandlerPreGo123
log.Printf("SM Using legacy pre-%s wakeHandler", wHandlerCutover.String())
} else {
wHandler = wakeHandler
}
}

func isr() {
irq := imx6ul.GIC.GetInterrupt(true)
Expand Down Expand Up @@ -87,7 +66,7 @@ func fiqHandler(ctx *monitor.ExecCtx) (_ error) {
// mask FIQs, applet handler will request unmasking when done
bits.Set(&ctx.SPSR, CPSR_FIQ)

wHandler(appletHandlerG, appletHandlerP)
wakeHandler(appletHandlerG, appletHandlerP)

return
}
Expand Down
41 changes: 0 additions & 41 deletions trusted_os/handler.s
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,6 @@
#include "go_asm.h"
#include "textflag.h"

// These defines are only used to aid applet runtime backward compatiblity,
// within wakeHandlerPreGo123, and represent timer structs offsets fo Go <
// 1.23.
#define g_timer 208
#define timer_nextwhen 36
#define timer_status 44
#define const_timerModifiedEarlier 7
#define p_timerModifiedEarliest 2384

// Supports tamago >= 1.23 applet runtime.
TEXT ·wakeHandler(SB),$0-8
MOVW handlerG+0(FP), R0
Expand All @@ -39,35 +30,3 @@ TEXT ·wakeHandler(SB),$0-8
done:
RET

// Supports tamago < 1.23 applet runtime.
TEXT ·wakeHandlerPreGo123(SB),$0-8
MOVW handlerG+0(FP), R0
MOVW handlerP+4(FP), R1

CMP $0, R0
B.EQ done

CMP $0, R1
B.EQ done

MOVW (g_timer)(R0), R0
CMP $0, R0
B.EQ done

// g->timer.nextwhen = 1
MOVW $1, R2
MOVW R2, (timer_nextwhen+0)(R0)
MOVW $0, R2
MOVW R2, (timer_nextwhen+4)(R0)

// g->timer.status = timerModifiedEarlier
MOVW $const_timerModifiedEarlier, R2
MOVW R2, (timer_status+0)(R0)

// g->m->p.timerModifiedEarliest = 1
MOVW $1, R2
MOVW R2, (p_timerModifiedEarliest)(R1)
MOVW $0, R2
MOVW R2, (p_timerModifiedEarliest+4)(R1)
done:
RET
Loading
Loading