Sorry that I didn't get to look at it earlier.

Jim's "option 2" is cryptographically baaaaaaad. Using non-secret
(possibly malleable) information as the AES key for the purpose of
key-derivation raises nasty issues wrt related keys. If the application
uses the same "user key" with several "transform keys" that are only
slightly different, then the resulting "device keys" will be related
in a bad way. I don't know if this can be exploited for cryptanalysis,
but I will not be very surprised if it can.

"Option 1" is much much better, and the "lost entropy" in the keys is
a non-issue (even these were 128-bit keys, and certainly for 256-bit
keys).

-- Shai

On Jan 5, 2006, at 6:43 PM, Matt Ball wrote:

Hi Jim,

Let me make sure I understand the idea.  Does this describe a
possible implementation of the two options?:

Option 1:

    K2[0:127]   = AES-Enc_k1(id)
    K2[128:255] = AES-Enc_k1(id')

where id is a globally unique identifier and id' is also unique,
but possibly derived from id.

Option 2:

    K2[0:127]   = AES-Enc_id(k1[0:127])
    K2[128:255] = AES-Enc_id(k1[128:255])

(We have a subtle problem because the AES cipher is using a 256-bit key,
but processes 128-bit blocks.  To generate the derived key, it
would then be necessary to perform at least two encoding operations
from the AES engine.)

Concerning the two options, I suspect that Option 1 might be more secure
because it is not easy to compute k1 given K2.  It also uses  the full
256-bit k1 in the correct place in the AES block cipher  (i.e. as the key
input).  However, with Option 1 there is an issue  with creating a good
value for id' (maybe use the 1's complement of  id?).  Also, it appears
that there is likely a loss of entropy in  Option 1, similar to the loss
from a hashing function.  In fact, I  suspect the entropy loss might be
greater because of using two  block ciphers (each block cipher in this
configuration would  probably lose roughly 2/3 of a bit of entropy, for
a total of 4/3  of a bit).

Option 2 is more symmetric with respect to k1 and k2 and doesn't
have the problem of needing an alternate id'.  It would also allow
a 256-bit (32 byte) id instead of 128-bit.  However, if k1[0:127]
== k1[128:255], then the derived K2 will also have the upper and
lower halves being the same.  I suspect this isn't a problem, but
it does depart a little from an ideal 256-bit random permutation.
Lastly, since the id is being used as a key, there might be weak
key problems, although I suspect this isn't an issue.

Option 2 also maintains the full entropy of k1 within K2, which is
probably the most compelling reason to use this construct over a
hashing function.  However, the hashing function approach has a bit
more flexibility with allowing variable-length inputs and also
protects k1 if K2 is ever discovered.

I'm personally leaning towards using HMAC, although I could be
easily persuaded to use AES.

Any other thoughts?

-Matt

Reply via email to