$Id$

Overview
========

- RX crypto class

	rxgk is a new crypto class, mostly since the interface need to
	be changed in the ktc for openafs anyway (at least binary
	interface).

	rxgk (krb5) can be used when the kdc returns a non des enctype.

- Layers

	There are two layer, the transport layer that is authentiation
	mechamism independent, and the authentiation layer.

	The glue between the authentiation layer and the transport
	layer is the RXGK authenticator.

- RXGK authenticator

	The only reson for the RXGK authenticator exists is that there
	are not fragmentation in the Challange/Response protocol in
	Rx. This limits the authentization in Rx to MTU sized packages.

- RXGK authenticator lifetime

	The server has a local key that is used to encrypt the gk
	authenticators. The local key is semi stateful, the
	server need to remember the old keys al long as there are
	valid RXGK authenticators held by any client. New RXGK
	authenticators can be fetched at any time but might require
	user input.

- Getting RXGK authenticator

	the authenticator is fetched using a service rx_null on the
	same port as the server the client wants to talk too.

transport layer
===============

- Key derivation

	Each connection get separate key for each connection/epoch.
	Each direction get a separate key for each direction.

	S = Session key
	CN = connection key
	counter = key generation (nonce)
	K{server} = Key from server direction
	K{client} = Key from client direction

	X{cn} = epoch{32} | cid{32} | key_counter{64}
	
	CN = random-to-key(pseudo-random(S, X{cn})

	K{server} = KD(CN, 0)	{ key used on data from server }
	K{client} = KD(CN, 1)	{ key used on data from client }

	Checksum field in the header (spare1) is always set to the
	lower 4 bits of the key_counter field. Ie server may not
	request rekeying faster the (4 * rc_max_seq_skew) packets.

	K depends on {S,epoch,cid,key_counter}

- Rekeying 

	Rekeing is needed since kcrypt assumes that data isn't
	encrypted for the 2**48 messages with the same key.

- Challenge/Response

	When the client is unknown to the server it sends a challenge
	with opcode RXKG_OPCODE_CHALLENGE (nonce).

	The client the send back a rxgk authenticator and the
	encrypted nounce.

- Wire protocol

	crypt mode

	Each packet are encrypted as [KCRYPTO] specifies. The data is
	prefixed with parts of the rx header that matter.

	auth mode

	Each packet are checksumed as [KCRYPTO] specifies. The data is
	prefixed with parts of the rx header that matter [4]. In auth
	mode the rx header subsitute is not sent over write to save
	space.

	The part of the header that is checksumed are these fields:

		uint32_t callid
		uint32_t seqno
		uint32_t serialno
		uint8_t  userstatus
		uint8_t  someflags (RX_PRESET_FLAGS)
		uint8_t  serviceid

Authentication RPCs
===================

- Information RPCs

	To be later specified.

	There is an information API to, with a RXGK authenticator, the
	client can verify what authentiation mechamisms is supported,
	both insecure and authenticated.

- Kerberos 5 to rxgk authenticator RPCs

	key{KerbS} - kerberos session subkey key

	The mutual auth data in the RXGK_EstablishKrb5Context is
	encrypted with the key{KerbS} key.

	Client sends acceptable enctypes and nonce to the server in
	challenge.

	Server sends back key(auth-cred-key) and nonce + 1 to the 
	client together with a RXGK authenticator cred encrypted with
	key{KerbS}.

	auth-cred is protected by key{gkkey}

	key{S} = key{auth-cred-key}

- GSS-API to rxgk authenticator RPCs

	To be later specified.

========

Code assumptions:

	L.NXS.SE realm

	gkkey@L.NXS.SE and afs@L.NXS.SE key exists in default keytab

========
implementation/higher level issues


- RXGK_AUTH_CRED needs checking
	
	[ 2. should we use the session key or the a random octet
	string generatated by the server, the key(auth-cred-key) below ]

	[ 3. ac_principal: gss exported name ? this to make it idependant
	of kerberos 5. Problem with gss name only specifed gss-mechs
	can be used. Server local so it can really be anything the
	server wants it to be. Need to be kept short so it will fit on
	one MTU. Also see {{10}}. ]

	The RXGK authenticator is fetch by doing either the RXGK
	GSSAPI rpc's or the RXGK_EstablishKrb5Context rpc to the RXGK
	service on the same port as the service that rxgk
	secures. Doing the RPC call gives you a gk authenticator and a
	key(S) that is valid for one server. The input to GSSAPI rpc
	and EstablishKrb5Context are mech specific.

	GSS-API
	[ 11. see rxgss how this should me implemented ... ]

exported auth name

	all mech's need to have a rxgk name to krb4 name function
	until pts is changed to support rxgk names.

	[ 10. Proposal: the protection interface have GKNAME to
	AFS/PTS named RPCs.

	In this proposal all names are mapped to one AFS username.

	For example, gss exported named KRB5:lha@SU.SE, krb5 native
	lha@SU.SE and krb5 native krb5 lha@KTH.SE all map to the same
	afs username `lha'.


	Also see {{3}}. ]


TODO:

- Auth mode

- Pass length since krb encryption doesn't preserve length (some enctypes does)

	[ 8. Is this really needed, packets are always send full ]

- More tests

	More the MTU since rpcs
	Stored packets packets, compare generate packages
	Check other checksum


DEPRICATED IDEAS

- Diffrent keys for fileservers

	I think we should ignore this for rxgk/kerberos 5 or do
	"fileserver groups" as discuss on Pittsburgh so this will
	happen. For "fileserver groups" a get groups rpc should be
	added to the vlserver (this will make non rx afslogs harder 
	to implement) and in the first version we just insert a rpc
	stub that return one name only, "default", or something
	equally silly.

	The reson you want to have diffrent keys for fileservers are

	- increased security (more keys, less data encrypted with the
	  same key, one server compromised doesn't compromise all servers)

	- give a fileserver to someone else that you not trust
	  to have the master key

  Depricated since we can get consensus, rxgk/gssapi will/must solve
  the problem.
