[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Some comments on JFK




In message <200112022238.fB2Mcp505964@romeo.rtfm.com>, Eric Rescorla writes:
 >(1) In message 1 the initiator sends g^i. This is replayed in message
 >3. I see why the initiator needs to tell the responder the group he
 >wants to use but why does it need to communicate g^i? If you simply
 >want the initiator to commit to g^i, why not use a hash? This would
 >save some bandwidth, which is always nice :)

I think this makes sense.

 >(2) The discussion of message 2 says:
 >	The authenticator key is changed at least
 >	as often as g^r, thus preventing replays of stale data.
 >
 >     But the discussion of message 3 says:
 >	The Responder's exponential (g^r) is re-sent by the Initiator because
 >         the Responder may be generating a new g^r for every new JFK
 >	protocol run	
 >
 >This seems problematic. Verification of message 3 uses HKr so if you
 >have multiple message 2s outstanding each with different g^rs (and
 >hence different HKrs according to the first quote) then you must
 >maintain a table of old HKrs, one per message.  Is this really your
 >intention?

If you have different g^r's, you need to keep the corresponding r's anyway, so
you can keep HKr as well. If you're re-using the same (r, g^r) pair, you only
need to keep those around (and only one HKr).

 >There appear to be some similar inconsistencies in the discussion of
 >message 3 caching where it says:
 >
 >    This cache of messages can be reset as soon as g^r or HKr are
 >    changed.
 >
 >Incidentally, it would save some bandwidth if the client echoed
 >a hash of g^r (or a key id provided in message 2) in message 3.
 >Again, this would save some bandwidth.

Generally, yes.

 >     
 >(3) The discussion of message 3 says:
 >
 >    The Responder keeps a copy of recently-received Message (3)'s, and
 >    their corresponding Message (4). Receiving a duplicate (or
 >    replayed) Message (3) causes the Responder to simply retransmit the
 >    corresponding Message (4), without creating new state or invoking IPsec.
 >
 >This suggests that the cache lookup is performed on the entire message 3.
 >E.g. 
 >
 >      if(msg4=table_lookup(message3,message3_len)){
 >        retransmit(msg4);
 >      }
 >      else ...
 >
 >However, this may open the responder to a DoS attack whereby the
 >attacker replays copies of message 3 with different encrypted blocks
 >(i.e. garbage).  The attacker can thereby force a cache miss and force
 >the responder to repeatedly compute g^ir while attempting to process
 >these messages.  This entails no particular computational burden on
 >the attacker.
 >
 >The easiest fix for this is for the responder to use only the
 >authenticated data (Ni,Nr,g^i,g^r) or simply HKr as the cache key.

Yes -- sorry, I suppose that wasn't clear in the text; the intent was to
have the authenticator be the key.

 >(3) Section 2.3 says:
 >
 >    The Initiator bears the initial computational burden
 >    and must establish round-trip communication with the Responder
 >    before the latter is required to perform expensive operations.
 >
 >Note that the initiator does not have to perform expensive computations
 >in order to force the responder to perform expensive computations.
 >It's trivial to generate a plausible-appearing g^i without doing
 >any actual modular exponentiation. This forces the responder to
 >compute g^ir. The initiator does of course have to prove that he
 >can perform a round-trip.

Right, but valid initiators do have to spend cycles before the responder
does.

 >    The Responder may compute a new exponential g^r for each
 >    interaction.  This is an expensive option, however, and at times of
 >    high load (or attack) it would be inadvisable. 
 >
 >Technically speaking, it's not the generation of g^r that is
 >expensive. If you're using g=2 this is can be made pretty fast.
 >It's SIG{r}(g^r) that's expensive, especially if you're using 
 >RSA. This is just a nit of course.

It's still more expensive than reusing the old g^r :-)

 >    The key used to protect
 >    Messages (3) and (4), Ke, is computed as HMAC{g^ir}{Ni, Nr, 1}. The
 >    session key used by IPsec (or any other application), Kir, is
 >    HMAC{g^ir}(Ni, Nr, 0).
 >
 >This isn't guaranteed to create a long enough key. In particular, you
 >don't say whether you're using 2 or 3 key 3DES but if you're using 3
 >key then you're already short at least 8 bits :)

Good point -- the reason for selecting this scheme is that it was shown to be
secure (ask Omer Reingold for more details -- co-author of the draft). 

 >Additionally, it seems
 >like bad practice to use the same key for messages (3) and (4). I'd
 >much rather see different keys.

Actually, there is no security problem by reusing the same key in the
two messages (the encryption is used only for privacy purposes -- the
security of the exchange is based on the signatures).

 >Also, I don't see where you're getting the 3DES initialization vector
 >from, though I assume you use CBC. Is it generated from g^ir? Random
 >and included in the message?

CBC seems the most likely candidate, although we wouldn't want to preclude
some of the newer modes of operation. If there is an IV, it is random and
included in the message.

 >(4) Section 2.5 contains a minor glitch:
 >
 >    implicit in $\mbox{ID}_I$ and $\mbox{ID}_R$) should be accomplished

Oops, my bad.

 >(5) The wire format is, uh... unusual. Is there some reason
 >     you've chosen not to go with some fixed packet format specified
 >     either by byte-diagrams or some description language. This is
 >     not going to be the easiest message format to write a codec
 >     for.

I thought it was one of the simplest formats imaginable...

Anyway, we're not really attached to any format --  the one in the draft
is just a strawman (we had to have something in there -- at the very least
for the prototype implementations --- more on this, at the IETF :)

 >(6) Performance issues:
 >
 >     The standard JFK exchange requires at least the following
 >     public-key operations on each side:
 >
 >     1 DH key agreement
 >     1 signature generation
 >     1 signature verification + 1 verification for each peer certificate
 >
 >     If you want true PFS the situation is worse since you must
 >     also do an extra g^X mod p and signature generation (to sign g^r,
 >     whereas if you reuse g^r you can amortize this signature over multiple
 >     interactions). This may not sound like a lot but remember that people
 >     avoid SSL for performance reasons even though it's substantially cheaper
 >     than JFK. I'd certainly expect people to reuse keys rather than
 >     use PFS in order to improve performance. This isn't that desirable.

Bear in mind that any protocol can reuse a g^x value across multiple exchanges
-- it's strictly an implementation issue.

That said, it is possible to do away with the signature in message 2. The
purpose of that signature is to prevent active attacks on the identity of the
initiator (an attacker can introduce their own g^r in a message 2, and the
Initiator would encrypt with that derived key). If protection of the Initiator
from this attack is not deemed necessary, the signature can go.

(You can protect the Initiator from active identity attacks without a signature
if you add another message to the protocol, as SIGMA does. However, there is a
good practical reason not to have an odd number of messages in a protocol...)

 >     It's possible to optimize away the extra signature by adding a little
 >     complexity to the protocol. If we change g^r with every interaction
 >     we can dispense with the final signature in message 4, provided that
 >     message 2 contains a signature over Ni and Nr as well as g^r.

Always changing g^r requires state to be kept for each Message 1 received,
thereby re-introducing the problem with IKE. That would be a clear violation
of our design goals.

 >     [Actually, it's arguable that we could dispense with the signature 
 >     in message 4 entirely and replace it with a MAC but that would
 >     allow an attacker who compromised a single g^r to impersonate the
 >     server indefinitely. You could imagine some sort of hack where 
 >     the signature was over g^r and a timestamp but this seems pretty
 >     scary.]           

To impersonate the server indefinitely, the attacker also has to have the
server's RSA key (and if he does, there's no protocol to protect you against
that :-)

I think you mean that the attacker can mount active identity attacks on any
Initiator that tries to contact the server. My feeling is that if the attacker
can get an r (and the corresponding g^r), with overwhelming probability he also
has the server's RSA key. Thus, back to square one (meaning, we need to depend
on revocation etc. to protect against that).


Thanks for the comments!
-Angelos




Follow-Ups: References: