ietf-smime
[Top] [All Lists]

Re: Strawman for adding a MDC to encrypted data

2006-12-08 08:57:52
Peter Gutman wrote on 12/08/2006 01:36:31 AM:


Over the years there have been various papers published on messing with 
CBC-
encrypted data to perturb the plaintext in a predictable way.  The 
OpenPGP
folks addressed this issue fairly quickly by adding an MDC to their 
encrypted
content, but S/MIME doesn't address it at all.  What makes this issue a 
lot
more troublesome is that the public perceives encryption as providing 
data
integrity protection, a service it in fact doesn't provide (they also 
perceive
signing as providing no data integrity protection, see Garfinkel 2006). 
Short
of educating the entire world's email-using population about 
cryptographic
security issues, the other possible alternative is to make the 
encryption act
in the way they think it acts.

(There are other useful applications of the added MDC as well, e.g. when
 wrapping private keys for storage the MDC protects against the 
Klima-Rosa
 attack, which OpenPGP keys are protected against but S/MIME ones 
aren't).

A simple fix for the problem is to add an MDC to EnvelopedData.  There 
are
alternatives, but none are practical: wrapping the EnvelopedData in
AuthenticatedData collapses under the weight of key management and
implementation issues, using a combined encrypt+authenticate mode is 
either
impractical due to patent concerns or has severe implementation problems
because these new modes will take an arbitrarily long amount of timeto 
become
widely supported, etc etc.

The MDC approach is a relatively straightforward change that simply runs 
a
hash over the ciphertext and attaches the encrypted form of the hash 
(using
the content-encryption key used to encrypt the rest of the content) to 
the
EnvelopedData as UnprotectedAttributes.  So the process becomes:

  ciphertext = encrypt( plaintext );
  MDC = encrypt( hash( ciphertext ) );

Hmm ... I vaguely recall some problems with using a unkeyed hash, e.g. 
SHA-1, to protect integrity.  Here's what I can remember at the moment, 
sorry if I'm making a mistake.

Presumably encrypt does not protect integrity, so, the attacker may be 
able to change ciphertext to ciphertext', and further know that the 
corresponding decryption plaintext' has some meaningful relationship to 
plaintext.  Now the attacker can compute hash(ciphertext') and if the 
encrypt function has sufficiently poor integrity, the attacker can use 
this knowledge of MDC to compute MDC' = encrypt(hash(ciphertext')).

An example of an encrypt function that is vulnerable to this any stream 
cipher, such as RC4.  Specifically, let ciphertext' = ciphertext xor delta 
= (rc4-stream xor plaintext) xor delta, giving plaintext' = plaintext xor 
delta.  Now MDC' = MDC xor hash(ciphertext) xor hash(ciphertext').

Even if S/MIME does not allow stream ciphers, they demonstrate that the 
construction above presumes that the encrypt function must have some kind 
of integrity properties.  I'm not sure if AES-CBC, for example, has the 
requisite integrity-protection property for the construction above.

An alternative construction may work, though:

MDC = MAC (ciphertext);

where MAC could be HMAC and the key would be the CEK, or a derivative 
thereof.  Using a MAC in this way has precedent in a scheme like 
DHAES/ECIES.  The scheme DHAES has a published security proof, so it has, 
to a significant extent, precedent in the academic crypto community.

Admittedly, the alternative construction, however, might require more 
implementation work than hash based construction, since some S/MIME 
implementations may not have code for computing a MAC (unless they 
implemented AuthenticatedData).  Even so, it doesn't really take too much 
work to implement HMAC given a hash function implementation.

Dan Brown
(905) 501-3857
http://www.certicom.com


Hashing the ciphertext protects against other attacks relating to 
manipulating
of PKCS #5 padding content.  The use of the content-encryption 
key/cipher for
the MDC tag avoids key management issues.  The OpenPGP folks have been 
doing
this for some years now, and it has the approval of the crypto 
community.

The only problematic issue is how to indicate the use of the MDC 
algorithm.
Some options are:

  Use a version number of 5 to indicate (implicitly) the use of a SHA-1 
MDC.

  Add something to the RecipientInfos as an OtherRecipientInfo that 
simply
  contains the hash algorithm details.

  (As above, but with OriginatorInfos).

The second option is a bit of a kludge, but seems to be the cleanestway 
to do
it.  The overall changes are very minimal, a new UnprotectedAttribute 
type
with the MDC, a new OtherRecipientInfo type, and a bit of code to run a 
hash
alongside the en/decrypt.  In my trial implementation (excluding the
attribute-handling) there were only about a dozen lines of code required
because the hashing is already performed for SignedData so all it 
required was
turning on the hash flag if an MDC was specified in the RecipientInfo.

Is there any support for adding this?  I should be able to get a draft 
out
fairly quickly, and from a check with two other implementors producing
interoperable implementations should be fairly easy.