Subject: [nfsv4] Last call start for "RPCSEC_GSS Version 2"

From: Spencer Shepler <[email-masked]>
Date: Mon, 02 Jun 2008 23:30:43 -0500

As Mike has indicated upon publishing of the following I-D:

http://www.ietf.org/internet-drafts/draft-ietf-nfsv4-rpcsec-gss- 
v2-03.txt

We are ready to do a working group last call for the document.

Please take the time to review the I-D and send comments to the
working group alias.

The last call will start now and run through end of day June 18th.

Thanks in advance for your efforts.

Spencer

_______________________________________________
nfsv4 mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/nfsv4

---

From: "Mike Eisler" <[email-masked]>
Date: Wed, 4 Jun 2008 10:04:24 -0700 (PDT)

For the uninitiated, this document adds support for channel bindings
to RPCSEC_GSS, in order to leverage the use of encrypted channels like
IPsec. The theory is that devices like TCP Offload Engines (TOE) have,
or will have, IPsec that is hardware-accelerated and runs much faster than
host-based software stacks of IPsec or a software data path of
RPCSEC_GSS/GSS-API/{GSS_Wrap/GSS_GetMIC.

What happens is that RPCSEC_GSSv2 sends a new request using an RPCSEC_GSS
handle in an established state. This new request contains the output
of GSS_GetMIC() on the some bits of information (channel bindings) specific
to the secure channel. For IPsec, the channel bundings will be a
one-way hash of the public keys. If the bindings are verified by
the client and server, then thereafter, the RPCSEC_GSS client and
server do not need to make GSS_GetMIC() computations on the
header or the arguments/results; double crypto is thus avoided when
IPsec (or for that matter, an SSH tunnel) is in the picture.

If this sounds familiar, it is. A few years back I wrote a I-D
called "CCM", which accomplished the same thing, but via a new
GSS-API mechanism. Several of us have concluded the mechanism approach
adds too much complexity, the proposed approach is the simplest for
people in the NFS developer community.

I believe that RPCSEC_GSSv2 is an IESG requirement to publish all the
NFS/RDMA documents as RFCs, so if you care about RDMA, you might
want to read the RPCSEC_GSSv2 I-D.

Thanks for reading.

-- 
Mike Eisler, Senior Technical Director, NetApp, 719 599 9026,
http://blogs.netapp.com/eislers_nfs_blog/

---

From: Nicolas Williams <[email-masked]>
Date: Wed, 11 Jun 2008 18:16:08 -0500

On Mon, Jun 02, 2008 at 11:30:43PM -0500, Spencer Shepler wrote:
> http://www.ietf.org/internet-drafts/draft-ietf-nfsv4-rpcsec-gss-v2-03.txt

Comments:

 - Section 1

    - Please add a reference to RFC5056 immediately following the first
      use of "channel binding" or "channel bindings."

      Also, add references to RFC2203, RFC1831...

    - It might be useful to explain that "channel" here refers to such
      things as the transports used by ONC RPC applications.

 - Please move the last paragraph of section 2 to section 1 as the third
   paragraph and re-write like so:

   "
   RPCSEC_GSSv2 simply adds an optional round trip that has the
   initiator compute a GSS MIC on the shared channel's channel binding
   data, and sends the MIC to the target.  The target verifies the MIC,
   and, if verification succeeds, in turn sends its own MIC of the
   channel's channel binding data to the initiator which verifies the
   target's MIC.  This accomplishes two things.  First the initiator
   and target are mutually authenticated as usual through RPCSEC_GSS.
   Second, the initiator and target prove they know the shared channel's
   channel bindings, and thus are using the same channel without
   possibility of a man-in-the-middle (MITM).
   "

   Moving this is necessary to provide background for the second
   paragraph of section 2.

 - Section 2

    - Please add a note as to section 2 that the description of channel
      binding given is informative, that the normative description is in
      RFC5056.

    - s/^2.  Channel Bindings Explained/2.  Channel Binding Explained/

      This explains the process of channel binding, not just what
      channel bindings are.

    - /^If a channel between/s/secure,/secure end-to-end, then/

    - Remove the second and thrid sentences of paragraph 1 and replace
      with: "This shared information can be used to construct "channel
      bindings" -- data which can be used in the channel binding process
      to show that there is (or isn't) an unauthorized MITM in the
      secure channel."

    - s/The MITM cannot simply[^.]*\./The MITM cannot cause the two
      channels to have the same source and destination public keys
      without also possessing the corresponding private keys (implying
      either that it is an authorized MITM or that the public key
      cryptosystem in question has been broken for the key sizes used)
      or without otherwise compromising the security of the channel's
      key exchange and authentication protocols./

    - Note that the last two sentences of the 2nd paragraph of section 2
      refer to protocol information not presented until the last
      paragraph of section 2.  See note above about moving that
      paragraph up.

    - 3rd paragraph, s/exploit/use/

      Actually, the key thing is that the app can use the secure channel
      without adding further cryptographic protection of application
      data at the application layer.

    - /^   o/s/shared information/channel bindings/

 - Section 3.2

   What does "rgc" in "rgc_version" stand for?

 - Section 3.3

    - Please explain what all the varions prefixes stand for (e.g.,
      "rbcva").

    - rbcva_chan_bind_hash_oid, should we actually need it (see below)
      should be described as containing the DER encoding of an OID.

    - But I don't think we need to hash the channel bindings at all
      because: a) gss_get/verify_mic() can handle large amounts of input
      data anyways, thus no need to hash it down, b) using a hash adds
      complexity (including hash agility considerations), c) channel
      bindings will typically be hashed data to begin with[*].
      
      [*] I've decided that IPsec channel bindings will be
	  H(H(initiator's pubkey) XOR H(responder's pubkey)) and that
	  the IPsec channel binding prefixes will contain the hash
	  function name, e.g., "IPsec-end-point-sha-256", and this for
	  the same reasons you give.

	  In fact, draft-williams-ipsec-channel-binding-01.txt has been
	  updated accordingly and submitted on April 21.

	  I believe this is non-controversial (Sam agreed when I
	  described this to him).

More later.

Nico

---

From: Nicolas Williams <[email-masked]>
Date: Wed, 11 Jun 2008 18:28:17 -0500

> > http://www.ietf.org/internet-drafts/draft-ietf-nfsv4-rpcsec-gss-v2-03.txt

 - Section 4

   So the handle namespaces for v1 and v2 are distinct, correct?

 - Section 7

   Well, the security considerations that apply are:

    - those in RFC2203
    - those in RFC5056
    - those of the secure channel being used

 - Section 9.2

    - Please add references to:

       - draft-ietf-btns-connection-latching-07.txt (just passed WGLC, BTW)
       - draft-williams-ipsec-channel-binding-01.txt

I still have to finish reviewing section 3.2.

Nico

---

From: Nicolas Williams <[email-masked]>
Date: Fri, 13 Jun 2008 14:00:50 -0500

> http://www.ietf.org/internet-drafts/draft-ietf-nfsv4-rpcsec-gss-v2-03.txt

There's a rather minor, but easy to fix attack on RPCSEC_GSSv2 as
described in -03.

I started wondering what kind of games an attacker could play with the
RPCSEC_GSS version number.  I think an MITM could modify RPCs from a v1
client, talking to a v2 server, to set the RPCSEC_GSS version to 2, and
in the process obtain a few MICs that it might, by sheer luck, cause the
server to accept in the channel binding portion of the protocol.

Now, the RPCSEC_GSS version number is bound into the v1 verifier, IIRC,
so the client's RPCs should all fail, leading the client to give up soon
enough.  Which means the attacker would get rather few MICs to play
with, making its chances of success very, very small.

Can you confirm my thinking here?

We might choose to live with this attack.  I'd rather fix the protocol
so this attack is not possible.

One fix that I see is to use the GSS-API channel binding facility to
bind the v2 version number into the RPCSEC_GSSv2 context handle setup.

We still need the RPCSEC_GSS_BIND_CHANNEL gss_proc though, because of
the way MIT krb5 and MIT-derived implementations of RFC1964/4121 handle
channel binding on the acceptor side.  And to do the hash negotiation
(if we choose to keep it; I'll address that in a separate post
momentarily).

Another possible fix would be to require that v2 clients always use the
RPCSEC_GSS_BIND_CHANNEL gss_proc immediately after establishing a
context handle, and limiting attempts to cal RPCSEC_GSS_BIND_CHANNEL to
just one.  This gives the MITM just one MIC to attempt this attack
per-client attempt to establish a v1 handle -- not perfect, but maybe
livable.

Nico

---

From: "Mike Eisler" <[email-masked]>
Date: Fri, 13 Jun 2008 13:21:48 -0700 (PDT)

>       bindings will typically be hashed data to begin with[*].

OK, I'm very confused.

You wrote on April 21:

``The primary change here is this: rather than use the raw public keys I
want to use a hash of them.  The main reason is: so keeping channel
binding data in kernel mode implementations is not too difficult (by
reducing the size of the data to keep around).  Hash agility is pushed
to the application, which will require a change to RPCSEC_GSSv2 (which
is still an I-D and has not progressed yet).''

The current RPCSEC_GSSv2 i-d is consistent with what you wrote on April
21. But you didn't say how you wanted the  RPCSEC_GSSv2 changed. So
in absence of guidance, this is what you get.

As for "typically be hashed data" that's not good enough. RPCSEC_GSS
creds and verifiers are limited to 400 bytes. Public keys can easily
exceed 400 bytes.

So your original instincts from April 21 seem correct.

---

From: "Mike Eisler" <[email-masked]>
Date: Fri, 13 Jun 2008 13:35:46 -0700 (PDT)

> server to accept in the channel binding portion of the protocol.

I'm not seeing it. The MIC in the verifier of both v1 and v2
of RPCSEC_GSS is compute from the RPC header "up to and including
      the credential"

Since the credential contains the RPCSEC_GSS version number (field
rgc_version below) the RPCSEC_GSS target will reject the MITM's
modified RPCs.

      union rpc_gss_cred_t switch (unsigned int rgc_version) {
        case RPCSEC_GSS_VERS_1:
        case RPCSEC_GSS_VERS_2: /* new */
          rpc_gss_cred_vers_1_t rgc_cred_v1;
      };

---

From: Nicolas Williams <[email-masked]>
Date: Fri, 13 Jun 2008 15:41:53 -0500

> ``The primary change here is this: rather than use the raw public keys I

The change was to draft-williams-ipsec-channel-binding to make use of a
hash *there* rather than in RPCSEC_GSSv2.

> is still an I-D and has not progressed yet).''

What I meant by pushing hash agility to the application is that it's the
IPsec implementation's job to implement one or more hashes, and the
app's job to pick one.

The change to RPCSEC_GSSv2 is to remove the need for a hash there.  (But
see below.)

> creds and verifiers are limited to 400 bytes. Public keys can easily

We don't send the channel bindings though.  Just a MIC, so the 400 byte
issue is a non-issue.

The main reason to worry about channel bindings size is that you have to
keep track of them in kernel-land, which can be a pain.

There's no guarantee, as you point out, that all channel bindings sepcs
will be "small", so I realized last night that we may still want to keep
the hash thing, at least as an option.

If we want it to be an option, then we could say that the empty OID
(zero-length octet string) means "identity function" and that the client
MUST pick a hash only if the channel bindings are larger than the output
size of any of the hash functions available and acceptable to the
client.

If you don't want it to be an option then I don't object, and I retract
my comment about removing the feature.

Nico

---

From: "Mike Eisler" <[email-masked]>
Date: Fri, 13 Jun 2008 16:54:42 -0700 (PDT)

> my comment about removing the feature.

Cool. We will leave it as is then.

---

From: Nicolas Williams <[email-masked]>
Date: Fri, 13 Jun 2008 19:26:27 -0500

> of RPCSEC_GSS is compute from the RPC header "up to and including

The version number in the context token exchange messages is not
protected.

So:

 - a v1 client
 - an MITM
 - a v1 and v2 server

 - the MITM intercepts the client's v1 context token messages and
   changes the version number to 2 before forwarding to the server, and
   changes the version number back to 1 in the replies from the server

    - neither the client nor the server notice

 - eventually the context is established and the client sends its first
   RPC protected by the established handle

    - this RPC is bound to fail since the verifier MIC'ed data includes
      the credential, which includes the RPCSEC_GSS version number

    - but the MITM is an optimist, and so the MITM formats an
      RPCSEC_GSS_BIND_CHANNEL RPC using the verifier from the client's
      RPC, and then forwards this to the server in the hopes that
      there's a collision

       - most likely the MITM's RPC fails, so the MITM send back garbage
	 to the client and hopes the client will try again

       - lather, rinse, repeat until collision happens, at which point
	 the MITM closes the connection to the client and then proceeds
	 to impersonate the client to the server, since at this point
	 the handle is bound to the MITM's channel with the server.

The client sees lots of failures, perhaps, from its p.o.v., due to
network problems.

The server sees lots of failures too.  But finnally a success.

> rgc_version below) the RPCSEC_GSS target will reject the MITM's

The version number in the context token exchange is the one that must be
protected.

Nico

---

From: "Mike Eisler" <[email-masked]>
Date: Sun, 15 Jun 2008 08:24:58 -0700 (PDT)

> 	 the handle is bound to the MITM's channel with the server.

The MIC is 128 bits or more right? Isn't this is a 1 in 2^128
chance of collision? It seems to me that any solution one designs
is going to prone to this.

We could require that RPCSEC_GSS_BIND_CHANNEL send GSS_Wrap()'ed content
in the credential of the request, and the verifier of the response. Since
the credential is somewhat larger than 128 bits, this makes it more
difficult for the MITM to forge a RPCSEC_GSS_BIND_CHANNEL that contains
mostly ciphertext.

---

From: Spencer Shepler <[email-masked]>
Date: Mon, 16 Jun 2008 18:28:06 -0500

Remember the last call completes end of day June 18th.

Spencer