Subject: Re: [IPsec] Quantum Resistance SK_d, SK_pi, SK_pr etc mixing

From: "Valery Smyslov" <[email-masked]>
Date: Mon, 3 Apr 2017 17:34:22 +0300

Hi,

> So I have proposed earlier that we should mix the ppk to SK_d, SK_pi,
> and SK_pr, i.e., something like this:
> 
>    SKEYSEED = prf(Ni | Nr, g^ir)
> 
>    {SK_d' | SK_ai | SK_ar | SK_ei | SK_er | SK_pi' | SK_pr'}
>                       = prf+ (SKEYSEED, Ni | Nr | SPIi | SPIr)
> 
>    If no PPK available, then
> 
>    SK_d = SK_d'
>    SK_pi = SK_pi'
>    SK_pr = SK_pr'
> 
>    If PPK is available then
> 
>    SK_d = prf(PPK, SK_d')
>    SK_pi = prf(PPK, SK_pi')
>    SK_pr = prf(PPK, SK_pr')
> 
> This has the follolowing benefits. The SK_d modification will mean
> that IKEv2 SA will gain protection against Quantum Resistance after
> the IKEv2 SA irs rekeyed, as rekeyed SA will be using SK_d to derive
> new keys. SK_d also used to derive the KEYMAT, meaning the Child SA
> will gain protection.

For this property it is enough to modify calculation of SK_d only.

> Modifying the SK_pi, and SK_pr will mean that if the PPK is wrong the
> IKEv2 authentication will fail, and we will get exactly same failure
> for wrong PPK than we do with wrong shared key or digital signature
> failures. This means that attacker do not gain any information which
> part of the authentication failed.

I'm not sure it is a good property. Sure, it gives an attacker no 
information about which part of authentication (signature or PPK) 
failed, but it gives local user no such information too. And
this is really bad, because in case of authentication failure users 
will have hard time finding which part to blame and will
most probably just switch PPK off.

On the other hand, the nice property of modifying SK_pi and SK_pr
is that even the initial exchange is authenticated even in case an attacker
can break digital signatures on the fly (sure, she can break DH and see what
is inside IKE_AUTH, but she cannot change the content unless she breaks PPK too).

I think that if SK_pi and SK_pr are modified, then some information
should be given to the user to help distinguish PPK errors from
signature errors. For example, the Initiator can include something like

N(PPK_INDICATOR) = prf(PPK, Ni | Nr | 0)

into the IKE_AUTH request, and the responder can include something like

N(PPK_INDICATOR) = prf(PPK, Ni | Nr | 1)

into the IKE_AUTH response. In this case each side can verify
that the other end do own and use the correct PPK before starting
computationally expensive public-key operations.
In case the PPK is incorrect AUTHENTICATION_FAILED
notification can be sent to the peer (as with any other authentication
errors), but local user will know which part of the authentication goes wrong.
Or probably some new notification (e.g. WRONG_PPK) can be sent
instead of (or in addition to) AUTHENTICATION_FAILED, if we want
the peer to have better diagnostics.

Regards,
Valery.

> [email-masked]

---

From: "Scott Fluhrer (sfluhrer)" <[email-masked]>
Date: Mon, 3 Apr 2017 16:17:34 +0000

I started editting the draft to incorporate this change, and I ran into a conflict with another part of the protocol: incremental rollout.  I'd like some quick advice about how to deal with the conflict.

Here's the feature it's in conflict with: in order to support 'brown-field' deployments (that is, an existing IKE infrastructure that people will be deploying this to), the current draft specifically allows an IKE implementation to be in a state where it works both with peers that implement this, and peers that do not; the idea being that the administrator would first upgrade all their nodes to work in this special intermediate mode; and once they've done they, they then upgrade their nodes to 'do QR-only' mode.  This is twice as much work for the administrators; however at no point of time is any network blockage (as two peers will always be able to negotiate).

Currently, whether we're using a PPK is negotiated by the N(PPK_NOTIFY) notifies that is sent in the first encrypted message; the responder learns whether or not the initiator supports this draft (and has a PPK) by whether the notify is there.  However, that same encrypted message includes the AUTH payload; which is generated using the SK_pi.  And, if the initiator isn't sure if we're using the PPK, it wouldn't know whether to use SK_pi' or prf(PPK, SK_pi')

Some obvious ways to address this:

- Move the notifies to the prior messages (that is, in the clear).  If we do this, then by the time we derive keys, we know whether we're using a PPK (even if the responder doesn't know which one it is until it hears the initiator's id).  This would mean that anyone could tell whether the two sides are using a PPK

- Drop this intermediate mode; that is, make it determanistic to whether we're uisng the PPK (based on the peer identity).  This would make roll-out more challenging, but it would simplify the implementations.

- For the initiator's AUTH payload, use SK_pi' always.  However, I suspect this would partially mess up the reason we're strirring it into SK_pi in the first place.

Opinions?  Does any other options come to mind?

> -----Original Message-----
> From: IPsec [mailto:[email-masked]] On Behalf Of Tero Kivinen
> Sent: Wednesday, March 29, 2017 7:11 PM
> To: [email-masked]
> Subject: [IPsec] Quantum Resistance SK_d, SK_pi, SK_pr etc mixing
> 
> So I have proposed earlier that we should mix the ppk to SK_d, SK_pi, and
> SK_pr, i.e., something like this:
> 
> This has the follolowing benefits. The SK_d modification will mean that IKEv2
> SA will gain protection against Quantum Resistance after the IKEv2 SA irs
> rekeyed, as rekeyed SA will be using SK_d to derive new keys. SK_d also
> used to derive the KEYMAT, meaning the Child SA will gain protection.
> 
> IKEv2 authentication will fail, and we will get exactly same failure for wrong
> PPK than we do with wrong shared key or digital signature failures. This
> means that attacker do not gain any information which part of the
> authentication failed.
> 
> I do so that in the early cases the PPKs are going to be configured manually in
> the system and there is quite big propability they being wrong, and catching
> the misconfigurations with proper error code is better, than just getting the
> random garbage on the Child SA data.
> --
> [email-masked]
> 
> _______________________________________________
> IPsec mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/ipsec

---

From: Paul Wouters <[email-masked]>
Date: Mon, 3 Apr 2017 13:21:26 -0400 (EDT)

> - Move the notifies to the prior messages (that is, in the clear).  If we do this, then by the time we derive keys, we know whether we're using a PPK (even if the responder doesn't know which one i…

I dont like this idea very much, unless it is using ephemral IDs. I did
think we wanted to add that as an option but perhaps not in this draft?

> - Drop this intermediate mode; that is, make it determanistic to whether we're uisng the PPK (based on the peer identity).  This would make roll-out more challenging, but it would simplify the impl…

I would think this is the obvious solution. I would not want to run a
connection definition that you can connect to "with or without PPK" and
run the risk of downgrade attack until the very last host has upgraded
to support PPK.

Paul

---

From: "Graham Bartlett (grbartle)" <[email-masked]>
Date: Mon, 3 Apr 2017 20:32:21 +0000

Hi Paul

Would a downgrade attack be possible if the PPK notify is included in the authentication material ?

cheers

On 03/04/2017, 18:21, "IPsec on behalf of Paul Wouters" <[email-masked] on behalf of [email-masked]> wrote:

    Paul

---

From: "Valery Smyslov" <[email-masked]>
Date: Tue, 4 Apr 2017 15:06:17 +0300

Hi Scott,

> I started editting the draft to incorporate this change, and I ran into a conflict with another
part of the
> protocol: incremental rollout.  I'd like some quick advice about how to deal with the conflict.
> 
> Here's the feature it's in conflict with: in order to support 'brown-field' deployments (that is,
an existing IKE
> infrastructure that people will be deploying this to), the current draft specifically allows an
IKE
> implementation to be in a state where it works both with peers that implement this, and peers that
do not;
> the idea being that the administrator would first upgrade all their nodes to work in this special
> intermediate mode; and once they've done they, they then upgrade their nodes to 'do QR-only' mode.
> This is twice as much work for the administrators; however at no point of time is any network
blockage (as
> two peers will always be able to negotiate).
> 
> Currently, whether we're using a PPK is negotiated by the N(PPK_NOTIFY) notifies that is sent in
the first
> encrypted message; the responder learns whether or not the initiator supports this draft (and has
a PPK)
> by whether the notify is there.  However, that same encrypted message includes the AUTH payload;
which
> is generated using the SK_pi.  And, if the initiator isn't sure if we're using the PPK, it
wouldn't know
> whether to use SK_pi' or prf(PPK, SK_pi')
> 
> - Move the notifies to the prior messages (that is, in the clear).  If we do this, then by the
time we derive
> keys, we know whether we're using a PPK (even if the responder doesn't know which one it is until
it hears
> the initiator's id).  This would mean that anyone could tell whether the two sides are using a PPK

I prefer this way. In more detail:

IKE_SA_INIT:
Initiator:
                           SA, KE, Ni,
                           [N(PPK_SUPPORTED),]
                           [V+][N+]                                -->

PPK_SUPPORTED notification indicated that the Initiator supports PPK and is willing to use it.
This notification contains no data.

Responder:
                    <-- SA, KE, Nr,
                          [CERTREQ+,]
                           [N(PPK_SUPPORTED),]
                           [V+][N+]

If the Responder supports PPK it will return PPK_SUPPORTED back in the IKE_SA_INIT reply.
Otherwise the Responder ignores this notification and PPK is not used in the following exchange.

Assuming both sides support PPK:

IKE_SA_AUTH:
Initiator:
                       HDR, SK {IDi, [CERT,] [CERTREQ,]
                                       [IDr,] AUTH, SAi2,
                                       TS, TSr, N(USE_PPK)}  --->

USE_PPK notification helps the Responder to select the right PPK and to ensure that 
the Initiator really possess the correct PPK value. Its data is computed as prf(SK_pi, Ni | Nr),
where SK_pi is as in Tero's proposal (SK_pi = prf(PPK, SK_pi')). Having this notification included
will solve two issues:
- first, the Responder can verify that the Initiator does have the correct PPK (i.e. PPK
misconfiguration
   errors become clear and can be distinguished from certificates configuration errors). Moreover,
   the Responder can verify that PPK is correct before starting computational expensive 
   signature verification. 
- if PPK selection is ambiguous, this notification can help select the right PPK.
  This can happen in situation of PPK rollover, when old PPK is being changed with a new one,
  and since this cannot happen overnight, there may be some period of time when peer's
   account is associated with two PPKs (security officer first adds a new PPK to the server,
   then replaces an old PPK with the new one on the client and finally removes an old PPK from the
server).

Responder:
                             <--- HDR, SK {IDr, [CERT,] AUTH,
                                      SAr2, TSi, TSr, N(USE_PPK)}

USE_PPK notification data is computed as prf(SK_pr, Ni | Nr), where SK_pr is as in Tero's proposal
(SK_pr = prf(PPK, SK_pr')).

AUTH payload is computed as in Tero's proposal. If a host detects that it has no PPK that matches
the peer's
USE_PPK data, it can return either AUTHENTICATION_FAILED (this will leak no information to a passive
observer of which part of authentication failed) or a new error notification WRONG_PPK (this would
allow
the peer to make some conscious actions to resolve the situation), or both.

> - Drop this intermediate mode; that is, make it determanistic to whether we're uisng the PPK
(based on the
> peer identity).  This would make roll-out more challenging, but it would simplify the
implementations.

This will make incremental introducing of PPK next to impossible.

> - For the initiator's AUTH payload, use SK_pi' always.  However, I suspect this would partially
mess up the
> reason we're strirring it into SK_pi in the first place.

Agree that it would mess up the initial reason.

Regards,
Valery.

---

From: Tero Kivinen <[email-masked]>
Date: Tue, 4 Apr 2017 15:23:16 +0300

> most probably just switch PPK off.

And if that helps, they do know that the problem was in the PPK. Also
depending on the authentication algorithm there is more cases that
result authentication failure and which are known to local user (i.e.,
expired or revoked certificates, unknown trust anchor, EAP
authentication failure etc). With certificates or with EAP you should
not really get failures in the AUTH calculation unless there is bug in
your code, or there is attacker on the line modifying the bits.

Only case where you get authentication failure which just results
invalid AUTH is when you are using shared key authentication and then
you do not know whether it is the shared secret or PPK which is wrong
(or whether there is bug in implementation or attacker modifying the
bits).

Turning PPK off and retrying and see if that helps will tell you
whether it is the PPK or the shared secret which is wrong, and that is
quite easy way to debug issues. 

> On the other hand, the nice property of modifying SK_pi and SK_pr is
> that even the initial exchange is authenticated even in case an
> attacker can break digital signatures on the fly (sure, she can
> break DH and see what is inside IKE_AUTH, but she cannot change the
> content unless she breaks PPK too).

Yep.

> computationally expensive public-key operations.

That does not help. We need to Diffie-Hellman before we can see the
IKE_AUTH contents, so when we are doing that verification we have
already done the expensive operations. On the other hand as this issue
is not really with certificates, we are not doing actual public key
operation when calculating the AUTH payload, we are simply ding the
prf with shared secret.

With certificates the public key used is already sent in the
certificate payload inside the exchange, so it is known, and if there
is problems verifying it, we know it before we end up in the AUTH
calculation, and we return AUTHENTICATION_FAILED without ever
calculating the AUTH payload.

> the peer to have better diagnostics.

I do not think that is needed, and I definately do not want to tell
attackers whether it was the PPK or something else that caused
AUTHENTICATION_FAILED notification. It would be fine to tell that in
the logs, but not on the wire. Even in the logs I do not think it is
that important, as there as easy ways to debug this.
-- 
[email-masked]

---

From: Tero Kivinen <[email-masked]>
Date: Tue, 4 Apr 2017 15:54:40 +0300

[Not wearing any hats]

Scott Fluhrer (sfluhrer) writes:
> - Move the notifies to the prior messages (that is, in the clear).
> If we do this, then by the time we derive keys, we know whether
> we're using a PPK (even if the responder doesn't know which one it
> is until it hears the initiator's id).  This would mean that anyone
> could tell whether the two sides are using a PPK

Currently PPK_NOTIFY is empty notification so moving that to the the
IKE_SA_INIT and changing its name to PPK_SUPPORTED is fine.

Sending the actual PPK identity is better done on the IKE_AUTH where
it is protected by the Diffie-Hellman, meaning attacker needs to do
active attack to learn it.

So I think protocol should be something like 

   Initiator                         Responder
   -------------------------------------------------------------------
   HDR, SAi1, KEi, Ni,
   	N(PPK_SUPPORTED) -->
                                <--  HDR, SAr1, KEr, Nr,
                                     	  N(PPK_SUPPORTED), [CERTREQ]
   HDR, SK {IDi, [CERT,] [CERTREQ,]
       [IDr,] AUTH, SAi2,
       N(PPK_IDENTITY, <ppk_id>), 
       TSi, TSr}  -->
                                <--  HDR, SK {IDr, [CERT,] AUTH,
                                         SAr2, TSi, TSr}

Where the N(PPK_SUPPORTED) just tells that both ends support PPK, and
they have at least one PPK installed. This means that incremental
installation needs to be done so that all possible PPKs are always
installed for each identity to the machine once, i.e., it either knows
PPKs for all IDs and sends N(PPK_SUPPORTED) or it does not send
N(PPK_SUPPORTED) at all.

I.e., you cannot install just PPKs for half of the users and enable
N(PPK_SUPPORTED). PPK will be enabled only and only if both ends send
N(PPK_SUPPORTED) during the IKE_SA_INIT.

Then during the IKE_AUTH the initiator picks PPK to use and sends the
<ppk_id> associated with the PPK in the N(PPK_IDENTITY, ...) notify
and uses the PPK to generate the AUTH. If it only has one PPK meaning
the <ppk_id> does not have any meaning it will send it as empty. If it
does not send PPK_IDENTITY at all, that means it is not using PPK even
when it was enabled (this can be used for example to test whether the
authentication problem is in the shared secret being wrong or in the
case where the PPK is wrong).

If N(PPK_IDENTITY, <ppk_id>) was sent by the initiator then responder
will find the matching for the user specified in the IDi and will use
that when calculating AUTH. The ppk_id is opaque binary string and
will be be interpreted at all by the IKE, but the PPK management
module might provide internal format for it.

For example if the PPKs are taken from the 1GB one-time-pad file
shared by the peers (one file per user), then the ppk_id could simply
be 32-bit offset to the file, and the external PPK management module
would keep track which of the offsets are used and which are not.

If the ppk_id is not known by the responder, then it will return
N(AUTHENTICATION_FAILED) error and log the error to the local log
file.

If EAP is used, then exchange is bit different:

   Initiator                         Responder
   -------------------------------------------------------------------
   HDR, SAi1, KEi, Ni,
   	N(PPK_SUPPORTED) -->
                                <--  HDR, SAr1, KEr, Nr,
                                     	  N(PPK_SUPPORTED), [CERTREQ]
   HDR, SK {IDi, [CERTREQ,]
       [IDr,] SAi2,
       N(PPK_IDENTITY, <ppk_id>), 
       TSi, TSr}  -->
                                <--  HDR, SK {IDr, [CERT,] AUTH, EAP}
   HDR, SK {EAP}  -->
                                <--  HDR, SK {EAP (success)}
   HDR, SK {AUTH}  -->
                                <--  HDR, SK {AUTH, SAr2, TSi, TSr}

I.e., the PPK_IDENTITY is still sent inside the first IKE_AUTH, but of
course in this case the actual PPK is not used by the initiator yet.
The responder will then reply with AUTH payload using the PPK, and the
final exchange uses the PPK again in both ends.

With EAP only authentication (RFC5998) the exchange is about same,
except now we do not have "[CERT,] AUTH" in the responders first
IKE_AUTH message, and the PPK is only used in the final IKE_AUTH
exchange when calculating AUTH payloads.

The NULL authentication (RFC7619) is logically incompatible with this
(it being opportunistic and this requiring configuration), so I think
we can say this will not be used with it. Or we can just say that can
be used, and SK_pi are used as specified here and in the RFC7619... 

> - For the initiator's AUTH payload, use SK_pi' always.  However, I
>   suspect this would partially mess up the reason we're strirring it
>   into SK_pi in the first place. 

That would be one option too. I.e., only modify SK_pr. I think it
actually would be enough, as we do trust the other end to do correct
things, and this would be enough to know whether peers share the same
PPK. On the other hand we will end up annoying case where the
initiator will know that PPK is wrong after the IKE_SA has already
been properly installed on the responder, thus initiator needs to
signal this with separate INFORMATIONAL exchange to the responder, and
thne delete IKE SA. I think the option I explained above is better.
-- 
[email-masked]

---

From: "Valery Smyslov" <[email-masked]>
Date: Tue, 4 Apr 2017 16:03:02 +0300

Hi Tero,

> already done the expensive operations. 

Sure.

> On the other hand as this issue

If PPK is used then we first verify that PPK is correct and only
after that start verifying certificates and AUTH payload.
In case PPK is incorrect this saves us quite a lot of computation.

Regards,
Valery.

---

From: Paul Wouters <[email-masked]>
Date: Tue, 4 Apr 2017 11:10:09 -0400 (EDT)

> would keep track which of the offsets are used and which are not.

This is vulnerable to a DOS attack though. The attacker once inserts
themselves to get IDi. Then they connect to the server often enough
with increased offsets to fail authentication, depleting the
one-time-pad file for the real user, who presumbly then is locked out.

Not announcing PPK support would not help much, as sending obvious
offsets would still be detectable.

Is there a way to securely use the same OTP ofset until AUTH is
successful?

> be used, and SK_pi are used as specified here and in the RFC7619...

I would just say don't use both :)

> thne delete IKE SA. I think the option I explained above is better.

Not a fan of this :)

Paul

---

From: "Scott Fluhrer (sfluhrer)" <[email-masked]>
Date: Tue, 4 Apr 2017 15:41:05 +0000

Going through this suggestion (and tweaking it a bit):

Pluses:
- It is more flexible; in addition to supporting the fixed PPK's, it would also allow support for one-use PPKs (as you mention), as well as being easy to extend to handle Phillip LaFrance's PFS ideas.
- Even for fixed PPK's, it makes it possible to update the PPKs in a bump-less fashion.
- I believe it can be made a bit more flexible than you make it out; it don't believe that you actually need to update every node with every PPK at the start.  With this protocol, the initiator decides which PPK to use (and whether to use a PPK at all; the obvious idea would be 'if the initiator doesn't' send a PPK_NOTIFY message, no PPK is in use').  With this, the upgrade procedure becomes:
	Step 1: configure the PPKs and the id's on each peer.  This will allow each side to use this protocol if it was the responder, but not insist on it if it's the initiator
	Step 2: for each peer, configure which PPK to use (probably based on peer identity), and make its use optional.  That is, when we're initiating, we'll now use the PPK; however, if we're the responder, we'll use the PPK if the initiator asks, but not reject the SA if he doesn't
	Step 3: for each peer, make the use of PPK mandatory (and so if we're the responder, when we get the initiator's identity, we see that the use of PPK was required; if we didn't get PK_NOTIFY, we'll reject the request)
  Again, we don't need to upgrade the entire network at once; we could incrementally do this by peer-to-peer connection...

Minus:
- It makes roll out possible, but (as above) it's a 3 step affair, rather than the previous 2 step. 
- We also need to specify the format of the ppk_id.  This isn't that hard, however we did want an updated revision Real Soon Now, and this format doesn't feel like something I want to just slap together....

Also, with the above tweak, I'm not certain what value the PPK_SUPPORTED notify brings to the table; you had it for the responder to signal to the initiator that it's been upgraded; the above protocol has the initiator expecting whether specific responders are upgraded or not.  It might make debugging a bit easier...

Another thing to consider: what if we're the responder, and the initiator uses a PPK (which we have), but not the PPK we would have used if we're the initiator.  I believe that we want to accept this (even if our PPK is marked as mandatory); would that lead to any potential problems?

Thoughts???

> From: Tero Kivinen [mailto:[email-masked]]
> Sent: Tuesday, April 04, 2017 8:55 AM
> To: Scott Fluhrer (sfluhrer)
> Cc: [email-masked]
> Subject: RE: [IPsec] Quantum Resistance SK_d, SK_pi, SK_pr etc mixing
> 
> [Not wearing any hats]
> 
> > If we do this, then by the time we derive keys, we know whether we're
> > using a PPK (even if the responder doesn't know which one it is until
> > it hears the initiator's id).  This would mean that anyone could tell
> > whether the two sides are using a PPK
> 
> Sending the actual PPK identity is better done on the IKE_AUTH where it is
> protected by the Diffie-Hellman, meaning attacker needs to do active attack
> to learn it.
> 
> they have at least one PPK installed. This means that incremental installation
> needs to be done so that all possible PPKs are always installed for each
> identity to the machine once, i.e., it either knows PPKs for all IDs and sends
> N(PPK_SUPPORTED) or it does not send
> N(PPK_SUPPORTED) at all.
> 
> <ppk_id> associated with the PPK in the N(PPK_IDENTITY, ...) notify and uses
> the PPK to generate the AUTH. If it only has one PPK meaning the <ppk_id>
> does not have any meaning it will send it as empty. If it does not send
> PPK_IDENTITY at all, that means it is not using PPK even when it was enabled
> (this can be used for example to test whether the authentication problem is
> in the shared secret being wrong or in the case where the PPK is wrong).
> 
> If N(PPK_IDENTITY, <ppk_id>) was sent by the initiator then responder will
> find the matching for the user specified in the IDi and will use that when
> calculating AUTH. The ppk_id is opaque binary string and will be be
> interpreted at all by the IKE, but the PPK management module might provide
> internal format for it.
> 
> For example if the PPKs are taken from the 1GB one-time-pad file shared by
> the peers (one file per user), then the ppk_id could simply be 32-bit offset to
> the file, and the external PPK management module would keep track which
> of the offsets are used and which are not.
> 
> N(AUTHENTICATION_FAILED) error and log the error to the local log file.
> 
> I.e., the PPK_IDENTITY is still sent inside the first IKE_AUTH, but of course in
> this case the actual PPK is not used by the initiator yet.
> The responder will then reply with AUTH payload using the PPK, and the final
> exchange uses the PPK again in both ends.
> 
> With EAP only authentication (RFC5998) the exchange is about same, except
> now we do not have "[CERT,] AUTH" in the responders first IKE_AUTH
> message, and the PPK is only used in the final IKE_AUTH exchange when
> calculating AUTH payloads.
> 
> The NULL authentication (RFC7619) is logically incompatible with this (it being
> opportunistic and this requiring configuration), so I think we can say this will
> not be used with it. Or we can just say that can be used, and SK_pi are used
> as specified here and in the RFC7619...
> 
> That would be one option too. I.e., only modify SK_pr. I think it actually
> would be enough, as we do trust the other end to do correct things, and this
> would be enough to know whether peers share the same PPK. On the other
> hand we will end up annoying case where the initiator will know that PPK is
> wrong after the IKE_SA has already been properly installed on the
> responder, thus initiator needs to signal this with separate INFORMATIONAL
> exchange to the responder, and thne delete IKE SA. I think the option I
> explained above is better.
> --
> [email-masked]

---

From: Tero Kivinen <[email-masked]>
Date: Wed, 5 Apr 2017 15:24:10 +0300

> one-time-pad file for the real user, who presumbly then is locked out.

Nope. Like normally you are not using the data in the file unless it
is properly authenticated. I.e. even if the attacker can say use PPK
from offset 0x123123, the other end will not update the offset
0x123123 to be used unless the other end also proofs it knows the PPK
at that offset.

It is same as we do not update the ESP replay counter unless the
packet actually has valid authentication token.

And this was the exact issue the 802.15.4 had with encrypt only mode,
i.e., with encrypt only mode there was no authentication tag, so the
responder was always required to assume packet is valid, and then it
updated the global frame counter of the sending device, and if
attacker sent frame counter of 0xfffffffe, that effectively locked the
sending device out permanently. This is the reason encrypted only mode
was removed in the 802.15.4-2015....

And the real user will most likely be locked out earlier because when
the attacker starts to do several tens of million IKE connections to
the server the server will most likely lock the user out or add
delays to connections long before the attacker is able to deplate the
one time pad... 

Yep.

> Is there a way to securely use the same OTP ofset until AUTH is

Yes. This is what all OTP methods do. If you give wrong value for OTP
token, they will ask the same value over and over again until you get
it right. In addition to that they usually add longer and longer
delays if you get it wrong several times in the row and finally lock
you out. They might even give you information saying that you typed
OTP response for number 15, but current response number required is
16. For example the bank in Finland which uses OTP tokens does that,
but only if you give correct response to the number that was already
used. They also say that if you have completely lost the number where
you are, type in the last number in the list, and they will then tell
you what number is the next number on the list (I assume they will
then mark the last number used, and next time ask for second last
number etc). 

> I would just say don't use both :)

Good. I was scared you might say, that of course we need to be able to
use NULL authentication with quantum protection... 
-- 
[email-masked]

---

From: Tero Kivinen <[email-masked]>
Date: Wed, 5 Apr 2017 16:00:31 +0300

Scott Fluhrer (sfluhrer) writes:
> - I believe it can be made a bit more flexible than you make it out;
> it don't believe that you actually need to update every node with
> every PPK at the start.  With this protocol, the initiator decides

I did not even require that. I said you need to provide all PPKs for
that one node at the same time. Or at least that I was trying to say.
I can now see that my text was bit unclear.

I.e., when you configure node A for PPK use, you need to give node A
all the PPKs for all peers it has. I.e., the configuration loaded on
the node A needs to provide all PPKs it will need.

Then you can do same thing for other nodes one by one cases. I.e., you
do not need to update the whole network at once, but you need to
provide full configuration for the one device at the same time.

After node A is configure with all PPKs, it will start sending
N(PPK_SUPPORTED) notifications. If it connects to other node which has
been reconfigured, then that node will also respond with
N(PPK_SUPPORTED) and they will use PPK. If it connects to node which
has not yet been reconfigured, then the node will not send
N(PPK_SUPPORTED) and PPK will be disabled.

> which PPK to use (and whether to use a PPK at all; the obvious idea
> would be 'if the initiator doesn't' send a PPK_NOTIFY message, no
> PPK is in use').  With this, the upgrade procedure becomes: 
> 	Step 1: configure the PPKs and the id's on each peer.  This
> will allow each side to use this protocol if it was the responder,
> but not insist on it if it's the initiator 
> 	Step 2: for each peer, configure which PPK to use (probably
> based on peer identity), and make its use optional.  That is, when
> we're initiating, we'll now use the PPK; however, if we're the
> responder, we'll use the PPK if the initiator asks, but not reject
> the SA if he doesn't 
> 	Step 3: for each peer, make the use of PPK mandatory (and so
> if we're the responder, when we get the initiator's identity, we see
> that the use of PPK was required; if we didn't get PK_NOTIFY, we'll
> reject the request) 
>   Again, we don't need to upgrade the entire network at once; we
> could incrementally do this by peer-to-peer connection...

Yes. That was there already in my proposal (but text was bit unclear). 

> rather than the previous 2 step.

Actually it is not 3 step affair, it is one step affair for each node.

Step 1) Install configuration having PPKs for node A.

Repeat step 1 on all other nodes, at will. Immediately when both pairs
of the connections have been reconfigured they will start using PPK.

If you want to change the configuration so that PPK is required then
that is second reconfiguration for the whole network, but this is not
something that needs to be done, as properly configured systems will
always use PPK if both ends have been reconfigured to have PPKs,
unless initiator explictly disables it for this connection (i.e., for
example for debugging purposes).

Only reason why you want to enforce the PPKs to be used always, is
when you know that your attacker can already break Diffie-Hellman on
real time, and can also break your authentication method in real time.
Then you need to use PPK to protect the authentication, as if attacker
is able to break the authentication in real time, then it can also
modify the packets on the wire by removing the N(PPK_IDENTITY) or
N(PPK_SUPPORTED) notifies and disabled PPK. If the authentication
(and Diffie-Hellman) cannot be broken in real time then authentiation
will prevent attacker disabling PPK. 

> - We also need to specify the format of the ppk_id. This isn't that
> hard, however we did want an updated revision Real Soon Now, and
> this format doesn't feel like something I want to just slap
> together....

Actually for both ppk_id, and the PPK value used in the calculations,
I would suggest following:

	Both the the ppk_id inside the N(PPK_IDENTITY) and the PPK
	value used in the SK_d/SK_pi/SK_pr calculations are opaque
	octect streams. Implementations supporting PPK, MUST support
	ppk_ids having length of less than 64 octets, and MAY support
	longer ppk_id values. The PPK itself MUST have length between
	16 and 64 octets.

	When both ppk_id and PPK are represented in the user interface
	the user interface MUST allow any octet stream to be
	represented (i.e., it must not assume that it can safely print
	the ppk or ppk_id to screen without any encoding them to
	printable characters), and MUST provide a way to input ppk_id
	and PPK in base64-encoded ascii string. User interface MAY
	allow other formats too, like plain ASCII, UTF-8, or
	hex-string. This requirement is only for the user interface,
	if the API is used to configure the ppk_id and PPK, then
	direct binary representation can be used and no base64 version
	of the API is needed.

	Note, that both ppk_id and PPK are octet streams, they are not
	assumed to be any kind of strings, thus they do not have
	associated character sets, and while UTF-8 strings are valid
	values for them, there is no character set specific processing
	for them.

> Also, with the above tweak, I'm not certain what value the
> PPK_SUPPORTED notify brings to the table; you had it for the
> responder to signal to the initiator that it's been upgraded; the
> above protocol has the initiator expecting whether specific
> responders are upgraded or not.  It might make debugging a bit
> easier...

Yes. It will allow setup to be done using 1 phase protocol instead of
3 phases. I.e. as N(PPK_SUPPORTED) tells to both ends whether they
have been configured with the needed information to do PPK, and after
that they will know they can use PPK if they like.

This is also the way we have done things with other extensions, i.e.,
exchange notification in the IKE_SA_INIT for supported features. 

> Another thing to consider: what if we're the responder, and the
> initiator uses a PPK (which we have), but not the PPK we would have
> used if we're the initiator.  I believe that we want to accept this
> (even if our PPK is marked as mandatory); would that lead to any
> potential problems?

I would say it depends on the PPK. If we use one-time-use PPKs, then
we will reject PPKs we know have already been used earlier. If we are
doing PPK rotation weekly, and other end moves to next PPK earlier
than we would have, we can allow that, as there most likely are reason
for that and this was caused by the adminstrator doing something. For
example the previous PPK was somehow compromized or lost, and the
other peer wants to move the the next one because of that.
-- 
[email-masked]

---

From: Paul Wouters <[email-masked]>
Date: Wed, 5 Apr 2017 11:40:02 -0400 (EDT)

> 0x123123 to be used unless the other end also proofs it knows the PPK

That opens up an attack where an attacker can trick you into re-using
the same PPK many times. I was assuming that could be dangerous in
itself? If it is not, then we should clearly explain that in the
document.

> delays to connections long before the attacker is able to deplate the

If the attacker can lock out the real user, that is also a DOS attack :)

> use NULL authentication with quantum protection...

My intention is to create so much AUTH_NULL IKE that I really hope the
TLA's cannot store all that ESP traffic to decrypt it with their fancy
new quantum computer in five years :)

Paul

---

From: "Scott Fluhrer (sfluhrer)" <[email-masked]>
Date: Wed, 5 Apr 2017 19:30:21 +0000

Ok, I now see what part of your idea I was (sort of) trying to work around.  To make it clear to everyone, I'll spell out the problem we're trying to address, and how your idea (with a slight addition on my part) could address it.

What we're talking about is "how would someone take a network that's using the standard IKE implementation, and convert it into a network that uses IKE+PPKs, and in a way that doesn't cause a flag day, or prevent negotiations from happening between nodes while the upgrade is in progress.

The idea is that the network admin goes through the nodes, and upgrades them in order; in step 0, the nodes are running standard IKE, and in the final step, they are running the full PPK protocol (and insist on using it).  For the upgrade to be bumpless, we require that any node at step i be able to communicate (as either initiator or responder) with a node at step i-1, i or i+1 (assuming, of course, that our security policy allows those two nodes to communicate).

With your idea, there are three steps (and so the admin would update each node in the network twice):

- Step 0 is "never use PPKs"; we're running the standard IKE protocol.
- Step 1 is "if we're the initiator, then use PPKs if the responder signaled support for it"
    "if we're the responder, then signal support, and allow the use of PPKs"
- Step 2 is "insist on PPKs (and also signal support if we're the responder)"

The issue I was pondering was "what if the admin wants to update only part of their network (say, as a test)?".  As I understood your proposal, the PPK_SUPPORT notify was always on if any PPKs were configured; indeed, from a responder side, it has to be that (because the responder has no other context to issue it or not).  However, from an initiator standpoint, it knows who the responder is (or, at least, it has to; it's the one that selects which PPK to use); hence, from the initiator standpoint, the PPK_SUPPORT notify could mean "I have a PPK that I would like to use with you, are you willing?"

With that proviso, then partial upgrades of the network can work; if an initiator (in the upgraded portion) talks to a responder in an nonupgraded section (or in an independently upgraded section), it just notes it doesn't have a PPK, and so doesn't send the notify (and similarly, if it was the initiator who wasn't upgraded, the responder performs the standard IKE protocol, and when the responder gets the identity, it can verify whether or not it would have expected the initiator to be upgraded).

So, how does that sound?

---

From: "Valery Smyslov" <[email-masked]>
Date: Thu, 6 Apr 2017 10:52:50 +0300

Hi, 

> use NULL authentication with quantum protection...

If both peers use NULL authentication, then there is no sense to use PPK,
since it is assumed that there is no trusted relationship between them
(and thus they don't share PPK). However, if NULL authentication is used
by only one peer (e.g. to keep his/her anonymity), then the PPK 
can be used by the other side.

Regards,
Valery.

---

From: "Valery Smyslov" <[email-masked]>
Date: Thu, 6 Apr 2017 11:35:20 +0300

Hi Tero,

> the node A needs to provide all PPKs it will need.

If node A is mostly an initiator (e.g. a remote access client),
then it knows beforehand to whom it is trying to connect. So you
may provide it only with PPKs for some nodes. Then the node A
will send PPK_SUPPORTED only in case it is connecting to a peer,
for which the node A has a PPK. This way you may deploy PPK
incrementally or partially (only to some part of the network).

For responder the situation is worse. At the moment it sends PPK_SUPPORTED
it doesn't know whether it has a PPK for this particular initiator.
So it must be preconfigured with PPKs for all possible initiators
before starting to reply with PPK_SUPPORTED.

> 	longer ppk_id values. The PPK itself MUST have length between

I'd rather add a type field to ppk_id. So the ppk_id is constructed
of 2 fields: type and value. Types could be:
1. raw id
2. OTF file offset
3. PPK dependent id
...

For the 3rd option the ppk_id is constructed using the PPK
itself and a session parameters, e.g. ppk_id = prf(PPK, Ni | Nr).
This would allow the responder to check whether PPK is correct
before verifying AUTH payload.

In general, having a type value would simplify PPK management in case
a host have PPKs of different types and need to look them up 
in different storages.

Regards,
Valery.

---

From: "Valery Smyslov" <[email-masked]>
Date: Thu, 6 Apr 2017 11:37:42 +0300

Hi Scott,

> The issue I was pondering was "what if the admin wants to update only part of their network (say,
as a
> test)?".  As I understood your proposal, the PPK_SUPPORT notify was always on if any PPKs were
> configured; indeed, from a responder side, it has to be that (because the responder has no other
context
> to issue it or not).  However, from an initiator standpoint, it knows who the responder is (or, at
least, it has
> to; it's the one that selects which PPK to use); hence, from the initiator standpoint, the
PPK_SUPPORT
> notify could mean "I have a PPK that I would like to use with you, are you willing?"
> 
> With that proviso, then partial upgrades of the network can work; if an initiator (in the upgraded
portion)
> talks to a responder in an nonupgraded section (or in an independently upgraded section), it just
notes it
> doesn't have a PPK, and so doesn't send the notify (and similarly, if it was the initiator who
wasn't
> upgraded, the responder performs the standard IKE protocol, and when the responder gets the
identity, it
> can verify whether or not it would have expected the initiator to be upgraded).
> 
> So, how does that sound?

Indeed, this a reasonable scenario.

Regards,
Valery.

---

From: Tero Kivinen <[email-masked]>
Date: Thu, 6 Apr 2017 14:57:18 +0300

> itself? If it is not, then we should clearly explain that in the

How?

They can trick you trying to use same PPK multiple times, but all of
those tries will fail and no traffic is ever transmitted protected by
that PPK, thus it does not matter.

It is not dangerous to use same PPK many times. My understanding is
that in most cases the PPK will be static, and will not change very
often. To be able to change it often, you need some kind of protocol
to distribute them, and we currently do not have one yet.

The reason people might want to change PPK is to limit how much data
can be decrypted if someone succesfully hacks in to one of the end
points. I.e., if you have used the same PPK for last year, and then
someone hacks in to your machine and steals that PPK, then they can
break the Diffie-Hellman for your last years worth of traffic, and
decrypt it because they know the PPK.

If you change your PPK every day, and make sure that you destroy old
used PPKs out from the system, then hacker will only gain one days
worth of traffic they can attack on by breaking the Diffie-Hellman.
This means that you should zero out the part of file containing PPK
you used when that PPK is no longer needed (i.e., you move to next
one), so DVD full of random stuff is not very good for distributing
them. The memory sticks has same problem, as you are not sure if the
data has been erased securely from the stick...

> If the attacker can lock out the real user, that is also a DOS attack :)

Yep, and almost all systems do it already. I.e., if you give wrong
password enough times, the account is locked for some time, and at one
point they might even disable it permanently.

Thats why the old admin wisdom was always to create secondary admin
account with different username, and make sure nobody knows what that
username is, so when someone locks your "root" account you can log in
with that admin account and unlock the "root"...
-- 
[email-masked]

---

From: Tero Kivinen <[email-masked]>
Date: Thu, 6 Apr 2017 15:15:24 +0300

Scott Fluhrer (sfluhrer) writes:
> The issue I was pondering was "what if the admin wants to update
> only part of their network (say, as a test)?".  As I understood your
> proposal, the PPK_SUPPORT notify was always on if any PPKs were
> configured; indeed, from a responder side, it has to be that
> (because the responder has no other context to issue it or not).
> However, from an initiator standpoint, it knows who the responder is
> (or, at least, it has to; it's the one that selects which PPK to
> use); hence, from the initiator standpoint, the PPK_SUPPORT notify
> could mean "I have a PPK that I would like to use with you, are you
> willing?"

Yep.

> With that proviso, then partial upgrades of the network can work; if
> an initiator (in the upgraded portion) talks to a responder in an
> nonupgraded section (or in an independently upgraded section), it
> just notes it doesn't have a PPK, and so doesn't send the notify
> (and similarly, if it was the initiator who wasn't upgraded, the
> responder performs the standard IKE protocol, and when the responder
> gets the identity, it can verify whether or not it would have
> expected the initiator to be upgraded). 
> 
> So, how does that sound?

Looks good.
-- 
[email-masked]

---

From: Tero Kivinen <[email-masked]>
Date: Thu, 6 Apr 2017 17:00:16 +0300

> incrementally or partially (only to some part of the network).

Yes, if your setup is remote access client setup. IPsec in general is
host to host, thus there is no servers and clients, and connections
can be created in both direction.

Actually with remote access client setup, it is enough to install PPKs
to the SGW first, and then start installing PPKs to the clients as
needed. Each client will typically only connect to one SGW, so they
will need just one PPK installed.

> before starting to reply with PPK_SUPPORTED.

Yep, or it can also use the source ip address of the incoming packet
to help here. I.e., if you have site to site mesh setup for your VPN
service, then each site will have static IP-addresses, and responder
can see from the IP-address whether it has PPK for the other end or
not.

This of course does not work with the remote access clients, or even
in cases where the sites do not have fixed IP-addresses (i.e., small
or home office SGWs).

Anyways we do not need to specify all of these cases in the
specifications, those are mostly implementation details, which each
implementor can specify depending on the environment their product
will be working in.

We just need to understand what are the limitiations with the selected
method, and in this case it is that responder needs to know from the
IP-address alone whether it has the PPK it can use for the incoming
connection, and from that decide whether it should or should not send
PPK_SUPPORTED notify. 

> a host have PPKs of different types and need to look them up 

That is one possibility. Should the type be 8-bit or 16-bit? I assume
the registry itself should be IANA registry with designated expert
review or something like that.
-- 
[email-masked]

---

From: "Valery Smyslov" <[email-masked]>
Date: Thu, 6 Apr 2017 17:14:19 +0300

> That is one possibility. Should the type be 8-bit or 16-bit? 

8 bits seems enough, but I'd rather use 16 bits so that we 
(hopefully) never  run out of available values.

> I assume the registry itself should be IANA registry with designated expert

Sure.

---

From: Michael Richardson <[email-masked]>
Date: Thu, 06 Apr 2017 10:29:44 -0400

> - Step 1 is "if we're the initiator, then use PPKs if the responder
    > signaled support for it" "if we're the responder, then signal support,
    > and allow the use of PPKs"

    > support if we're the responder)"

This is a pretty normal process, yet it seems that some protocol designers
often do not take this in account.  I wonder if we should write this down
as a BCP.

{the rest of what you wrote is great}

--
Michael Richardson <[email-masked]>, Sandelman Software Works
 -= IPv6 IoT consulting =-

---

From: Paul Wouters <[email-masked]>
Date: Thu, 6 Apr 2017 10:58:28 -0400 (EDT)

> review or something like that.

I wouldn't want to broadcast my type of PPK used in IKE_INIT or
IKE_AUTH, as an active attacker could then learn this information.

Paul

---

From: "Valery Smyslov" <[email-masked]>
Date: Thu, 6 Apr 2017 18:05:43 +0300

Hi Paul,

> IKE_AUTH, as an active attacker could then learn this information.

She could learn a lot of more useful information - your identity,
traffic selectors, authentication method you are using, your certificates,
Configuration Attributes you request, IKE features you support etc. 

Among all this a type of PPK is not very interesting. 
Use type "opaque" if you are paranoid about that.

Regards,
Valery.

---

From: Michael Richardson <[email-masked]>
Date: Thu, 06 Apr 2017 11:37:42 -0400

Tero Kivinen <[email-masked]> wrote:
    >> Pluses: - I believe it can be made a bit more flexible than you make
    >> it out; it don't believe that you actually need to update every node
    >> with every PPK at the start.  With this protocol, the initiator
    >> decides

    > I can now see that my text was bit unclear.

Why do we need to provide PPKs for all peers at the same time?

    > Only reason why you want to enforce the PPKs to be used always, is when
    > you know that your attacker can already break Diffie-Hellman on real
    > time, and can also break your authentication method in real time.  Then
    > you need to use PPK to protect the authentication, as if attacker is
    > able to break the authentication in real time, then it can also modify
    > the packets on the wire by removing the N(PPK_IDENTITY) or
    > N(PPK_SUPPORTED) notifies and disabled PPK. If the authentication (and
    > Diffie-Hellman) cannot be broken in real time then authentiation will
    > prevent attacker disabling PPK.

Agreed, but I don't think this mandates that one load all the PPKs at the
same time, does it?

---

From: Tero Kivinen <[email-masked]>
Date: Mon, 10 Apr 2017 12:35:18 +0300

> Why do we need to provide PPKs for all peers at the same time?

Because responder tells that PPK is supported in the IKE_SA_INIT, and
then in the IKE_AUTH the initiator will either use PPK or not. If we
have responder configured so that it only has some PPKs, i.e., it has
PPK for node A, but not for node B, and both of those are nodes which
do not have static IP-address, then it does not know whether it should
send N(PPK_SUPPORTED) in IKE_SA_INIT. If it sends N(PPK_SUPPORTED) to
node B, then node B might use PPK in its IKE_AUTH AUTH payload
calculation, and if responder then does not have PPK it will not be
able to verify the AUTH payload and IKE_AUTH fails.

Of course if responder can know whether it has PPK for the initiator
based on the IP-address, then it does not need to have all PPKs for
all initiators that might connect to it. Simiarly if it is only acting
as iniatitor, it can always decide whether to use PPK or not. But in
general case it needs to know the PPKs for all peers that could
connect to it using PPK before it can start sending N(PPK_SUPPORTED).
-- 
[email-masked]

---

From: "Scott Fluhrer (sfluhrer)" <[email-masked]>
Date: Mon, 10 Apr 2017 14:59:52 +0000

I've been putting together the updates, and one question came up: what format should the PPK_ID field (sent be the initiator in the first encrypted message to identify the PPK it used) be?

I'm thinking that an arbitrary octet string would be appropriate; it can be distributed at the same time as the PPK data itself.

In addition, one thing that we do not want to interfer with extensions to this proposal; for example, the discussed extension that pulls the PPKs from a 1G one-time pad file.  I believe that concept could work here; in that case, the ID field would be just the PPK index (and both sides would understand that extension).

I don't believe that IKE currently makes any assumptions that notification data is a multiple of 4 bytes in length; is that correct?

Is there anything I missed?

> From: Scott Fluhrer (sfluhrer)
> Sent: Wednesday, April 05, 2017 3:30 PM
> To: 'Tero Kivinen'
> Cc: [email-masked]
> Ok, I now see what part of your idea I was (sort of) trying to work around.  To
> make it clear to everyone, I'll spell out the problem we're trying to address,
> and how your idea (with a slight addition on my part) could address it.
> 
> What we're talking about is "how would someone take a network that's using
> the standard IKE implementation, and convert it into a network that uses
> IKE+PPKs, and in a way that doesn't cause a flag day, or prevent negotiations
> from happening between nodes while the upgrade is in progress.
> 
> The idea is that the network admin goes through the nodes, and upgrades
> them in order; in step 0, the nodes are running standard IKE, and in the final
> step, they are running the full PPK protocol (and insist on using it).  For the
> upgrade to be bumpless, we require that any node at step i be able to
> communicate (as either initiator or responder) with a node at step i-1, i or i+1
> (assuming, of course, that our security policy allows those two nodes to
> communicate).
> 
> The issue I was pondering was "what if the admin wants to update only part
> of their network (say, as a test)?".  As I understood your proposal, the
> PPK_SUPPORT notify was always on if any PPKs were configured; indeed,
> from a responder side, it has to be that (because the responder has no other
> context to issue it or not).  However, from an initiator standpoint, it knows
> who the responder is (or, at least, it has to; it's the one that selects which
> PPK to use); hence, from the initiator standpoint, the PPK_SUPPORT notify
> could mean "I have a PPK that I would like to use with you, are you willing?"
> 
> With that proviso, then partial upgrades of the network can work; if an
> initiator (in the upgraded portion) talks to a responder in an nonupgraded
> section (or in an independently upgraded section), it just notes it doesn't
> have a PPK, and so doesn't send the notify (and similarly, if it was the initiator
> who wasn't upgraded, the responder performs the standard IKE protocol,
> and when the responder gets the identity, it can verify whether or not it
> would have expected the initiator to be upgraded).
> 
> 
> So, how does that sound?

---

From: "Valery Smyslov" <[email-masked]>
Date: Mon, 10 Apr 2017 18:15:54 +0300

Hi Scott,

> I've been putting together the updates, and one question came up: what format should the PPK_ID
field
> (sent be the initiator in the first encrypted message to identify the PPK it used) be?
> 
> I'm thinking that an arbitrary octet string would be appropriate; it can be distributed at the
same time as
> the PPK data itself.
>
> In addition, one thing that we do not want to interfer with extensions to this proposal; for
example, the
> discussed extension that pulls the PPKs from a 1G one-time pad file.  I believe that concept could
work
> here; in that case, the ID field would be just the PPK index (and both sides would understand that
> extension).

I think that it's worth to add an indication of the type of PPK_ID. I.e. the PPK_ID should consist
of 
two fields - PPK_ID type (16 bits, managed by IANA) and PPK_ID data. That would make PPK
management a bit easier - the responder would know where to look PPK for.

> I don't believe that IKE currently makes any assumptions that notification data is a multiple of 4
bytes in
> length; is that correct?

IKEv2 makes no such assumption - notification data can be of any length.

Regards,
Valery.

---

From: Paul Wouters <[email-masked]>
Date: Mon, 10 Apr 2017 12:54:05 -0400 (EDT)

On Mon, 10 Apr 2017, Valery Smyslov wrote:

> I think that it's worth to add an indication of the type of PPK_ID. I.e. the PPK_ID should consist of

Sounds good to me.

Paul

---

From: "Scott Fluhrer (sfluhrer)" <[email-masked]>
Date: Tue, 11 Apr 2017 14:47:47 +0000

Paul, on a previous email, you wrote:

> I wouldn't want to broadcast my type of PPK used in IKE_INIT or IKE_AUTH, as an active attacker could then learn this information.

I believe it was in this context; did you change your mind?

If everyone is OK with a PPK_ID type.  If everyone is, I'll put that into the draft...

> From: IPsec [mailto:[email-masked]] On Behalf Of Paul Wouters
> Sent: Monday, April 10, 2017 12:54 PM
> To: Valery Smyslov
> Cc: [email-masked] WG
> Subject: Re: [IPsec] Quantum Resistance SK_d, SK_pi, SK_pr etc mixing
> 
> > I think that it's worth to add an indication of the type of PPK_ID.
> > I.e. the PPK_ID should consist of two fields - PPK_ID type (16 bits,
> > managed by IANA) and PPK_ID data. That would make PPK management a
> bit easier - the responder would know where to look PPK for.
> 
> Sounds good to me.
> 
> Paul
>

---

From: Paul Wouters <[email-masked]>
Date: Tue, 11 Apr 2017 10:54:42 -0400

As long as there is an opaque type in the list of types, everyone can reveal as much as they are comfortable with.

Paul

Sent from my iPhone

> On Apr 11, 2017, at 10:47, Scott Fluhrer (sfluhrer) <[email-masked]> wrote:
>

---

From: "Scott Fluhrer (sfluhrer)" <[email-masked]>
Date: Wed, 12 Apr 2017 20:52:39 +0000

I've been pondering another question, and I think I'll bring it up before finalizing the next version of the draft.

After the WG meeting, we (Tero and myself) met in the hallway and had a little chat.  One of the things that I took away from it (and please correct me if I was wrong) was that you thought that it was important that the PPK itself was potentially equidistributed; for example, if it was 256 bits long, then all possible 256 bit values were representable; after all, we are handling it the PRF as a key.  On this basis, you suggested that the PPK be encoded in Base64 (and converted into binary by each endpoint).

Now, for the specific PRFs standardized in IKE, it's not actually that important that all bit patterns be possible.  Currently, the PRFs defined are HMAC of various hash functions, and XCBC/CMAC (which aren't quantum safe).  The HMAC PRFs do not actually need to make the assumption that the key is equidistributed; it is sufficient that there are at least 2**256 possible PPKs (which can be ensured by simply allowing the PPK to be long enough).

It would certainly be simpler to say "take the PPK as an ASCII string, and hand it off to the PRF as the key", and skip the Base64 conversion; we might want to suggest a limit on the alphabet of the PPK (as not all implementation like things with, say, spaces, in them), however that's not a serious suggestion.

On the other hand, it does rather assume that any future PRF will also work well with a non-evenly distributed key.

Thoughts?

---

From: Paul Wouters <[email-masked]>
Date: Wed, 12 Apr 2017 21:47:51 -0400 (EDT)

> It would certainly be simpler to say "take the PPK as an ASCII string, and hand it off to the PRF as the key", and skip the Base64 conversion; we might want to suggest a limit on the alphabet of th…

I would prefer not to add limitations to the byte stream. If someone is
using an actual quantum computer entangled source, that might require
additional post processing to convert it to a reduced ascii set.

For our implementation, we already use a prefix to denote the type of
encoding used for PSKs. And for OTP's in particular, I really do expect
to point to an actual raw binary file, so needing to convert that to
ascii would actually be making more work for us to implement.

It would also make referring to "the offset" a little weird. Is this
the number of converted-to-ascii bytes or the raw bytes offset?

Paul

---

From: "Scott Fluhrer (sfluhrer)" <[email-masked]>
Date: Thu, 13 Apr 2017 03:11:06 +0000

> From: Paul Wouters [mailto:[email-masked]]
> Sent: Wednesday, April 12, 2017 9:48 PM
> Cc: Tero Kivinen; [email-masked]
> > It would certainly be simpler to say "take the PPK as an ASCII string, and
> hand it off to the PRF as the key", and skip the Base64 conversion; we might
> want to suggest a limit on the alphabet of the PPK (as not all implementation
> like things with, say, spaces, in them), however that's not a serious
> suggestion.
> 
> I would prefer not to add limitations to the byte stream. If someone is using
> an actual quantum computer entangled source, that might require additional
> post processing to convert it to a reduced ascii set.

I wasn't nearly as clear as I ought to have been; I made some assumptions without stating them.

There are, of course, multiple possible PPK sources; one is a preconfigured fixed value in the device; another might be values from a CD-ROM (as others discussed elsethread); still another might be a quantum key distribution device.

My discussion was solely about the preconfigured fixed value, and I was just talking about the mapping between 'fixed value' and 'the PPK value you hand to the PRF'; this fixed value will likely be configured as a string (similar to a standard preshared key), my question was the mapping of this string to a PPK value.

Now, obviously, there will be other methods of generating PPKs; for those alternative methods, they will likely generate large (256 bit or so) uniform random value; there may be no particular reason to impose any nontrivial mapping there.  Obviously, talking about ASCII in that context may make no sense whatsoever.  I don't intend to talk about these alternative methods directly in the draft (except to provide a hook to add them later).

Does that clarify things?

> encoding used for PSKs. And for OTP's in particular, I really do expect to point
> to an actual raw binary file, so needing to convert that to ascii would actually
> be making more work for us to implement.
> 
> It would also make referring to "the offset" a little weird. Is this the number
> of converted-to-ascii bytes or the raw bytes offset?
> 
> Paul

---

From: Paul Wouters <[email-masked]>
Date: Wed, 12 Apr 2017 23:38:09 -0400 (EDT)

> My discussion was solely about the preconfigured fixed value, and I was just talking about the mapping between 'fixed value' and 'the PPK value you hand to the PRF'; this fixed value will likely be…

Right, and likely use the exact same code path as for PSK, so I think
the vendors will have will interop similarly with PSK as with PPK for
this use case. I really wouldn't want to have our PPK secrets to be
differently configured or interpreted from out PSK secrets with respect
to whether it ignores a space or not.

> Now, obviously, there will be other methods of generating PPKs; for those alternative methods, they will likely generate large (256 bit or so) uniform random value; there may be no particular reaso…

Right, but I think it is better to not give different formats/charsets
for PPKs. Maybe note/warn the implementer for dangerous characters, but
don't define a new set of valid chars for this one type of PPK.

Paul

ps. as for your "they will likely generate" argument, I fear that is
mostly wishful thinking. As was pointed out recently, this is the
stuff you find in "production quality VPN services":

https://support.onevpn.com/knowledgebase/configure-l2tp-protocol-windows-10/

which says:

 	 0- Select the radio box for “Use preshared key for authentication” and enter “123456789”

And those kind of things lead to these kind of statistics:

https://twitter.com/letoams/status/549654933608595457

---

From: "Valery Smyslov" <[email-masked]>
Date: Thu, 13 Apr 2017 10:18:55 +0300

Hi Scott,

> I've been pondering another question, and I think I'll bring it up before finalizing the next
version of the
> draft.
> 
> After the WG meeting, we (Tero and myself) met in the hallway and had a little chat.  One of the
things
> that I took away from it (and please correct me if I was wrong) was that you thought that it was
important
> that the PPK itself was potentially equidistributed; for example, if it was 256 bits long, then
all possible 256
> bit values were representable; after all, we are handling it the PRF as a key.  On this basis, you
suggested
> that the PPK be encoded in Base64 (and converted into binary by each endpoint).
> 
> Now, for the specific PRFs standardized in IKE, it's not actually that important that all bit
patterns be
> possible.  Currently, the PRFs defined are HMAC of various hash functions, and XCBC/CMAC (which
aren't
> quantum safe).  The HMAC PRFs do not actually need to make the assumption that the key is
> equidistributed; it is sufficient that there are at least 2**256 possible PPKs (which can be
ensured by
> simply allowing the PPK to be long enough).
> 
> It would certainly be simpler to say "take the PPK as an ASCII string, and hand it off to the PRF
as the key",
> and skip the Base64 conversion; we might want to suggest a limit on the alphabet of the PPK (as
not all
> implementation like things with, say, spaces, in them), however that's not a serious suggestion.
> 

I've been thinking that the protocol must not prescribe PPK format (as well as PSK format).
For the protocol it is a binary string. How it is represented in GUI and in which form it is
transferred
from peer to peer (base64, hex, even ASCII etc.) is not a protocol's matter. E.g. I can have a
hardware
tokens fabricated in pairs containing the same random PPK, that is never exported from the tokens.
The end user never see the PPK value. Distribution is made by physically handing over the tokens. 
All crypto operations with PPK are done inside token.  What base 64 we are talking about 
in this case? Where to apply it?

Regards,
Valery.

---

From: Tero Kivinen <[email-masked]>
Date: Thu, 13 Apr 2017 14:00:04 +0300

Scott Fluhrer (sfluhrer) writes:
> I've been pondering another question, and I think I'll bring it up
> before finalizing the next version of the draft. 
> 
> After the WG meeting, we (Tero and myself) met in the hallway and
> had a little chat.  One of the things that I took away from it (and
> please correct me if I was wrong) was that you thought that it was
> important that the PPK itself was potentially equidistributed; for
> example, if it was 256 bits long, then all possible 256 bit values
> were representable; after all, we are handling it the PRF as a key.
> On this basis, you suggested that the PPK be encoded in Base64 (and
> converted into binary by each endpoint). 

Actually I do not care if all possible 256-bit values can be used, but
care that whatever value I get from somewhere can be used... I.e., if
I have some external distribution method giving me those PPK values, I
want to make sure I can configure both ends to use those values.

> Now, for the specific PRFs standardized in IKE, it's not actually
> that important that all bit patterns be possible.  Currently, the
> PRFs defined are HMAC of various hash functions, and XCBC/CMAC
> (which aren't quantum safe).  The HMAC PRFs do not actually need to
> make the assumption that the key is equidistributed; it is
> sufficient that there are at least 2**256 possible PPKs (which can
> be ensured by simply allowing the PPK to be long enough).

Yes.

> It would certainly be simpler to say "take the PPK as an ASCII
> string, and hand it off to the PRF as the key", and skip the Base64
> conversion; we might want to suggest a limit on the alphabet of the
> PPK (as not all implementation like things with, say, spaces, in
> them), however that's not a serious suggestion. 

Lets say I have external method which generates me a quantum safe PPK
for both ends. Now, I want to make sure I can use that PPK in both
ends, and to make sure it can be used I want to make it sure that I
can configure whatever PPK I get from this external thing to be used
as PPK.

If we use ASCII string, then I need to take my binary blob PPK and
convert it to something that is representable in ascii (for example
hex or base64 encoding).

As my APIs etc will take PPK as binary opaque string with length,
there is no point of restricting myself to just ascii strings there.
It is less error prone to allow me to use the raw binary string than
for example hex conversion of the binary string. For example with hex
strings the result will be different depending whether I use uppercase
or lower case letters. With base64 the result will be different if I
make base64 string without any whitespace, or if I split base64 string
to 72 character long lines.

So for reading the PPK for config file and then converting it to
binary will make this kind of issues disappear, and when the config
file reads base64 string (or hex string) in, and then convert it to
binary object it does not matter whether there is whitespaces etc in
string.

It also make it so that we do not need to care about the character
sets. If we say PPK is string, then we need to know whether it is
ASCII, iso-latin-1, iso-latin-15, utf-8 or whatever. 

> On the other hand, it does rather assume that any future PRF will
> also work well with a non-evenly distributed key.

I do not really care whether the PRF works with non-evenly distributed
key, I care that when I configure the same PPK in both ends, I can be
sure the binary object feed to the PRF will be same.

If I configure PPK to be string

	Erittäinen salainen merkkijono

to my system, the binary representation of that will be different
depending whether my editor saved it as UTF-8 or Latin-1... If I
configure my sytem to use base64 string of

	RXJpdHTkaW5lbiBzYWxhaW5lbiBtZXJra2lqb25vCg==

then both ends will convert it to binary object in same way, and it
does not really matter whether the original string was in UTF-8 or
latin-1 (In this case I think my system used latin-1 for it).
-- 
[email-masked]