Subject: looking for feedback on crypto draft: cipher state chaining

From: Ken Raeburn <[email-masked]>
Date: 30 May 2002 19:22:17 -0400

The current draft of the Kerberos crypto spec includes the "cipher
state" idea, and the possibility of chaining this opaque thing from
one encryption operation to the next.  It's meant to encompass initial
vectors, counters, "tweaks" (see Liskov & Rivest, "Tweakable Block
Ciphers"), nonces, or what have you.  Maybe it's a bunch of random
bytes, or maybe it's structured; that's why it's supposed to be
opaque, and not explicitly settable in the application protocol spec.

It allows for enforcing sequencing in a stream of messages using the
same encryption key and key usage number with (in the current
cryptosystems) no additional space, but with the drawback that an
out-of-sequence message looks just like any other corruption of the
message; it's not a full substitute for actual sequence numbers if you
want to be able to identify that particular problem.

However, the Kerberos specification makes no use of this chaining
capability, since all message encryptions are independent of one
another.  Do we want to keep it?

If we keep it, we can use the framework as a more general facility for
doing encryption (and other operations) using Kerberos-derived keys in
application protocols that want to send low-overhead protected streams
of messages, without having to know things about the specific
encryption types, and without having to invent additional crypto
support for each application protocol.

If we get rid of the chaining, we focus on isolated message
encryptions, drop the cipher state altogether (since it would always
have to have the "initial" value) and the specification for the
encrypt and decrypt operations becomes simpler.  Application code can
use KRB-SAFE and KRB-PRIV messages (if they don't mind all the
overhead), or use the raw keys in some manner defined specifically for
the application protocol, though experience has shown that it's easy
to do a bad job of that.  And often it means writing specs in terms of
particular encryption systems, and thus updating the protocol every
time you want to use it with a new encryption system.

Another consideration: We currently make no allowance for limiting the
amount of data or number of messages encrypted using a given key, so
as to protect the key from certain types of attacks.

Any comments?

I think either we need to remove it, or add some justification in the
text.

On a related note: I've heard fairly little feedback on the crypto
draft in general.  Is this because you think:
 - "it's great, keep it just like it is"
 - "that's so stupid.  well, someone else will say something..."
 - "who cares, just get the damn thing published already"
 - "what do you mean?  i sent some feedback!"  -- in which case, i'm
   not talking about you :-)
 - "crypto draft? what?"

BTW, I'm investigating making some changes to the "simplified profile"
to make it a bit more flexible for some things I'd like to do in the
AES spec....

Ken

---

From: Martin Rex <[email-masked]>
Date: Fri, 31 May 2002 14:59:55 +0200 (MET DST)

> opaque, and not explicitly settable in the application protocol spec.

Wouldn't you need to keep state when using a stream cipher instead
of a block cipher?  Didn't Microsoft implement Kerberos with
an RC4 stream cipher (and some other vendors others before them)?

When using stream ciphers, you also have to keep independent
state for each direction (because you really don't want to
limit yourself to half-duplex).  :)

-Martin

---

From: "Nicolas Williams" <[email-masked]>
Date: Fri, 31 May 2002 10:33:58 -0400

On Thu, May 30, 2002 at 07:22:17PM -0400, Ken Raeburn wrote:

[...]

How significant is the additional overhead of using KRB-SAFE/KRB-PRIV as
opposed to stream encryption?

> to do a bad job of that.

I suspect developers will generally prefer to use stream encryption
over KRB-SAFE/KRB-PRIV when the application protocol is stream oriented.
I don't see why they shouldn't, as long as their protocols allow for
negotiation of crypto system so as to allow for upgrades in the face of
new cryptanalytic attacks.

>                           And often it means writing specs in terms of

Yes. Higher level protocols (e.g., SSHv2) should abstract the crypto
system so as to make it easier to introduce new crypto algorythms and
techniques.

> as to protect the key from certain types of attacks.

Unfortunately, rekeying is difficult to specify at this level since that
implies that the protocol using the crypto framework includes the ability
of the participants to initiate session rekeying. The best that the
crypto system can do is specify the lifetime/use limits of cipher states,
thus hinting to the API develpopers that they must pass such information
back to the applications (whose developers in turn are thus made aware
of the requirement to include a rekey facility in their protocols).

> I think either we need to remove it, or add some justification in the

IMHO there is significant value to having this sort of crypto system
spec lying around. Others will need something like it eventually and if
this spec is not available they will reinvent the wheel, badly. I'm
thinking that protocols such as SSHv2 and TLS would be having an easier
time now if their designers had abstracted the crypto system more than
they did - introducing confounders now would be just a matter of adding
a new encryption type.

OTOH, Kerberos has never been about how apps do stream encryption and
there's no need to introduce that now, except for the fact that there
are apps that use Kerberos and which also use stream encryption, and
maybe got it wrong (kcmd.c?). Such apps could be handled by the spec
with a "though shall not do that"/"though shall use KRB-SAFE/KRB-PRIV",
or the spec could cater to them as it does now.

But if removing the stream crypto facility would speed up the RFC
process, then by all means remove it.

Can the cipher state stuff be put in a separate document? Is there any
reason why it should be tightly tied to Kerberos (name-wise, if nothing
else)? What WG should be responsible for a stream crypto spec?

> Ken

Cheers,

Nico
-- 
-DISCLAIMER: an automatically appended disclaimer may follow. By posting-
-to a public e-mail mailing list I hereby grant permission to distribute-
-and copy this message.-

Visit our website at http://www.ubswarburg.com

This message contains confidential information and is intended only 
for the individual named.  If you are not the named addressee you 
should not disseminate, distribute or copy this e-mail.  Please 
notify the sender immediately by e-mail if you have received this 
e-mail by mistake and delete this e-mail from your system.

E-mail transmission cannot be guaranteed to be secure or error-free 
as information could be intercepted, corrupted, lost, destroyed, 
arrive late or incomplete, or contain viruses.  The sender therefore 
does not accept liability for any errors or omissions in the contents 
of this message which arise as a result of e-mail transmission.  If 
verification is required please request a hard-copy version.  This 
message is provided for informational purposes and should not be 
construed as a solicitation or offer to buy or sell any securities or 
related financial instruments.

---

From: Tom Yu <[email-masked]>
Date: 31 May 2002 21:08:06 -0400

>>>>> "Nicolas" == Nicolas Williams <[email-masked]> writes:

Nicolas> On Thu, May 30, 2002 at 07:22:17PM -0400, Ken Raeburn wrote:
Nicolas> [...]

Nicolas> How significant is the additional overhead of using
Nicolas> KRB-SAFE/KRB-PRIV as opposed to stream encryption?

KRB-SAFE and KRB-PRIV add a _minimum_ of 48 octets, assuming all
optionals omitted, all (allowed) integers positive but less than 127,
and all octet strings are zero length.  Additionally, this value of
overhead ignores cryptosystem-provided padding.  Obviously these
conditions are somewhat unlikely.

Gory details follow (skip if you're not interested):

====================
KRB-SAFE	::= [APPLICATION 20] SEQUENCE { -- +2+2
	pvno		[0] INTEGER (5), -- +2+3
	msg-type	[1] INTEGER (20), -- +2+3
	safe-body	[2] KRB-SAFE-BODY, -- +2+KRB-SAFE-BODY
	cksum		[3] Checksum -- +2+Checksum
}
Checksum	::= SEQUENCE { -- +2
	cksumtype	[0] Int32, -- +2+3 assuming nonzero
	checksum	[1] OCTET STRING -- +2+2 assuming zero len
}
KRB-SAFE-BODY	::= SEQUENCE { -- +2
	user-data	[0] OCTET STRING, -- +2+2 assuming empty
	timestamp	[1] KerberosTime OPTIONAL,
	usec		[2] Microseconds OPTIONAL,
	seq-number	[3] UInt32 OPTIONAL,
	s-address	[4] HostAddress, -- +2+HostAddress
	r-address	[5] HostAddress OPTIONAL
}
HostAddress	::= SEQUENCE  { -- +2
	addr-type	[0] Int32, -- +2+3 assuming nonzero
	address		[1] OCTET STRING -- +2+2 assuming empty
}

KRB-PRIV	::= [APPLICATION 21] SEQUENCE { -- +2+2
	pvno		[0] INTEGER (5), -- +2+3
	msg-type	[1] INTEGER (21), -- +2+3
	enc-part	[3] EncryptedData -- +2+EncryptedData
}
EncryptedData	::= SEQUENCE { -- +2
	etype	[0] Int32, -- +2+3 assuming nonzero
	kvno	[1] UInt32 OPTIONAL,
	cipher	[2] OCTET STRING -- +2+2 assuming empty
}
EncKrbPrivPart	::= [APPLICATION 28] SEQUENCE { -- +2+2
	user-data	[0] OCTET STRING, -- +2+2 assuming empty
	timestamp	[1] KerberosTime OPTIONAL,
	usec		[2] Microseconds OPTIONAL,
	seq-number	[3] UInt32 OPTIONAL,
	s-address	[4] HostAddress, -- +2+HostAddress
	r-address	[5] HostAddress OPTIONAL
}
====================

Using implicit tags reduces this by 22 octets, but of course we can't
do that now.  Removing the useless PVNO and MSG-TYPE fields reduces it
by another 6 octets.  Using PER would likely reduce it even more, but
I don't feel like working out the PER encoding.

---Tom