Extra OneRNG anti-tamper feature
Paul Campbell
paul at taniwha.com
Mon Jan 12 22:30:24 GMT 2015
I had a bright idea while I was travelling these past weeks - I talked to
Peter at LinuxConf yesterday and wanted to share it with others for some
critical review - I haven't decided to actually use it yet.
Essentially this is an extra way to validate that a device has not been
tampered - the chips I'm using have a feature where you can lock the debug
interface on the device, the only way to unlock it (for reprogramming) is to
erase the flash - this means you can embed a secret in the flash (a key or
whatever) but still allow people to reprogram the device.
What we're trying to to protect against is someone reflashing a device in
transit or substituting a reflashed device - we're not trying to stop people
from reflashing them, or to provide this protection to devices that people have
received and reprogrammed - they've reprogrammed their device they know what
they put in them.
This protection is over and above the current signed image that the device can
be convinced to cough up for verification, that will continue to work.
The basic idea is that we add a unique key/secret pair into the device and
keep a copy on a trusted database - an encrypted exchange is used to validate
that the database and the device share the same secret (basically each
provides a nonce that are encrypted with a portion of the hidden secret, then
they each encrypt the rest of the secret - the encrypted secrets are compared)
- I largely stole this handshake from something else I've implemented (but not
designed) before, (without the initial DH to exchange the secrets).
This time I am using the chip's AES128 hardware figuring that if there's any
funny business going on with it that it's going to cause the handshake to fail
(rather than to spuriously succeed when it does something wrong since the AES
on my validation server would have to also fail in the same way)
Below is the initial comment from the code I've currently written (but not
tested) - comments would be much appreciated
Paul
//
// This code handles the extra anti-tamper feature of RNG
// essentially it works this way:
//
// 1) OneRNG device flash is protected so we can't read it from the debug
interface
// but we can erase (all of) it
//
// 2) when we program it we put a known random value in the first 96 bytes
of
// the last 128 bytes of it 16 bytes 'ID, 16 bytes 'K', 64 bytes
'S'
//
// 3) user asks device for a its 'ID' from bytes 0:15 of this area 'cmdI'
// returns '!!iiiiii....iiii!' where iiii...iiii is 32 hex digits
//
// 4) user provides 'ID' to the OneRNG web site
// a) it generates a 16 byte token 'T'
// b) caches the tuple ('ID'/'T') - TTL 2 minutes
// c) and returns 'T' to the user
//
// 5) when asked for a confirmation a OneRNG is given the token 'T'
'cmdRtttt....tttt'
// (ttt....tttt is 32 hex digits) and:
// a) use the bytes 16:31 of the region as an AES128 key 'K'
// b) encrypt a 2 block nonce of random data 'R' (32 bytes) ->
'ER'
// c) encrypt (chained) 2 blocks of token 'T' (32 bytes) -> 'ET'
// d) encrypt (chained) the final 32:95 bytes of the region 'S'(64
bytes) -> 'ES'
// e) offer the resulting 128 bytes from the encryption to the
host 'ER'+'ET'+'ES'
//
// 6) user presents bytes 0:15 of the user data 'ID' and bytes 0:63 of
the encrypted data 'ER'+'ET' to OneRNG's web page
//
// 7) OneRNG's server:
// a) wait a random time (to hide error cause info)
// b) inspects its database of manufactured devices using the key
from bytes 16-31 'ID'
// c) if 'ID' isn't in the DB return an error
// d) retrieves bytes 0-95 'K'+'ID'+'S' that were programmed into
the device
// e) decrypts 'ER' using 'K' giving nonce 'R' (discarded)
// f) decrypts (chained) 'ET' using 'K' giving 'T'
// g) if 'T' doesn't match returns an error
// h) reencrypts 'R'+'T'+'S' using 'K' giving 'ER'+'ET'+'ES'
// i) returns 'ES' to user
// j) tells user how many times it has offered up results for this
id (to record
// potential replay attacks)
//
// 8) User compares 'ES' from user's OneRNG with value that OneRNG
delivered in step 5d)
// gets worried if they are not the same
// (we allow this to be done manually but we also provide a python
script)
//
// The basic idea is that we have a shared secret K+S (ID is essentially
a secret id)
// we tell the server we know the key by encrypting something it does
know with K (T) and return
// the encrypted second secret S - the user compares the encrypted second
secret (ES) with the
// one the OneRNG gave it
//
// We also use T to stop replay attacks (where someone records a good
transaction from another
// OneRNG and replays it from a compromised one)
//
// In other words:
//
// step OneRNG web host/user User's OneRNG
//
// 3) 'ID'<-'ID'
//
// 4) 'ID'<-'ID'
// 'T'->'T'
//
// 5) 'T'->'T'
// 'ER'+'ET'+'ESa'<-'R'+'T'+'S'
//
// 6) 'ID'+'ER'+'ET'<-'ID'+''ER'+'ET'
//
// 7) 'ID'+'ER'+'ET'->'R'+'T'->'ESb'
// 'ESa'=='ESb'
//
More information about the Discuss
mailing list