[OTR-dev] Forward secrecy/deniability for long messages with low overhead

Sergio Lerner sergiolerner at certimix.com
Thu Feb 21 13:33:03 EST 2013


Hello!

This is my first message to the list, so forgive me in advance if I
break any per-established rule.
Also forgive me if the subject I will talk about has already been
discussed in the past or if I misunderstood the protocol in a way that
makes this message meaningless.

One of the most interesting thinks I've found in OTR is the ability to
provide forward secrecy. Nevertheless, as I've read in the section 4.2
of the paper http://www.cypherpunks.ca/otr/otr-wpes.pdf, some times keys
are kept in memory for long times if the remote used does not reply.

I can think of two scenarios where this is a drawback:

1. Alice sends many messages in a row, but Bob does not reply.
2. Alice want to send a big file to Bob while (say 10 Mbytes) using OTR
with forward secrecy. Examples
  2.a) Alice is sending audio/video chunks recorded with his
microphone/camera over OTR.
  2.b) Alice is downloading a file and at the same time she is sending
it to Bob.

In both three cases she wants that at any time, if her computer is
compromised, then the data already sent is protected unconditionally.
Also in these last two cases, going though D-H for every block
transmitted may imply a very high overhead, and a reduction in
throughput because of the RTT latency needed to exchange D-H messages.

My proposal it that AES-CTR uses a one-way function instead of an
incremental counter. Also the IV is derived from the shared secret.
Let CTR[i] be the plaintext used for the counter in AES-CTR.
Let SS be the shared secret. Normally the protocols does:

EK=Hash(SS)
MK=Hash(EK)

We change this sequence to:

IVK = Hash(SS | intialization-vector)
EK=Hash(SS | encryption)
MK=Hash(SS | authentication)

And SS is destroyed.

Then we define the sequence:

BUFFER[0]=IVK                     (the buffer is 256 or 512 bits wide)
BUFFER[i] =Hash(Buffer[i-1]) (in the implementation, BUFFER[i] overrides
the memory positions of BUFFER[i-1])

CTR[i] = BUFFER[i]                    (truncated to 128 bits)

So CTR[0]=IVK (truncated)

After each block i of AES-CTR is generated, the BUFFER is recycled and
the previous counter is lost forever.
If an attacker managers to break in the computer at a certain time j,
then it's impossible for the attacker to recover the previous i<j
counters (since SS was destroyed and BUFFER[j] cannot be used to recover
BUFFER[i]).

I think the overhead of a Hash evaluation per block is unimportant for a
protocol of this kind, and is much less than a full D-H key exchange per
block sent.
If one wants to go one step further, then we also provide deniability
during long message transmission:

Define MK[i] = Key-derivation-function( MK , i ), like HMAC( MK | i )

Then Alice send each block i authenticating with the key MK[i] and Bob
acknowledges the correct reception (by MAC verification), then MK[i] is
published.

Now, if we apply this algorithm to ANY message (being short or long),
D-H would be required only once at the beginning of the session, which
gives a much faster protocol with the same security/privacy guarantees.
Am I missing something?
What do you think?

Best regards,
 Sergio Demian Lerner.
 www.certimix.com










More information about the OTR-dev mailing list