Fair enough, Russ.
The only problem is that I have never known a standard that didn't
end up being picked up and used by another group, many times inappropriately,
because they didn't understand the context and limitations of the original
effort.
Any comments on my proposed solution?
bob
Russ Housley <housley(_at_)spyrus(_dot_)com> 02/04/99 02:18PM >>>
Bob:
I do not mind if a group goes off and solves the most general problem, but
that is not the problem that I have.
In the S/MIME v3 environment and other environments that use the
Cryptographic Message Syntax (CMS), the KEK and CEK will always be
symmetric keys. If we could come to closure on one symmetric key wrapping
another symmetric key, it would be very helpful to the S/MIME v3 effort.
In fact, wrapping one 3DES key in another 3DES key is the highest priority,
and wrapping one RC2 key in another RC2 128-bit key is the next highest
priority.
Russ
At 12:57 PM 2/4/99 -0700, Bob Jueneman wrote:
Peter,
The only [small] problem I have with your approach is performance,
as double encryption with triple-DES is relatively expensive, especially
if you don't save and reuse the state after the three key expansions
step in DES. In addition, I would like to have a key wrapper format
that is completely independent of the KEK algorithm, soi that I can use
the same wrapper whether I use DES, RSA, elliptic curves, etc. And
I don't think you want to propose doing double encryption with an
asymmetric cipher!
What I would suggest would be to replace your inner encryption
with the equivalent of Output Feedback mode, but using SHA-1
as the encryption or whitening function, with a random nonce R serving
as the starting seed for SHA-1.
In other words, begin by computing SHA-1(R) of the random nonce, and
call that W(1). Then W(2) = SHA-1(W(1)), and W(n) = SHA-1(W(n-1)),
where n= length(keyblob + encryption block size)/160 rounded up to
the next SHA-1 block boundary, so that any necessary padding is whitened
as well.
Then XOR the string of W(1)...W(n) with the keyblob KB(1)...KB(n) to
produce the whitened plaintext of the keyblob, P(1)...P(n).
Finally, encrypt R || P(1)...P(n) using whatever KEK algorithm is desired.
Now the only question I have is whether the fact that the whitening
does not involve the plaintext and is therefore known once the random
nonce has been decrypted can somehow be used to leak information,
given partially known plaintext in the keyblob. It would if the nonce weren't
secret, but in order to gain any information about the nonce would require
finding a ciphertext block that matches a specific block, corresponding to R,
rather than merely finding any two matching blocks.
So I don't see an attack, regardless of the type of KEK encryption algorithm
used, including both symmetric and asymmetric algorithms. Does anyone else?
I do concede that this approach produces some data expansion -- at least 160
bits for the random nonce, and perhaps some more for padding if the keyblob
that
is being encrypted is not an exact multiple of the encryption block size.
Generally speaking, that is a tradeoff I would be willing to make.
Bob
Peter Gutmann <pgut001(_at_)cs(_dot_)auckland(_dot_)ac(_dot_)nz> 02/05/99
02:46AM >>>
[Note: Recipient list trimmed to those who've shown an interest so far]
Instead of using OAEP-type padding (which is rather complex to implement and
results in data expansion), why not just encrypt the wrapped key twice? This
way, the outer encryption layer depends on every bit in the inner encryption
layer, and that depends on the plaintext and MEK, so you never get lots of
identical messages encrypted with different keys. This is trivial to
implement, requires no extra algorithms beside than the cipher used for the
wrapping, and results in no data expansion. Here's how it works:
Notation:
P[] = plaintext blocks
C1[], C2[] = ciphertext blocks encrypted once/twice
Encryption:
Encrypt P[ 0 ]...P[ n ] using the initial IV
Encrypt C1[ 0 ]...C1[ n ] using the existing IV from the previous pass
(ie C1[ n ])
Decryption:
Decrypt C2[ 1 ]...C2[ n ] using C2[ 0 ] as the IV
Decrypt C2[ 0 ] using C1[ n ] as the IV
Decrypt C1[ 0 ]...C1[ n ] using the initial IV
Peter.