IETF-SSH archive

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

Re: Some questions about "SSH Transport Layer Encryption Modes"



On Thu, Oct 23, 2003 at 07:07:21PM -0400, Bill Sommerfeld wrote:
> > So one would have:
> > 
> > NONBLOCK_REKEY(response=FALSE), KEXINIT, ...
> > 
> > and expect back one of:
> > 
> > NONBLOCK_REKEY(response=TRUE),  NEWKEYS, ...
> > UNIMPLEMENTED, NEWKEYS, ...
> > NEWKEYS, ...
> > 
> > Thoughts?
> 
> Can this be done asynchronously, early during connection negotiation
> (or perhaps well before the rekey is needed)?  That way, you won't
> hang waiting for a response which might never arrive...

Yes.  That was the idea.  Do it async before the _initial_ key exchange.
Actually the above does sort of imply any response to the NONBLOCK_REKEY
message would be delayed until the NEWKEYS is about to be sent.  That
wasn't my intention.  I intended that the messages would be replied to
in order,  or at least as soon as possible.

So one sends the sequence above (without waiting betwen the NONBLOCK_REKEY
and the KEXINIT.  At that stage one will do the normal KEXINIT algorithm,
including the specific key negotiation stuff.

So depending upon timing one could have:

C-->S  NB_RKY(FALSE),  KEXINIT,  KEXDH_INIT
C<--S  NB_RKY(TRUE), KEXINIT, KEXDH_REPLY, NEWKEYS
       (pause)
C-->S  NEWKEYS

C-->S  NB_RKY(FALSE),  KEXINIT,  KEXDH_INIT
C<--S  UNIMP, KEXINIT, KEXDH_REPLY, NEWKEYS
       (pause)
C-->S  NEWKEYS

C-->S  NB_RKY(FALSE),  KEXINIT,  KEXDH_INIT
C<--S  KEXINIT, KEXDH_REPLY, NEWKEYS
       (pause)
C-->S  NEWKEYS

    (All of above are simple and distinguishable)

C<--S  KEXINIT
C-->S  NB_RKY(FALSE), KEXINIT,  KEXDH_INIT
       (pause)
C<--S  NB_RKY(TRUE), KEXDH_REPLY, NEWKEYS
       (pause)
C-->S  NEWKEYS

C<--S  KEXINIT
C-->S  NB_RKY(FALSE), KEXINIT,  KEXDH_INIT
       (pause)
C<--S  UINMP, KEXDH_REPLY, NEWKEYS
       (pause)
C-->S  NEWKEYS

C<--S  KEXINIT
C-->S  NB_RKY(FALSE), KEXINIT,  KEXDH_INIT
       (pause)
C<--S  KEXDH_REPLY, NEWKEYS
       (pause)
C-->S  NEWKEYS

    (This is the same,  but generalised with the server optimising it's TX)

C<--S  NB_RKY(FALSE), KEXINIT
C-->S  NB_RKY(FALSE), KEXINIT,  KEXDH_INIT
C-->S  NB_RKY(TRUE)
       (pause)
C<--S  NB_RKY(TRUE), KEXDH_REPLY, NEWKEYS
       (pause)
C-->S  NEWKEYS

    (Client and server both send it,  server optimised TX)

C-->S  KEXINIT,  KEXDH_INIT
C<--S  NB_RKY(FALSE), KEXINIT, KEXDH_REPLY, NEWKEYS
       (pause)
C-->S  NB_RKY(TRUE), NEWKEYS

C-->S  KEXINIT,  KEXDH_INIT
C<--S  NB_RKY(FALSE), KEXINIT, KEXDH_REPLY, NEWKEYS
       (pause)
C-->S  UNIMP, NEWKEYS

C-->S  KEXINIT,  KEXDH_INIT
C<--S  NB_RKY(FALSE), KEXINIT, KEXDH_REPLY, NEWKEYS
       (pause)
C-->S  NEWKEYS

    (Server initiates it)

C<--S  NB_RKY(FALSE), KEXINIT
C-->S  KEXINIT,  KEXDH_INIT
       (pause)
C<--S  KEXDH_REPLY, NEWKEYS
       (pause)
C-->S  NB_RKY(TRUE), NEWKEYS

C<--S  NB_RKY(FALSE), KEXINIT
C-->S  KEXINIT,  KEXDH_INIT
       (pause)
C<--S  KEXDH_REPLY, NEWKEYS
       (pause)
C-->S  UINMP, NEWKEYS

C<--S  NB_RKY(FALSE), KEXINIT
C-->S  KEXINIT,  KEXDH_INIT
       (pause)
C<--S  KEXDH_REPLY, NEWKEYS
       (pause)
C-->S  NEWKEYS

    (Server initiates,  and optimising it's TX)

A similar analysis applies to dh-group-exchange,  since it ultimately boils
down to an INIT and REPLAY.  I've not looked at the GSS draft (I've no
interest in it),  but the same rules should apply.

A sender of the NONBLOCK_REKEY sends it before sending KEXINIT.  Thereafter
by the time he receives NEWKEYS he'll know from either the messages received,
or a lack of response to the message,  if his peer supports it.  Since in
general both ends have to consider the messages as pipelined rather than
strict command-stop-response,  this should always work.

In fact the response to the NONBLOCK_REKEY (if there is one) could appear
at any point in the messages received from the peer,  as long as it's
before the NEWKEYS message.

So the above sequence would be used during the initial keying session
(where the session id is created).  Either end seeing or sending a
NONBLOCK_REKEY(TRUE),  means that both ends support the facility.
Subsequent rekeys would not have to use the NONBLOCK_REKEY message,
as they already know if it's supported.  However there is no harm
in sending it subsequently,  it's just a waste of time to do so.

Also the above does not burden implementations that don't wish to support
this facility.  Only those that do (and initiate the negotiation),  have
to go to the effort of tracking which packet sequence number they sent 
the NONBLOCK_REKEY message in such that they can determing if the
UNIMPLEMENTED message matches it.

Also the fact that the NONBLOCK_REKEY is sent before encryption and/or
authentication are engaged does not cause any security problems (that
I can see).  The worst that could happen is the initial negotiation
was broken (DOS attack).  It would be possible to prevent this facility
from being used if a MiTM changed/deleted the KEXDH_REPLY(TRUE) message,
but that's just a performance loss,  not a security problem.

DF



Home | Main Index | Thread Index | Old Index