[OTR-dev] Achieving non-non-repudiation in another protocol.

Ian Goldberg ian at cypherpunks.ca
Wed Aug 27 10:17:04 EDT 2008


On Tue, Aug 26, 2008 at 10:39:57PM -0400, Gregory Maxwell wrote:
> Hopefully the this brief non-libotr discussion is not too far off-topic.
> 
> I'm getting close to releasing a real-time low latency audio
> conferencing tool (suitable for real-time music collaboration and the
> like).
> 
> The system provides automatic, transparent, and always on encryption
> since I believe that I'm ethically obligated to include that as an
> author of a protocol that will be used across the internet.

Well said.  :-)

> It would be desirable if the anti-MITM functionality of my application
> did not also introduce non-repudiation, which is undesirable for this
> application.  So I'd like the essential non-non-repudiation behavior
> of OTR.  I think I've achieved that, but I'd like a quick sanity
> check.
> 
> Some of the features of OTR, such as the ability to make validly
> decoding blind forgeries are not realistic in my application because
> of the use of compression (Nor are blind bitflips all that useful
> against audio in any case), so I'm performing my non-non-repudiation
> in a manner fairly different from libotr.
> 
> I won't be providing a complete and accurate description of the
> cryptographic protocol here, since I'm only trying to verify that what
> I'm doing will achieve non-non-repudiation.
> 
> Definitions:
> DHp1  = Client 1's ephemeral EC Diffie-Hellman public key
> DHp2  = Client 2's ephemeral EC Diffie-Hellman public key
> M1      = Random value generated by client 1 for message auth
> M2      = Random value generated by client 2 for message auth
> N1       = Random value generated by client 1 as a nonce
> N2       = Random value generated by client 2 as a nonce
> S1()     = Signing with Client1's private key.
> S2()     = Signing with Client2's private key.
> H()       = some cryptographic hash function
> 
> Client 1 sends   DHp1 || N1 || MAC(M1,DHp1) ->  Client 2
> then
> Client 2 sends  DHp2 || N2 || MAC(M2,DHp2) -> Client 1
> then
> Client 1 sends M1 || S1(H(M1||N2)) -> Client 2
> then
> Client 2 sends M2 || S2(H(M2||N1)) -> Client 1
> 
> With reasonable assumptions that M1, M2, N1, N2 are large and randomly
> selected:
> 
> Client 1 and 2 can now verify that the DH public values are
> authenticated by M1 and M2. And that M1 and M2 were authenticated by
> the public keys so no MITM is possible. Replay isn't possible against
> client 1 or client 2 because the signatures depend on a nonce
> controlled by the other client.
> 
> After the final exchange either client (or any eavesdropper) could
> create a new stream are re-use the Mn and Nn values from this exchange
> to make a forged stream that appears to be signed by Client1, Client2,
> or both.
> 
> Does this appear correct?

I think you indeed achieve repudiability, but I'm pretty sure the above
protocol suffers from the same identity-misbinding attack that OTRv1
had.

The MITM can change the signature on the last message to be her own
signature instead of C2's.  Then C1 will think she's talking to MITM,
but she's really talking to C2.

OTR switched to the SIGMA protocol (used in IPSec) to overcome this
problem.  I think to fix the above, you could:

- Change the H inside the signatures to a MAC, with key based on the DH
  shared secret.  This proves that the parties have computed the same
  session key.
- Put the sender's name/id/pubkey inside this MAC, along with the M and
  N values.

Then if you remove the MAC(M1,DHp1) (and 2) and indeed the Ms entirely,
I think you get SIGMA.  Not positive; I'd have to write it out and look
more closely.  Maybe you have to put both N1 and N2 inside the MACs
inside the signature.

   - Ian



More information about the OTR-dev mailing list