[onerng talk] Extra OneRNG anti-tamper feature

Paul Campbell paul at taniwha.com
Tue Jan 20 04:34:35 GMT 2015


On Tue, 20 Jan 2015 16:57:48 Peter Gutmann wrote:
> Paul Campbell <paul at taniwha.com> writes:
> >Below is the initial comment from the code I've currently written (but not
> >tested) - comments would be much appreciated
> 
> You asked for it :-).

I did - thanks!

> //              b) encrypt a 2 block nonce of random data 'R' (32 bytes) ->
> 'ER'
> 
> This is in effect acting as an IV, but in that case why not just use an IV,
> and why two blocks?  In addition since you're encrypting a fresh nonce,
> there isn't really any need for an IV.

well the IV is essentially the initial state of the chaining passed into the 
first block of the CBC - both ends have to agree on it to decrypt it. 

This is a random nonce intended to mess with anyone who's trying to extract 
the key (since the data that follows was just passed over the net in the 
clear)

2 blocks is magic because it's the size of our USB buffers - it could be 1 
block 32-bytes

> //              d) encrypt (chained) the final 32:95 bytes of the region
> 'S'(64 bytes) -> 'ES'
> 
> What's the purpose of S?  I can't see what it contributes, or why you need
> 64 bytes of it.

this gives us something to compare at the end by the user to tell that we both 
have the same key  without revealing the key itself (just a known secret 
string encrypted with the secret key) - remember we don't trust the OneRNG 
here - we can't ask it to do the final test for validity - it might just say 
'OK' 
 
> //              e) decrypts 'ER' using 'K' giving nonce 'R' (discarded)
> 
> So this is effectively an IV again...

see above

> //              h) reencrypts 'R'+'T'+'S' using 'K' giving 'ER'+'ET'+'ES'
> 
> Is this a new IV?  The previous text says 'R' was discarded, but this
> implies it's reused, in which case the encryption would be the same as what
> you received.

well we don't quite discard it, we  reencrypt it it to get the CBC state the 
same (then we discard it)

I should add i) we just send ES back again to the user

> //      8) User compares 'ES' from user's OneRNG with value that OneRNG
> delivered in step 5d)
> 
> If these are supposed to be the same value, couldn't someone impersonating
> the server just reflect the client's data back at them?

because they don't know S (or the key, nor can they decrypt R) they cannot 
reencrypt and generate ES, since R is different each time, and passed 
encrypted) ES will also be different each time to guard against replay
 
> So there's all sorts of stuff going on there that doesn't really make much
> sense.  Here's a much simpler protocol that does the same thing with mutual
> authentication using a single AES block.  The ID and nonce are 64-bit
> quantities.
> 
>   Server                    OneRNG
>   ------                    ------
>    <------------ ID -------------
>    ------ E( ID || nonce ) ----->

this is essentially  the first part of my handshake (but the other way around)

>    <-- E( ID || nonce ^ 0xFF ) --

I replace FF with  the secret S

> 
> The client identifies itself, the server responds with the client ID and a
> nonce (decrypting and verifying the ID proves the server knows the shared
> key), the client then responds with the re-encryption of the ID +
> bit-flipped nonce which proves knowledge of the shared key and demonstrates
> freshness. You can replay the server message unless you include a nonce
> with the client ID, but since the point is to verify the authenticity of
> the OneRNG via the shared key I'm not sure what that gets you.  If it's a
> concern you could use:
> 
>   Server                        OneRNG
>   ------                        ------
>    <--------- ID || nonce1 ----------
>    --- E( ID ^ nonce1 || nonce2 ) -->
>    <------- E( ID || nonce2 ) -------

(I think this is the cablecard handshake :-)


So the main difference here is that I have two trusted end points, and a user 
in the middle with a trusted connection  to the OneRNG who doesn't trust the 
OneRNG - in your nomenclature:

   Server                        USER                                   OneRNG
<-------- ID ----------------- ----------- ID --------------------
 --------- nonce1  ----------  -----------nonce1------------->
 <-ID,E( nonce2||nonce1)--  <--ID,E(nonce2||nonce1||S)--
                    (USER holds on to the encrypted S blocks)
---E( nonce2||nonce1||S) -> 
                    (USER only receives encrypted S block part
                    and compares it with the one the OneRNG delivered)

for the server ID is essentially a database key that allows it to access the 
previous generated nonce1, the key and S

I think you're correct in that we could simplify to:

   Server                        USER                                   OneRNG
<-------- ID ----------------- ----------- ID --------------------
 --------- nonce1  ----------  -----------nonce1------------->
 <-ID,E( nonce2----------)--  <--ID,E(nonce2||nonce1)-----
                   (USER holds on to the encrypted nonce1 blocks)
---E( nonce2||nonce1) -> 
                   (USER only receives encrypted nonce1 block 
                    part and compares it with the one the OneRNG delivered)

where only the AES128 key is secret rather than the key and the secret S.

	Paul


More information about the Discuss mailing list