Subject: [nfsv4] ssv key size issue

From: Olga Kornievskaia <[email-masked]>
Date: Fri, 12 Dec 2008 13:48:41 -0500

There seems to be a problem with the spec's statement (page 494 in 
section18.33.3) and in general with having enough bits for encryption 
keys given a chosen integrity algorithm:

"The length of SSV MUST be equal to the length of the key used by the negotiated encryption algorithm."

Integrity and encryption subkeys are derived from the SSV value using 
HMAC. The output size of the HMAC is determined by the underlying hash 
mechanism (sha1, sha256, etc...). For hmac-sha1 it is 20bytes which is 
enough for 128bit AES but not for 192 and 256bit version. Spec lists 
sha1, sha224, sha256, sha384, and sha256 for integrity and aes-128, 
aes-192, and aes-256. To have enough bits for the encryption keys it 
seems that we shouldn't even be support first 2 integrity algorithm choices.

Having SSV be equal in length to encryption key is an issue for having 
enough key material for generating subkeys for integrity. While HMAC rfc 
allows for input keys to be of smaller size than the hash function's 
output, it is strongly discouraged. So say we picked aes-128, than 
128bit key is insufficient to satisfy ANY integrity algorithms. 192 is 
enough for sha1. aes-256 will cover sha1, sha224, and sha256, leaving 
out sha284 from ever being used!

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

---

From: "Mike Eisler" <[email-masked]>
Date: Fri, 12 Dec 2008 12:37:52 -0800 (PST)

On Fri, December 12, 2008 10:48 am, Olga Kornievskaia wrote:

Olga,

Thanks for looking at this.

> negotiated encryption algorithm."

I agree that this statement is not accurate given the subkey derivation.
Instead, we should say:

   The length of key used by the negotiated
   encryption algorithm MUST NOT exceed the
   length of the output of negotiated hash algorithm.

   The calculation uses the HMAC [11] algorithm, using the
   current SSV as the key, the one way hash algorithm
   as negotiated by EXCHANGE_ID, and the input text
   as represented by the XDR encoded enumeration value
   for that subkey of data type ssv_subkey4. If the output of the
   HMAC exceeds the length (N) required for the encryption algorithm,
   then the subkey will be set to the first N bytes of the output of
   the HMAC.

Truncating HMACs seems to be a common practice; the HMAC RFC gives
some guidelines, and I'll update the spec to incorporate those guidelines.

> output, it is strongly discouraged. So say we picked aes-128, than

I agree it makes sense that the length of the SSV
SHOULD NOT be less than the length of the key of the negotiated
encryption algorithm. I don't see the issue if the input key to
HMAC is less than the output of the HMAC. The HMAC RFC says:

   However, less than L bytes is strongly
   discouraged as it would decrease the security strength of the
   function

but doesn't explain why. If a hash length that exceeds the key
length produces HMACs that make it easier to guess the key or forge
HMACs that would be a problem. Given that HMACs with md5 and single des
have been around for a long time, it is hard to believe.
http://tools.ietf.org/html/rfc3962 was published after the HMAC RFC
and specifies 128 bit AES with SHA-1 (160 bits) as the hash algorithm.

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

---

From: "Mike Eisler" <[email-masked]>
Date: Sat, 13 Dec 2008 10:19:10 -0800 (PST)

Attached is proposed text to address the issues Olga found.

Index: nfsv41_middle_core_infrastructure.xml
===================================================================
RCS file: /cvs/stdk/NFSv41/nfsv41_middle_core_infrastructure.xml,v
retrieving revision 1.107
diff -c -r1.107 nfsv41_middle_core_infrastructure.xml
*** nfsv41_middle_core_infrastructure.xml	13 Dec 2008 05:17:50 -0000	1.108
--- nfsv41_middle_core_infrastructure.xml	13 Dec 2008 18:16:46 -0000
***************
*** 3530,3535 ****
--- 3530,3543 ----
     way hash algorithm as negotiated by EXCHANGE_ID,
     and the input text as represented by the XDR encoded
     enumeration value for that subkey of data type ssv_subkey4.
+    If the length of the output of the HMAC algorithm exceeds the length of
+    key of encryption algorithm (which is also negotiated by EXCHANGE_ID),
+    then the subkey MUST be truncated from the HMAC output, i.e. if the
+    subkey is of N bytes long, then the first N bytes of the HMAC output
+    MUST be used for the subkey. The specification of EXCHANGE_ID
+    states that the length of the output of the HMAC algorithm MUST NOT
+    be less than length of subkey needed for the encryption algorithm
+    (see <xref target="OP_EXCHANGE_ID"/>).
    </t>
    <?rfc include="autogen/type_ssv_subkey4.xml"?>
    <t>
*** nfsv41_middle_core_infrastructure.xml	5 Dec 2008 05:58:04 -0000	1.107
--- nfsv41_middle_core_infrastructure.xml	13 Dec 2008 05:16:56 -0000
***************
*** 3538,3544 ****
     that originate from the NFSv4.1 client, whether as part
     of a request over the fore channel, or a response
     over the backchannel. The subkey derived from
!    SSV4_SUBKEY-MIST2I is used for MICs originating from the
     NFSv4.1 server. The subkey derived from SSV4_SUBKEY_SEAL_I2T
     is used for encryption text originating from the NFSv4.1
     client and the subkey derived from SSV4_SUBKEY_SEAL_T2I
--- 3538,3544 ----
     that originate from the NFSv4.1 client, whether as part
     of a request over the fore channel, or a response
     over the backchannel. The subkey derived from
!    SSV4_SUBKEY_MIC_T2I is used for MICs originating from the
     NFSv4.1 server. The subkey derived from SSV4_SUBKEY_SEAL_I2T
     is used for encryption text originating from the NFSv4.1
     client and the subkey derived from SSV4_SUBKEY_SEAL_T2I
***************
*** 3575,3581 ****
     1 after SET_SSV (<xref target="OP_SET_SSV" />)
     is called the first time on a client
     ID.
!    Thereafter, it is incremented on each SET_SSV.
     Thus smt_ssv_seq represents the version of the SSV at
     the time GSS_GetMIC() was called.  As noted in <xref
     target="OP_EXCHANGE_ID" />, the client and server
--- 3575,3581 ----
     1 after SET_SSV (<xref target="OP_SET_SSV" />)
     is called the first time on a client
     ID.
!    Thereafter, the SSV sequence number is incremented on each SET_SSV.
     Thus smt_ssv_seq represents the version of the SSV at
     the time GSS_GetMIC() was called.  As noted in <xref
     target="OP_EXCHANGE_ID" />, the client and server
Index: nfsv41_middle_op_exchange_id.xml
===================================================================
RCS file: /cvs/stdk/NFSv41/nfsv41_middle_op_exchange_id.xml,v
retrieving revision 1.39
diff -c -r1.39 nfsv41_middle_op_exchange_id.xml
*** nfsv41_middle_op_exchange_id.xml	12 Dec 2008 06:52:57 -0000	1.39
--- nfsv41_middle_op_exchange_id.xml	13 Dec 2008 05:16:56 -0000
***************
*** 165,173 ****
         this property cannot be updated by 
         subsequent EXCHANGE_ID requests.
  
!        The length of SSV MUST be equal to the length of the
!        key used by the negotiated encryption algorithm.
  
        </t>
  
        <t>
--- 165,205 ----
         this property cannot be updated by 
         subsequent EXCHANGE_ID requests.
  
! 	 <vspace blankLines='1' />
  
+        There are REQUIRED and RECOMMENDED relationships between the
+        length of the key of the encryption algorithm ("key length"), the length of the
+        output of hash algorithm ("hash length"), and the length of the SSV ("SSV length").
+        <list style="symbols">
+        <t>
+         key length MUST be &lt;= hash length. This is because the keys used for
+         the encryption algorithm are actually subkeys derived from the SSV,
+         and the derivation is via the hash algorithm. The selection of an
+         encryption algorithm with a key length that exceeded the length of
+         the output of the hash algorithm would require padding, and thus
+         weaken the use of the encryption algorithm.
+        </t>
+        <t>
+         hash length SHOULD be &lt;= SSV length. This is because the
+         SSV is a key used to derive subkeys via an HMAC, and
+         it is recommended that the key used as input to an HMAC be
+         at least as long as the length of the HMAC's hash algorithm's
+         output (see Section 3 of <xref target="RFC2104">RFC2104</xref>).
+        </t>
+ 
+        <t>
+         key length SHOULD be &lt;= SSV length. This is a transitive result of the
+         above two invariants.
+        </t>
+ 
+        <t>
+         key length SHOULD be >= hash length / 2. This is because the subkey
+         derivation is via 
+         an HMAC and it is recommended that if the HMAC has to be truncated,
+         it should not be truncated to less than half the hash length
+         (see Section 4 of <xref target="RFC2104">RFC2104</xref>).
+        </t>
+        </list>
        </t>
  
        <t>
***************
*** 549,554 ****
--- 581,594 ----
         it returns NFS4ERR_ENCR_ALG_UNSUPP.
  
         If ssp_encr_algs is empty, the server MUST return NFS4ERR_INVAL.
+ 
+        Note that due to previously stated requirements and recommendations
+        on the relationships between key length and hash length, that some
+        combinations of RECOMMENDED and REQUIRED encryption algorithm and
+        hash algorithm either SHOULD NOT or MUST NOT be used as explained.
+        <xref target="algtbl"/> summarizes the illegal and discouraged
+        combinations.
+ 
       </t>
       <t hangText="ssp_window:" />
       <t>
***************
*** 602,607 ****
--- 642,655 ----
       </list>
       
      </t>
+       <texttable anchor='algtbl'>
+ 	      <ttcol align='left'>Encryption Algorithm</ttcol>
+ 	      <ttcol align='left'>MUST NOT be combined with</ttcol>
+ 	      <ttcol align='left'>SHOULD NOT be combined with</ttcol>
+ 	      <c>id-aes128-CBC</c> <c></c> <c>id-sha384, id-sha512</c>
+ 	      <c>id-aes192-CBC</c> <c>id-sha1</c> <c>id-sha512</c>
+ 	      <c>id-aes256-CBC</c> <c>id-sha1, id-sha224</c> <c></c>
+       </texttable>
  
      <t>
        The arguments include an array of up to one