Skip to content

Commit

Permalink
Use fake RPMB to implement the counter.
Browse files Browse the repository at this point in the history
  • Loading branch information
jiggoha committed Jan 29, 2024
1 parent e4da79c commit 5a2c38c
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 120 deletions.
64 changes: 0 additions & 64 deletions trusted_os/flash.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
package main

import (
"bytes"
"encoding/binary"
"errors"
"fmt"
"log"
Expand Down Expand Up @@ -46,13 +44,6 @@ const (
osConfBlock = 0x5000
osBlockA = 0x5050
osBlockB = 0x102828
// This sector is interpreted as whether the device should wipe its previous
// data and boot as a new witness identity.
newIdentityBlock = 0x1FFF00
// This sector contains a counter to differentiate between witness
// identities. For production devices, this counter should live in RPMB,
// so that it is secure, read-only, and overflow protected.
mmcIdentityCounter = 0x1FFF01

batchSize = 2048
)
Expand Down Expand Up @@ -146,61 +137,6 @@ func determineLoadedOSBlock(card Card) error {
return nil
}

// newWitnessIdentity reads the newIdentityBlock from MMC.
func newWitnessIdentity(card Card) (bool, error) {
blockSize := card.Info().BlockSize
if blockSize != expectedBlockSize {
return false, fmt.Errorf("h/w invariant error - expected MMC blocksize %d, found %d", expectedBlockSize, blockSize)
}

b, err := card.Read(newIdentityBlock*expectedBlockSize, 1)
if err != nil {
return false, err
}

buf := bytes.NewReader(b)
var newIdentity bool
if err := binary.Read(buf, binary.BigEndian, &newIdentity); err != nil {
return false, err
}

return newIdentity, nil
}

// incrementWitnessIdentityMMC increments the mmcIdentityCounter in the MMC block.
func incrementWitnessIdentityMMC(card Card) error {
blockSize := card.Info().BlockSize
if blockSize != expectedBlockSize {
return fmt.Errorf("h/w invariant error - expected MMC blocksize %d, found %d", expectedBlockSize, blockSize)
}

// Read
b, err := card.Read(mmcIdentityCounter*expectedBlockSize, 1)
if err != nil {
return err
}

rBuf := bytes.NewReader(b)
var counter uint32
if err := binary.Read(rBuf, binary.BigEndian, &counter); err != nil {
return err
}

// Increment
counter++

// Write
wBuf := new(bytes.Buffer)
if err := binary.Write(wBuf, binary.BigEndian, counter); err != nil {
return err
}

if err := card.WriteBlocks(mmcIdentityCounter*expectedBlockSize, wBuf.Bytes()); err != nil {
return err
}
return nil
}

// read reads the trusted applet bundle from internal storage, the
// applet and FT proofs are *not* verified by this function.
//
Expand Down
13 changes: 0 additions & 13 deletions trusted_os/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,19 +169,6 @@ func main() {
log.Printf("Failed to determine OS MMC block (no OS installed?): %v", err)
}

newIdentity, err := newWitnessIdentity(Storage)
if err != nil {
log.Printf("Failed to read new witness identity MMC block: %v", err)
}
if newIdentity {
// TODO: disable for now
if false && imx6ul.SNVS.Available() {
rpmb.incrementWitnessIdentity()
} else {
incrementWitnessIdentityMMC(Storage)
}
}

log.Printf("SM log verification pub: %s", LogVerifier)
logVerifier, err := note.NewVerifier(LogVerifier)
if err != nil {
Expand Down
23 changes: 1 addition & 22 deletions trusted_os/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
package main

import (
"bytes"
"crypto/aes"
"crypto/sha256"
"encoding/binary"
Expand Down Expand Up @@ -158,26 +157,6 @@ func (r *RPC) Read(xfer rpc.Read, out *[]byte) (err error) {
return
}

// ReadIdentityCounterStorage reads data from the storage media sector
// containing the witness identity counter.
func (r *RPC) ReadIdentityCounterStorage(_ any, counter *uint32) error {
if r.Storage == nil {
return errors.New("missing Storage")
}

b, err := r.Storage.Read(mmcIdentityCounter, 1)
if err != nil {
return err
}

buf := bytes.NewReader(b)
if err := binary.Read(buf, binary.BigEndian, *counter); err != nil {
return err
}

return err
}

// WriteRPMB performs an authenticated data transfer to the card RPMB partition
// sector allocated to the Trusted Applet. The input buffer can contain up to
// 256 bytes of data, n can be passed to retrieve the partition write counter.
Expand All @@ -198,7 +177,7 @@ func (r *RPC) ReadRPMB(buf []byte, n *uint32) error {
// value stored in this area.
func (r *RPC) ReadIdentityCounterRPMB(_ any, counter *uint32) error {
buf := make([]byte, witnessIdentityCounterLength)
if err := r.RPMB.transfer(rpmbWitnessIdentityCounter, buf, nil, false); err != nil {
if err := r.RPMB.transfer(witnessIdentityCounter, buf, nil, false); err != nil {
return err
}

Expand Down
41 changes: 20 additions & 21 deletions trusted_os/rpmb.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const (
// witness identity counter length - uint32
witnessIdentityCounterLength = 4
// RPMB witness identity counter
rpmbWitnessIdentityCounter = 7
witnessIdentityCounter = 7

diversifierMAC = "ArmoryWitnessMAC"
iter = 4096
Expand Down Expand Up @@ -202,6 +202,23 @@ func (r *RPMB) checkVersion(offset uint16, s string) (err error) {
return
}

// transfer performs an authenticated data transfer to the card RPMB partition,
// the input buffer can contain up to 256 bytes of data, n can be passed to
// retrieve the partition write counter.
func (r *RPMB) transfer(offset uint16, buf []byte, n *uint32, write bool) (err error) {
if write {
err = r.partition.Write(offset, buf)
} else {
err = r.partition.Read(offset, buf)
}

if err != nil && n != nil {
*n, err = r.partition.Counter(true)
}

return
}

// incrementWitnessIdentity increments the counter in the RPMB area to
// differentiate a new witness identity.
func (r *RPMB) incrementWitnessIdentity() (err error) {
Expand All @@ -211,7 +228,7 @@ func (r *RPMB) incrementWitnessIdentity() (err error) {

// Read
rBuf := make([]byte, witnessIdentityCounterLength)
if err = r.partition.Read(rpmbWitnessIdentityCounter, rBuf); err != nil {
if err = r.partition.Read(witnessIdentityCounter, rBuf); err != nil {
return err
}
counter := binary.BigEndian.Uint32(rBuf)
Expand All @@ -222,23 +239,5 @@ func (r *RPMB) incrementWitnessIdentity() (err error) {
// Write
wBuf := make([]byte, witnessIdentityCounterLength)
binary.BigEndian.PutUint32(wBuf, counter)

return r.partition.Write(rpmbWitnessIdentityCounter, wBuf)
}

// transfer performs an authenticated data transfer to the card RPMB partition,
// the input buffer can contain up to 256 bytes of data, n can be passed to
// retrieve the partition write counter.
func (r *RPMB) transfer(offset uint16, buf []byte, n *uint32, write bool) (err error) {
if write {
err = r.partition.Write(offset, buf)
} else {
err = r.partition.Read(offset, buf)
}

if err != nil && n != nil {
*n, err = r.partition.Counter(true)
}

return
return r.partition.Write(witnessIdentityCounter, wBuf)
}
23 changes: 23 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,22 @@ func (r *RPMB) transfer(sector uint16, buf []byte, n *uint32, write bool) (err e
}
return
}

// 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)
}

0 comments on commit 5a2c38c

Please sign in to comment.