Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow passing the witness identity counter to the Trusted Applet. #142

Merged
merged 20 commits into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from 16 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
17 changes: 14 additions & 3 deletions trusted_os/ctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ type controlInterface struct {
ota *otaBuffer
}

func getStatus() (s *api.Status) {
func (ctl *controlInterface) getStatus() (s *api.Status) {
version, _ := parseVersion(Version)

s = &api.Status{
Expand All @@ -61,8 +61,19 @@ func getStatus() (s *api.Status) {
Build: Build,
Version: version,
Runtime: fmt.Sprintf("%s %s/%s", runtime.Version(), runtime.GOOS, runtime.GOARCH),
// TODO(jayhou): set IdentityCounter here.
}

if rpmb := ctl.RPC.RPMB; rpmb == nil {
log.Printf("cannot get witness identity counter because RPMB is nil")
} else {
count, err := rpmb.witnessIdentity()
if err != nil {
log.Printf("cannot get witness identity counter: %v", err)
} else {
s.IdentityCounter = count
}
}

if witnessStatus != nil {
s.Witness = &api.WitnessStatus{
Identity: witnessStatus.Identity,
Expand All @@ -87,7 +98,7 @@ func (ctl *controlInterface) HandleMessage(_ []byte) (_ []byte) {
}

func (ctl *controlInterface) Status(_ []byte) (res []byte) {
res, _ = proto.Marshal(getStatus())
res, _ = proto.Marshal(ctl.getStatus())
return
}

Expand Down
20 changes: 12 additions & 8 deletions trusted_os/flash.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,18 @@ import (

const (
expectedBlockSize = 512 // Expected size of MMC block in bytes
otaLimit = 31457280
taConfBlock = 0x200000
taBlockA = 0x200050
taBlockB = 0x2FD050
osConfBlock = 0x5000
osBlockA = 0x5050
osBlockB = 0x102828
batchSize = 2048

otaLimit = 31457280

taConfBlock = 0x200000
taBlockA = 0x200050
taBlockB = 0x2FD050

osConfBlock = 0x5000
osBlockA = 0x5050
osBlockB = 0x102828

batchSize = 2048
)

const (
Expand Down
17 changes: 16 additions & 1 deletion trusted_os/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package main
import (
"crypto/aes"
"crypto/sha256"
"encoding/binary"
"errors"
"log"
"net"
Expand All @@ -40,6 +41,7 @@ type RPC struct {
Storage Card
Ctx *monitor.ExecCtx
Cfg []byte
Ctl controlInterface
Diversifier [32]byte
}

Expand Down Expand Up @@ -104,7 +106,7 @@ func (r *RPC) Status(_ any, status *api.Status) error {
return errors.New("invalid argument")
}

s := getStatus()
s := r.Ctl.getStatus()
*status = *s

return nil
Expand Down Expand Up @@ -171,6 +173,19 @@ func (r *RPC) ReadRPMB(buf []byte, n *uint32) error {
return r.RPMB.transfer(taUserSector, buf, n, false)
}

// ReadIdentityCounterRPMB performs an authenticated data transfer from the card RPMB
// partition sector allocated to the witness identity counter. It returns the
// value stored in this area.
func (r *RPC) ReadIdentityCounterRPMB(_ any, counter *uint32) error {
buf := make([]byte, witnessIdentityCounterLength)
if err := r.RPMB.transfer(witnessIdentityCounter, buf, nil, false); err != nil {
return err
}

*counter = binary.BigEndian.Uint32(buf)
return nil
}

// DeriveKey derives a hardware unique key in a manner equivalent to PKCS#11
// C_DeriveKey with CKM_AES_CBC_ENCRYPT_DATA.
//
Expand Down
43 changes: 43 additions & 0 deletions trusted_os/rpmb.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,26 @@ import (
const (
// RPMB sector for CVE-2020-13799 mitigation
dummySector = 0

// version epoch length
versionLength = 4
// RPMB sector for OS rollback protection
osVersionSector = 1
// RPMB sector for TA rollback protection
taVersionSector = 2

// RPMB sector for TA use
taUserSector = 3
// RPMB OTP flag bank
rpmbFuseBank = 4
// RPMB OTP flag word
rpmbFuseWord = 6

// witness identity counter length - uint32
witnessIdentityCounterLength = 4
// RPMB witness identity counter
witnessIdentityCounter = 7
jiggoha marked this conversation as resolved.
Show resolved Hide resolved

diversifierMAC = "ArmoryWitnessMAC"
iter = 4096
)
Expand Down Expand Up @@ -211,3 +218,39 @@ func (r *RPMB) transfer(offset uint16, buf []byte, n *uint32, write bool) (err e

return
}

// witnessIdentity gets the witness identity counter from the RPMB area.
func (r *RPMB) witnessIdentity() (counter uint32, err error) {
if r.partition == nil {
return 0, errors.New("RPMB has not been initialized")
}

rBuf := make([]byte, witnessIdentityCounterLength)
if err = r.partition.Read(witnessIdentityCounter, rBuf); err != nil {
jiggoha marked this conversation as resolved.
Show resolved Hide resolved
return 0, err
}
return binary.BigEndian.Uint32(rBuf), nil
}

// incrementWitnessIdentity increments the counter in the RPMB area to
// differentiate a new witness identity.
func (r *RPMB) incrementWitnessIdentity() (err error) {
if r.partition == nil {
return errors.New("RPMB has not been initialized")
}

// Read
rBuf := make([]byte, witnessIdentityCounterLength)
if err = r.partition.Read(witnessIdentityCounter, rBuf); err != nil {
return err
}
counter := binary.BigEndian.Uint32(rBuf)

// Increment
counter++

// Write
wBuf := make([]byte, witnessIdentityCounterLength)
binary.BigEndian.PutUint32(wBuf, counter)
return r.partition.Write(witnessIdentityCounter, wBuf)
}
32 changes: 32 additions & 0 deletions trusted_os/rpmb_fake.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ const (
// RPMB sector for TA use
taUserSector = 3

witnessIdentityCounterLength = 4
// RPMB sector for witness identity counter
witnessIdentityCounterSector = 4

sectorLength = 256
numSectors = 16
)
Expand Down Expand Up @@ -130,3 +134,31 @@ func (r *RPMB) transfer(sector uint16, buf []byte, n *uint32, write bool) (err e
}
return
}

// witnessIdentity gets the witness identity counter from the RPMB area.
func (r *RPMB) witnessIdentity() (counter uint32, err error) {
rBuf := make([]byte, witnessIdentityCounterLength)
if err := r.transfer(witnessIdentityCounterSector, rBuf, nil, false); err != nil {
return err
jiggoha marked this conversation as resolved.
Show resolved Hide resolved
}
return binary.BigEndian.Uint32(rBuf)
}

// incrementWitnessIdentity increments the counter in the RPMB area to
// differentiate a new witness identity.
func (r *RPMB) incrementWitnessIdentity() error {
// Read
rBuf := make([]byte, witnessIdentityCounterLength)
if err := r.transfer(witnessIdentityCounterSector, rBuf, nil, false); err != nil {
return err
}
counter := binary.BigEndian.Uint32(rBuf)

// Increment
counter++

// Write
wBuf := make([]byte, witnessIdentityCounterLength)
binary.BigEndian.PutUint32(wBuf, counter)
return r.transfer(witnessIdentityCounterSector, wBuf, nil, true)
}
Loading