[AFS3-std] rxgk specification

Simon Wilkinson simon@sxw.org.uk
Fri, 18 Sep 2009 18:37:07 +0100


--Apple-Mail-15-110320617
Content-Type: text/plain;
	charset=US-ASCII;
	format=flowed;
	delsp=yes
Content-Transfer-Encoding: 7bit

I've been in the process of piecing together a formal specification  
for the rxgk security class, based on notes from previous discussions,  
and on Love's partial implementation in Heimdal.

I now think I've got a document that pretty much represents the  
intended state of this class, and I'd like to open it up for  
standardisation discussion (those of us in Edinburgh will be  
discussing it next week, too).

Cheers,

Simon.


--Apple-Mail-15-110320617
Content-Disposition: attachment;
	filename=rxgk.txt
Content-Type: text/plain;
	x-unix-mode=0644;
	name="rxgk.txt"
Content-Transfer-Encoding: quoted-printable




AFS                                                            Wilkinson
                                                                     YFS
                                                      September 18, 2009


                rxgk: GSSAPI based security class for RX

Abstract

   rxgk is a security class for the RX RPC protocol.  It uses the GSSAPI
   framework to provide authentication, confidentiality and integrity
   protection.

   This document provides a general description of rxgk.  A further
   document will provide details of integration with specific RX
   applications



































Wilkinson                                                       [Page 1]
=0C
                rxgk: GSSAPI based security class for RX  September 2009


Table of Contents

   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  3
   2.  Encryption framework . . . . . . . . . . . . . . . . . . . . .  3
     2.1.  Key usage values . . . . . . . . . . . . . . . . . . . . .  3
   3.  Security Levels  . . . . . . . . . . . . . . . . . . . . . . .  4
   4.  Token Format . . . . . . . . . . . . . . . . . . . . . . . . .  4
   5.  Key negotiation  . . . . . . . . . . . . . . . . . . . . . . .  5
   6.  The combine tokens operation . . . . . . . . . . . . . . . . .  8
     6.1.  Overview . . . . . . . . . . . . . . . . . . . . . . . . .  8
     6.2.  Key combination algorithm  . . . . . . . . . . . . . . . .  8
     6.3.  RPC definition . . . . . . . . . . . . . . . . . . . . . .  8
     6.4.  Server operation . . . . . . . . . . . . . . . . . . . . .  9
     6.5.  Client operation . . . . . . . . . . . . . . . . . . . . .  9
   7.  The rxgk security class  . . . . . . . . . . . . . . . . . . .  9
     7.1.  Overview . . . . . . . . . . . . . . . . . . . . . . . . .  9
     7.2.  Key derivation . . . . . . . . . . . . . . . . . . . . . . 10
     7.3.  The Challenge  . . . . . . . . . . . . . . . . . . . . . . 10
     7.4.  The Response . . . . . . . . . . . . . . . . . . . . . . . 10
       7.4.1.  The Authenticator  . . . . . . . . . . . . . . . . . . 11
     7.5.  Checking the Reponse . . . . . . . . . . . . . . . . . . . 11
     7.6.  Packet handling  . . . . . . . . . . . . . . . . . . . . . 11
       7.6.1.  Encryption . . . . . . . . . . . . . . . . . . . . . . 11
       7.6.2.  Integrity protection . . . . . . . . . . . . . . . . . 12
       7.6.3.  Authentication only  . . . . . . . . . . . . . . . . . 12
   8.  Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 13
   9.  Notes  . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
   Author's Address . . . . . . . . . . . . . . . . . . . . . . . . . 14























Wilkinson                                                       [Page 2]
=0C
                rxgk: GSSAPI based security class for RX  September 2009


1.  Introduction

   rxgk is a GSSAPI based security class for the rx protocol.  It
   provides authentication, confidentiality and integrity protection for
   rx RPC calls, using a security context established using any GSSAPI
   mechanism with PRF support.

   Architecturally, rxgk is split into two parts.  The rxgk rx security
   class provides strong encryption using previously negotiated ciphers
   and keys.  It builds on the Kerberos crypto framework for its
   encryption requirements, but is authentication mechanism independent
   - the class itself does not require the use of either Kerberos, or
   GSSAPI.  The security class simply uses a previously negotiated
   encryption type, and master key.  The master key is never directly
   used, but instead a per connection key is derived for each new secure
   connection that is established.

   The second portion of rxgk is a service which permits the negotiation
   of an encryption algorithm, and the establishment of a master key.
   This is done via a separate RPC exchange with a server, prior to the
   setup of any rxgk connections.  The exchange establishes an rxgk
   token, and a master key shared between client and server.  This
   exchange is protected within a GSSAPI security context.


2.  Encryption framework

   Bulk data encryption within rxgk is performed using the encryption
   framework defined by RFC3961.  Any algorithm which is defined using
   this framework and supported by both client and server may be used.

2.1.  Key usage values

   In order to avoid using the same key for multiple tasks, key
   derivation is employed.  The following key usage values are used by
   rxgk, their functions are as defined later in this document.

   const RXGK_CLIENT_ENC_PACKET            =3D 1026;
   const RXGK_CLIENT_MIC_PACKET            =3D 1027;
   const RXGK_SERVER_ENC_PACKET            =3D 1028;
   const RXGK_SERVER_MIC_PACKET            =3D 1029;
   const RXGK_CLIENT_ENC_RESPONSE          =3D 1030;
   const RXGK_CLIENT_COMBINE_ORIG          =3D 1032;
   const RXGK_SERVER_COMBINE_NEW           =3D 1034;
   const RXGK_SERVER_ENC_TICKET            =3D 1036;






Wilkinson                                                       [Page 3]
=0C
                rxgk: GSSAPI based security class for RX  September 2009


3.  Security Levels

   rxgk supports the negotiation of a range of different security
   levels.  These, along with the protocol constant that represents them
   during key negotiation, are:
   Authentication only  (0) Provides only connection authentication,
         without either integrity or confidentiality protection.  This
         mode of operation provides higher throughput, but is vulnerable
         to man in the middle attacks.
   Integrity  (1) Provides integrity protection only.  Data is protected
         from modification by an attacker, but not against eavesdropping
   Bind  (2) Connection security is provided by channel bindings with
         another layer.  This mode of operation is experimental, and
         this value is reserved for future expansion.
   Encryption  (3) Provides both integrity and confidentiality
         protection.


4.  Token Format

   An rxgk token is an XDR encoded version of the following structure.
   Tokens are encrypted with a private key known only to one (or more)
   of the servers the client is communicating with, using key usage
   RXGK_SERVER_ENC_TICKET, and are presented to the client as an opaque
   blob.

     struct RXGK_Token {
       afs_int32 version;
       afs_int32 enctype;
       opaque    K0<>;
       afs_int32 level;
       afs_int64 starttime;
       afs_int32 lifetime;
       afs_int32 bytelife;
       afs_int64 expirationtime;
       struct RXGK_Identity identities<>;
       struct RXGK_Extension extensions<>;
     }

     struct RXGK_Identity {
       afs_uint32 auth_type;
       opaque name<>;
     }

     struct RXGK_Extension {
       afs_uint32 id;
       opaque data<>;
     };



Wilkinson                                                       [Page 4]
=0C
                rxgk: GSSAPI based security class for RX  September 2009


5.  Key negotiation

   rxgk uses an independent RX RPC service for key negotiation.  The
   location of this service is application dependent.  Within a given
   application protocol, a client must be able to locate the key
   negotiation service, and that service must be able to create tokens
   which can be read by the application server.  The simplest deployment
   has the service running on every server, on the same transport
   endpoints, but using a separate, dedicated, rx service id.

   The key negotiation RPC is defined by the following RPCL

   typedef afs_int32 RXGK_Enctypes<>;

   struct RXGK_StartParams {
       RXGK_Enctypes enctypes;
       afs_int32 levels<>;
       afs_int32 lifetime;
       afs_int32 bytelife;
       afs_int32 nametag;
       opaque client_nonce<>;
   };

   struct RXGK_ClientInfo {
       afs_int32 errorcode;
       afs_int32 flags;
       afs_int32 enctype;
       afs_int32 level;
       afs_int32 lifetime;
       afs_int32 bytelife;
       afs_int64 expiration;
       opaque mic<>;
       RXGK_Ticket_Crypt ticket;
       opaque server_nonce<>;
   };

   package RXGK_

   GSSNegotiate(IN RXGK_StartParams *client_start,
                IN RXGK_Token *input_token_buffer,
                IN RXGK_Token *opaque_in,
                OUT RXGK_Token *output_token_buffer,
                OUT RXGK_Token *opaque_out,
                OUT afs_uint32 *gss_status,
                OUT RXGK_Token *rxgk_info) =3D 1;


   The client populates RXGK_StartParams with lists of its prefered



Wilkinson                                                       [Page 5]
=0C
                rxgk: GSSAPI based security class for RX  September 2009


   options.  These should be ordered from best to worst, with the
   clients favoured option occuring first within the list.  The
   parameters are:
   enctypes:  List of encryption types from the Kerberos Encryption Type
         Number registry created in RFC3961 and maintained by IANA.
         This list indicates the encryption types that the client is
         prepared to support.
   levels:  List of supported rxgk transport encryption levels.
   lifetime:  The maximum lifetime of the negotiated key, in seconds.
   bytelife:  The maximum amount of data that the negotiated key should
         encrypt before being discared, expressed as log 2 of the number
         of bytes.  A value of 0 indicates that there is no limit on the
         number of bytes that may be transmitted.  The byte lifetime is
         advisory - a connection that is over its byte lifetime should
         be permitted to continue, but clients should attempt to
         establish a new context at their earliest convenience.
   clientnonce:  A client generated string of random bytes, to be used
         as input to the key generation.

   The client then calls gss_init_sec_context() to obtain an output
   token to send to the server.  The GSS service name is application
   dependent.

   The client then calls RXGK_GSSNegotiate, as defined above.  This
   takes the following parameters
   clientparms  The client params structure detailed above.  This should
         remain constant across the negotiation
   input_token_buffer  The token produced by a call to
         gss_init_sec_context
   opaque_in  An opaque token, which was returned by the server
         following a previous call to GSSNegotiate in this negotiation.
         If this is the first call, this should be NULL.
   output_token_buffer  The token output by the server's call to
         gss_accept_sec_context
   opaque_out  An opaque token, which the server may use to preserve
         state information between multiple calls in the same context
         negotiate.  The client should use this value as opaque_in in
         its next call to GSSNegotiate.
   gss_status  The major status code output by the server's call to
         gss_accept_sec_context
   rxgk_info  If gss_status =3D=3D GSS_S_COMPLETE this contains an =
encrypted
         block containing the server's response to the client.  See
         below.

   Upon receiving the server's response, the client checks the contents
   of gss_status.  If this is GSS_S_CONTINUE_NEEDED, the client should
   call gss_init_sec_context again with the token provided by the server
   in output_token_buffer, followed by a further call to GSSNegotiate,



Wilkinson                                                       [Page 6]
=0C
                rxgk: GSSAPI based security class for RX  September 2009


   including the server's previous opaque_out as this call's opaque_in

   This process continues until the either the server, or client,
   encounters an error, or the server returns GSS_S_COMPLETE in
   gss_status.

   Upon completion, rxgk_info contains the XDR representation of a
   RXGK_ClientInfo structure, encrypted using gss_wrap() with
   confidentiality protection.  The client should decrypt this structure
   using gss_unwrap - ClientInfo contains the following server populated
   fields
   errorcode  A policy (rather than connection establishment) error
         code.  If non-zero, an error has occured, the resulting key
         negotiation has failed, and the rest of the values in this
         structure are undefined.
   flags
   enctype  The encryption type selected by the server.  This will be
         one of the types listed by the client in its StartParams
         structure
   level The rxgk security level selected by the server.
   lifetime  The connection lifetime, in seconds, as determined by the
         server (this must be less than or equal to the lifetime
         proposed by the client)
   bytelife  The maximum amount of data (in log 2 bytes) that may be
         transfered using this key.  This must be less than or equal to
         the bytelife proposed by the client
   expiration  The time, in seconds since the Unix epoch, at which this
         token expires
   mic   The result of calling gss_get_mic over the XDR encoded
         representation of the StartParams request received by the
         server.
   token An rxgk token.  This is an opaque blob, as detailed earlier
   server_nonce  The nonce used by the server to create the K0 used
         within the rxgk token

   Upon receiving the server's response, the client must verify that the
   mic contained within it matches the MIC of the XDR representation of
   the StartParams structure it sent to the server (this prevents a man
   in the middle from performing a downgrade attack).  It should also
   verify that the server's selected connection properties match those
   it proposed.

   The client may then compute K0, by taking the nonce it sent to the
   server (client_nonce), and the one it has just received
   (server_nonce), combining them together, and passsing them to
   gss_psuedo_random, with the GSS_C_PRF_KEY_FULL option





Wilkinson                                                       [Page 7]
=0C
                rxgk: GSSAPI based security class for RX  September 2009


           gss_pseudo_random(gssapi_context,
                             GSS_C_PRF_KEY_FULL,
                             client_nonce || server_nonce,
                             K,
                             *K0);

   || is the concatenation operation

   K, the desired output length, is the key generation seed length as
   specified in the RFC3961 profile of the negotiated enctype


6.  The combine tokens operation

6.1.  Overview

   A client may elect to combine multi rxgk tokens in its possession
   into a single token.  This allows an rx connection to be secured
   using a combination of multiple, individually established identities,
   which provides additional security for a number of application
   protocols.

   Token combination is performed using the CombineTokens RPC call.  The
   client has two keys - K0 and K1, and two tokens, T0 and T1.  It
   locally combines the two keys using a defined combination alogrithm
   to produce Kn.  It then calls the CombineTokens RPC with T0 and T1,
   to receive a new token, Tn, which has embeded within it Kn, as
   computed by the server.

6.2.  Key combination algorithm

   Assume that the tokens being combined are T0 and T1, with initial
   keys K0 and K1.  The new initial key for the combined token, Kn is
   computed using the KRB-FX-CF2 operation, described in section 6.1 of
   draft-ietf-krb-wg-preauth-framework-14.txt.  The constants pepper1
   and pepper2 required by this operation are defined as the ASCII
   strings "AFS" and "rxgk" respectively.

6.3.  RPC definition

   The combine keys RPC is defined as

   CombineTokens(IN opaque token0,
                 IN opaque token1,
                 OUT opaque new_token) =3D 2;






Wilkinson                                                       [Page 8]
=0C
                rxgk: GSSAPI based security class for RX  September 2009


6.4.  Server operation

   The server receives both token0 and token1 from the RPC call, and
   decrypts these tokens using its private key.  Providing this
   decryption is successful, it now has copies of the initial key (K0)
   from both tokens.  It then performs the key combination algorithm
   detailed above to obtain a new key, Kn.  The server constructs a new
   token, where each of the numerical fields are set to the minimum of
   the values of each of the original tokens, and the list of identities
   is the union of those in the original tokens.  This new token
   contains the derived key, Kn.  The new token is encrypted with the
   server's private key, as normal, and returned to the client.

6.5.  Client operation

   As detailed within the overview, the client calls the CombineTokens
   RPC using two tokens, T0 and T1 within its posession.  It then
   receives a new token, Tn from this call.  The client can only make
   use of Tn to establish an rxgk security class if it can derive Kn,
   which it can only do if it already knows K0 and K1.


7.  The rxgk security class

7.1.  Overview

   When the server decides that an incoming call requires protection it
   sends a challenge to the client in the usual RX way.  This challenge
   contains some versioning information, and a random nonce selected by
   the server.  Upon receiving this challenge, the client stores the
   current timestamp (start_time in this description). start_time is
   then used, along with other connection information to derive a
   transport key from the current user's master key (K0) which was
   negotiated as part of an earlier key negotiation or token combining
   operation

   Upon receiving this challenge, the client uses the transport key to
   encrypt an authenticator, which contains the server's nonce, and some
   other connection information.  The client sends this authenticator,
   together with start_time and the current user's rxgk token, back to
   the server.

   The server decrypts the rxgk token to determine the master key in
   use, uses this to derive the transport key, which it in turn uses to
   decrypt the authenticator, and thus validate the connection.






Wilkinson                                                       [Page 9]
=0C
                rxgk: GSSAPI based security class for RX  September 2009


7.2.  Key derivation

   In order to avoid the sharing a keys between multiple connections,
   each connection has its own transport key, TK, which is derived from
   the master key, K0.  Derivation is performed using the PRF+ function
   defined in RFC4402, combined with the random-to-key function of K0's
   encryption type, as defined in RFC3961.  The PRF input data is the
   concantenation of the rx epoch, connection ID, and start_time, all in
   network byte order.  This gives:

     TK =3D random-to-key(PRF+(K0, L, epoch || cid || start_time))

   Note that start_time is selected by the client when it receives the
   server's challenge, and shared with the server as part of its
   response.  Thus both sides of the negotiation are guaranteed to use
   the same value for start_time.

7.3.  The Challenge

   The rxgk challenge is an XDR encoded structure with the following
   signature:

      struct RXGK_Challenge {
          afs_int32 version;
          opaque nonce[20];
      };

   version:  The rxgk version number
   nonce:  20 octets of random data

   A client receiving a challenge containing an unknown version number
   MUST reject that challenge.

7.4.  The Response

   The rxgk response is an XDR encoded structure, with the following
   signature:

      struct RXGK_Response {
           afs_int32 version;
           afs_int64 start_time;
           opaque token<>
           opaque authenticator<>
      };







Wilkinson                                                      [Page 10]
=0C
                rxgk: GSSAPI based security class for RX  September 2009


   version:  the rxgk version number
   start_time:  the number of seconds since the Unix epoch (1970-1-1 00:
         00:00Z)
   authenticator  the XDR encoded representation of RXGK_Authenticator,
         encrypted with the transport key, and key usage
         RXGK_CLIENT_ENC_RESPONSE.

7.4.1.  The Authenticator

      struct RXGK_Authenticator {
           opaque nonce[20];
           afs_uint32 epoch;
           afs_uint32 cid;
           afs_int32 call_numbers[RX_MAXCALLS];
      };

   nonce:  a copy of the nonce from the challenge
   epoch:  the rx connection epoch
   cid:  the rx connection ID
   call_numbers:  the set of current rx call numbers

7.5.  Checking the Reponse

   To check the validity of an rxgk response, the authenticator should
   be decrypted, the nonce compared with that sent in the challenge, and
   the connection ID and epoch compared with that of the current
   connection.  Failure of any of these steps MUST result in the failure
   of the security context.

7.6.  Packet handling

   The way in which the rxgk security class handles packets depends upon
   the requested security level.  As noted earlier, 3 levels are
   currently defined - authentication only, integrity protection and
   encryption

7.6.1.  Encryption

   Using the encryption security level provides both integrity and
   confidentiality protection.

   The existing payload is prefixed with a header, to produce the
   following data for encryption.








Wilkinson                                                      [Page 11]
=0C
                rxgk: GSSAPI based security class for RX  September 2009


    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                          Call Number                            |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                        Sequence Number                      | * |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |          Data Length            |           Service ID          |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   | Data .....
   +-+-+-+-+

   The field marked with * is the 2 bit channel ID.

   This plaintext is encrypted using an RFC3961 style encrypt()
   function, with the connection's transport key, using key usage
   RXGK_CLIENT_ENC_PACKET for messages from client to server, and
   RXGK_SERVER_ENC_PACKET for messages from server to client, and the
   encrypted block transmitted to the peer.

7.6.2.  Integrity protection

   The rxgk_auth security level prepends the packet with the same data
   block as crypt (as detailed above), and then calls the RFC3961
   get_mic operation over the result, using key usage
   RXGK_CLIENT_MIC_PACKET for messages from client to server, and
   RXGK_SERVER_MIC_PACKET for messages from server to client.

   The peer is sent the output from the MIC operation, followed by the
   original payload (excluding the additional header which was added for
   the MIC step).

   Upon receiving a protected packet, the receiver should consult the
   RFC3961 profile for the encryption algorithm in use to determine how
   many bytes of checksum are contained within the packet.  Having split
   the data into checksum and payload using this information, the
   checksum should be verified using the encryption profile's
   verify_mic() operation with the appropriate key derivation.

   Note that the checksum field within the rx packet header itself is
   not used, as it is too small to hold a collision proof checksum
   value.

7.6.3.  Authentication only

   When running at the rxgk_clear level, no manipulation of the payload
   is performed by the security class.





Wilkinson                                                      [Page 12]
=0C
                rxgk: GSSAPI based security class for RX  September 2009


8.  Acknowledgements

   rxgk was originally developed over a number of AFS Hackathons.  The
   editor of this document has assembled the protocol description from a
   number of notes taken at these meetings, and from a partial
   implementation in the Arla AFS client.  Thanks to Derrick Brashear,
   Jeffrey Hutzelman, Love Hornquist Astrand and Chaskiel Grundman for
   their original design work, and comments on this document, and
   apologies for any omissions or misconceptions in my archaelogical
   work.


9.  Notes

   This document has been compiled from a number of sources.  This
   section details those locations where the different sources
   significantly differ, and other observations whilst compiling the
   specification.  It is not intended to appear in the completed
   document.

   There is currently no way within an rxgk token to specify which key
   it is encrypted with, and so no way to support multiple keys on the
   one server

   The rxgk_notes file specifies that the Token format is implementation
   defined.  And yet, if we want to be able to interoperate between
   servers from different implementations we have to define what this
   looks like, as it travels on the wire.  I suspect it is protocol
   dependent, and its definition probably belongs in the document which
   details how AFS uses rxgk

   rxgk_notes has the crypt and auth header being "callNumber | seq |
   serial | user_status | flags | svcid (same as rxkad)" However, arla
   uses the smaller header detailed in this document.

   No mention is made of what an implementation should do if the fields
   with the encrypted/authenticated packet header differ from those in
   the cleartext header

   Arla and rxgk notes differ significantly in their descriptions of the
   key negotiation process.  Arla introduces the opaque fields for
   maintaining state, the nametag in StartParams, flags in ClientInfo,
   and changes the format of the MIC

   At no point do we specify acceptable client and server nonce sizes






Wilkinson                                                      [Page 13]
=0C
                rxgk: GSSAPI based security class for RX  September 2009


Author's Address

   Simon Wilkinson
   Your File System Inc

   Email: simon@sxw.org.uk













































Wilkinson                                                      [Page 14]
=0C

--Apple-Mail-15-110320617
Content-Type: text/plain;
	charset=US-ASCII;
	format=flowed
Content-Transfer-Encoding: 7bit



--Apple-Mail-15-110320617--