[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: DIGEST-MD5 SASL mechanism?




> -----Original Message-----
> From: Lawrence Greenfield [mailto:leg+@xxxxxxxxxxxxxx]
> Sent: Wednesday, July 07, 1999 1:20 PM
> To: Paul Leach
> Cc: 'ietf-sasl@xxxxxxx'
> Subject: Re: DIGEST-MD5 SASL mechanism?
> 
> 
> [...]
>    > 
>    > - the MAC is defined including the "variable length 
> padding prefix",
>    >   but the padding is treated as part of the message.
> 
>    No, it is just encrypted with the message, it isn't part 
> of the message. The
>    MAC for encrypted messages is the padding concatenated 
> with the MAC for
>    unencrypted messages.
> 
> This really doesn't make sense.  A "MAC" is a message authentication
> code; padding is not part of the message authentication.

If I wanted to be technical: sure it is, in the sense that if the pad bytes
contain the incorrect value, the MAC won't check. However, it indeed isn't a
traditional MAC such as HMAC or keyed MD5.

However, I take your point. I'll admit I was loose with the terminology --
it would have been more accurate to be something like the "MAC trailer"
which is the pad, version, MAC, and sequence number.

> 
> Further, you don't cover what happens if the HMAC length is not a
> multiple of the cipher blocksize.

Duh. Oops. Drat. Good catch.

> 
> draft 03 specifies the encryption as follows:
> 
> SEAL(Ki, Kc, SeqNum, msg) = CIPHER(Kc, { msg, pad}), CMAC(Ki, Kc,
>       SeqNum, msg)
> CMAC(Ki, Kc, SeqNum, msg) =
>     { 0x00000001, CIPHER(Kc, HMAC(Ki, (SeqNum, msg))[0..7]), SeqNum }
> 
> From your message, I've corrected this to:
> 
> SEAL(Ki, Kc, SeqNum, msg) = CIPHER(Kc, { msg, pad}), CMAC(Ki, Kc,
>       SeqNum, msg)
> CMAC(Ki, Kc, SeqNum, msg) =
>     { 0x0001, CIPHER(Kc, HMAC(Ki, (SeqNum, msg))[0..9]), SeqNum }
> 
> Of course, the 10 byte HMAC prefix is not a multiple of the 8 byte DES
> block.

Someone made me change it; it used to be 8 bytes. That's when the version
number was 4 bytes. And everything worked -- but there was an objection that
the MAC wasn't long enough.
(Of course, it's still true that we'd be screwed with any cipher with a
block size longer than 8 bytes.)

> 
> I would propose encoding instead as follows:
> 
> SEAL(Ki, Kc, SeqNum, msg) = 
>    CIPHER(Kc, { msg, pad, CMAC(Ki, SeqNum, msg) } )
> 
> CMAC(Ki, SeqNum, msg) =
>    { 0x0001, HMAC(Ki, (SeqNum, msg))[0..9], SeqNum }
> 
> where pad is 1 or more bytes containing the amount of padding needed
> to make msg + CMAC be a multiple of the block size.

The simplest change is just to make the size of the pad big enough to (msg +
10) (10 being the size of HMAC output) be a multiple of the block size.

The reason for preferring the simplest change is that the DIGEST-SASL
mechanism is holding up the LDAP RFCs.

> 
> Is there a reason that the sequence number and version field were left
> unencrypted?  In order to minimize the amount of easy cribs?

Although not decribed, the same basic algorithm works for packet flows which
can be recieved out of order (because they are sent over UDP or because of
multiplexing a single TCP connection, as the HTTP/NG folks have talked about
doing. Stream ciphers are problematic in this case. To accomodate them, when
handling out-of-order delivery, each packet, instead of using Ke for the
encryption key, uses HMAC(Ke, SeqNum). This requires the SeqNum to be in the
clear.

The version number beng in the clear is a holdover from an existing protocol
with which I have experience which I thought would be useful to leave in the
clear. The idea it could affect the decryption somehow in future versions,
or indicate different MAC, or that rekeying was needed after a certain
amount of traffic. However, I agree that it's not so important.

Paul