Hi, this is a long message...

I've looked through the -01 version of the QSKE draft. The draft has been 
expanded
and now it covers such aspects as QSKE negotiation, fragmentation and 
transferring
of payloads larger than 64K. I didn't review the draft in details, however 
after reading
I have concerns over the technical solutions the draft proposes. In particular, 
I think that 
the problems of negotiation, fragmentation and representation of large payloads 
could be solved better.

1. Negotiation.

The draft introduces a new negotiation mechanism to be used explicitly with 
multiple QS key exchanges. While the proposed mechanism looks like an ingenious
way to deal with legacy implementations and as a powerful tool to negotiate
complex policies, I don't think it is ever needed, since all this can be done
using existing mechanism. How it can be achieved:

Let's define a bunch of new Transform Types each defining some kind of QSKE:

Transform Type 6 - Lattice QSKE
Transform Type 7 - Code-based QSKE
Transform Type 8 - Isogeny-based QSKE
Transform Type 9 - Symmetric QSKE
...

Each of these Transform Types must then be populated with Transform IDs
for QSKE of corresponding type. It is also important to add NONE into each of 
these
types.  The Initiator willing to combine QSKEs of specific types would include
corresponding Transform Types populated with the Transform IDs the initiator
deems acceptable. If NONE for some Transform Type is included, it means 
that this Transform Type is optional. IKEv2 requires the responder to select
a combination of transforms such that a single Transform ID of each Transform 
Type 
is present. It means that the current SA payload syntax is able to represent 
the policies 
that the new negotiation mechanism in the draft is designed for. For example:

SA:
  Proposal1:
    TransformType1: ENCR_AES_CBC
    TransformType2: PRF_HMAC_SHA2_256
    TransformType3: AUTH_HMAC_SHA2_256_128
    TransformType4: 2048-bit MODP Group
  Proposal2:
    TransformType1: ENCR_AES_CBC
    TransformType2: PRF_HMAC_SHA2_256
    TransformType3: AUTH_HMAC_SHA2_256_128
    TransformType4: 2048-bit MODP Group
    TransformType6: LatticeQSKE_2
    TransformType6: CodebasedQSKE_1, CodebasedQSKE_2
  Proposal3:
    TransformType1: ENCR_AES_CBC
    TransformType2: PRF_HMAC_SHA2_256
    TransformType3: AUTH_HMAC_SHA2_256_128
    TransformType4: 2048-bit MODP Group
    TransformType6: LatticeQSKE_1
    TransformType6: LatticeQSKE_2, NONE
    TransformType6: IsogenybasedQSKE_1, IsogenybasedQSKE_2

In this example the Proposal1 is aimed for the legacy responders.
Proposals  means that the classic MODP_2048 group
must be combined with LatticeQSKE_2 and either CodebasedQSKE_1 or 
CodebasedQSKE_2. Proposal3 means that the classic MODP_2048 group must be 
combined with either IsogenybasedQSKE_1 or IsogenybasedQSKE_2 and may 
optionally 
be combined with LatticeQSKE_2.

Legacy responders would ignore Proposals 2 and 3 since they contain
unknown Transform Type. However they would pick Proposal1.
QSKE-enabled responders would select either Proposal 2 or 3 depending
on their policy.

Re-using existing mechanism is much easier to implement since the parsing
code is already there, as well as the interface with the local policy.
This mechanism is flexible enough to express the policies from the draft.
It doesn't have a round trip penalty when communicating with legacy
responder. It assumes that classic KE is always present, however I can
see it as a feature, not as a disadvantage (see the next topic in the message).
And in the future it will be possible to add QSKE mechanisms into Transform 
Type 4,
provided their public key are small enough (and their security is proved, of 
course).
In this case no classic KE is more needed. 

One disadvantage of using SA payload comparing with the new mechanism from 
the draft is that it is less compact and complex policies can lead to the 
situation 
when SA payload size will become too large. However, there is a draft 
describing compact 
representation of IKE payloads that allows to significantly decrease SA payload 
size
(https://datatracker.ietf.org/doc/draft-smyslov-ipsecme-ikev2-compact/)

One more consideration. I assume that existing implementations are conformant 
with 
RFC 7296, which states (Section 3.3.6):

   If the responder receives a proposal that contains a Transform Type
   it does not understand, or a proposal that is missing a mandatory
   Transform Type, it MUST consider this proposal unacceptable; however,
   other proposals in the same SA payload are processed as usual.

There were a concerns that some implementations could incorrectly
reject the whole SA payload if they encountered an unknown Transform Type.
To deal with such (crippled) implementations one more round trip and an
additional logic would be needed (if we decide to deal with them ever),
but I think that it'll be no more complex than the negotiation mechanism from
the draft.

Am I missing something here?

2. Fragmentation

I think that defining a new fragmentation mechanism for IKE_SA_INIT is bad 
choice. 
We already have IKE fragmentation and it is more appropriate to re-use
existing mechanism. It is possible to do it in a way suggested by Tero:
https://www.ietf.org/mail-archive/web/ipsec/current/msg11563.html
I've published a draft defining auxiliary exchange for this purpose:
https://datatracker.ietf.org/doc/draft-smyslov-ipsecme-ikev2-aux/

Comparing with a new fragmentation mechanism for IKE_SA_INIT defined in the 
draft,
re-using the existing IKE fragmentation via an auxiliary exchange has the 
following advantages.

- It is easier to implement. The IKE fragmentation is already supported by many 
vendors
   and it is easier to add a new simple exchange than to complicate 
IKE_SA_INIT, that is already
   quite complex. Note, that with the draft's proposal IKE_SESSION_RESUME 
exchange would
   need to be modified as well. With auxiliary exchanges resumption will be 
supported for free.

- It is substantially more secure. The way the draft deals with fragmentation 
is susceptible to DoS 
   attacks when an attacker injects bogus fragments poisoning reassembly 
buffer. Adding
   cookie to the fragments. as the draft suggests to prevent this attack, 
doesn't help at all: 
   to inject bogus fragments an attacker need to know IKE SPIs, so he/she must 
be able
   to view messages from the peers, and if he/she is able to do it, then he/she 
will also
   know the cookie. So, the proposed defense never works. This attack is 
impossible
   with the standard IKE fragmentation unless an attacker is able to break key 
exchange 
   in the IKE_SA_INIT in real time. I presume he/she would need QC for that and 
I hope
   by the time it is possible we'll already have some QC-proof key exchange 
with small
   public keys, so that it can be used in the IKE_SA_INIT and thwart the attack.

- It is more robust. The problem with the approach suggested in the draft is 
that it
   works very poorly in case of packet loss, because all the fragments are sent 
simultaneously.
   If the number of fragments is small enough, then it doesn't cause major 
problems.
   However, as the number of fragment grows, single packet loss results in 
resending
   the whole bunch of fragments. If the packet loss is caused by congestion, 
then
   momentary resending all the fragments would result in more congestion, that 
   would only make things worse. Standard IKE fragmentation is also susceptible 
   to this problem, since it wasn't designed to deal with more than a handful 
fragments.
   This is no more true with QC-safe huge public keys. Ideally, each fragment 
   should be acknowledged individually, however in is generally impossible with 
IKE 
   request-reply paradigm (since reply fragments must also be acknowledged).
   Fortunately, using several auxiliary exchanges for transferring QC-safe 
public keys
   make it possible to at least make this problem less significant. The idea is
   to perform several QC-safe key exchanges utilizing large public keys one by 
one:

  HDR (IKE_SA_INIT, MID=0), SAi1, KEi, Ni,
       [N(AUX_EXCHANGE_SUPPORTED)]  -->
                                    <--  HDR (IKE_SA_INIT, MID=0), SAr1, KEr, 
Nr,
                                             [N(AUX_EXCHANGE_SUPPORTED)]

   HDR (IKE_AUX, MID = 1), SK {QSKE1i}  -->
                                     <--  HDR (IKE_AUX, MID = 1), SK { QSKE1ir}

   HDR (IKE_AUX, MID = 2), SK {QSKE2i}  -->
                                     <--  HDR (IKE_AUX, MID = 2), SK { QSKE2ir} 
  

   HDR (IKE_AUTH, MID = 3), SK {SA, TSi, TSr}  -->
                                     <--  HDR (IKE_AUTH, MID = 3), SK { SA, 
TSi, TSr}   

  So each of negotiated QSKEs is performed in a separate exchange,
  thus reducing the number of fragments in case it is fragmented.
  It is even possible to split any single QS key exchange in a several
  IKE_AUX exchanges if the exchange is DH-like, i.e. if public keys are 
  of the same size and are generated independently.

  [Actually the same problem with reliable transferring of large number
  of fragments in case of QSKE will also arise in case of re-keying...
  There are several possible solutions, but I think they can be discussed
  separately.]

So, I see no advantages of the new IKE_SA_INIT fragmentation mechanism 
over the re-using of existing one. Again, am I missing something here?

3. Large KE payloads

The draft makes it possible to deal with public keys greater than 64K
by means of a complex pointer-like system (integrated with proposed
fragmentation mechanism). I think that it is too complex. I'd rather
use simple approach, that is aligned with the re-using of standard
IKE fragmentation described above. 

I propose that in case the public key is greater than 64K, it is 
split into several consecutive KE payloads in a single message.
If several long public keys are present in the message, then
all the payloads each key is split into must be grouped together.
An example:

   HDR (IKE_AUX, MID = 1), SK {QSKE1i, QSKE1i, QSKE1i, QSKE2i, QSKE2i }  -->
    <--  HDR (IKE_AUX, MID = 1), SK { QSKE1ir, QSKE1ir, QSKE1ir, QSKE2ir, 
QSKE2ir }

Here we have 2 large public key in a single message, QSKEi1 is split
into 3 payloads and QSKEi2 is split into 2 payloads. Actually, I don't think
it is a good idea to send several large public keys in a single message given
the problems outlined above, but it is a possible construction.
A better way would be:

   HDR (IKE_AUX, MID = 1), SK {QSKE1i, QSKE1i, QSKE1i}  -->
                     <--  HDR (IKE_AUX, MID = 1), SK { QSKE1ir, QSKE1ir, 
QSKE1ir}

   HDR (IKE_AUX, MID = 2), SK {QSKE2i, QSKE2i}  -->
                     <--  HDR (IKE_AUX, MID = 2), SK { QSKE2ir, QSKE2ir}   

And even better way would be (provided the QSKEs are DH-like):

   HDR (IKE_AUX, MID = 1), SK {QSKE1i}  -->
                                     <--  HDR (IKE_AUX, MID = 1), SK { QSKE1ir}

   HDR (IKE_AUX, MID = 2), SK {QSKE1i}  -->
                                     <--  HDR (IKE_AUX, MID = 2), SK { QSKE1ir}

   HDR (IKE_AUX, MID = 3), SK {QSKE1i}  -->
                                     <--  HDR (IKE_AUX, MID = 3), SK { QSKE1ir}

   HDR (IKE_AUX, MID = 4), SK {QSKE2i}  -->
                                     <--  HDR (IKE_AUX, MID = 4), SK { QSKE2ir} 
  

   HDR (IKE_AUX, MID = 5), SK {QSKE2i}  -->
                                     <--  HDR (IKE_AUX, MID = 5), SK { QSKE2ir} 
  

[And I still hope that cryptographers won't leave us with only 
those QC safe key exchange methods that use huge public keys.
I really don't want to transfer megabytes of keys just to create an SA
to read my one hundred bytes long e-mail...]

So, the bottom line. I think that the QSKE draft goes into wrong
direction, suggesting over-complicated and insecure solutions
and ignoring existing mechanisms that can be used instead.
I hope the authors will re-consider this.

Regards,
Valery.


_______________________________________________
IPsec mailing list
IPsec@ietf.org
https://www.ietf.org/mailman/listinfo/ipsec

Reply via email to