Score:2

AES key expansion question

us flag

I'm reading about the key expansion for AES but I can't seem to find the answer to this question yet. The book refers to a cipher key and the expanded key (or key schedule). This is the algorithm from the book:

procedure KeyExpansion(byte K[4][Nk], byte W[4][Nb (N r + 1)]) ? Nk ≤ 6
    for j = 0 to Nk − 1 do
        for i = 0 to 3 do
            W[i][j] ← K[i][j]
        end for
    end for
    for j = Nk to Nb (N r + 1) − 1 do
        if j mod Nk = 0 then
            W[0][j] ← W[0][j − Nk ] + S RD [W[1][j − 1]] + RC[j/Nk ]
            for i = 1 to 3 do
                W[i][j] ← W[i][j − Nk ] + S RD [W[i + 1 mod 4][j − 1]]
            end for
        else
            for i = 0 to 3 do
                W[i][j] ← W[i][j − Nk ] + W[i][j − 1]
            end for
        end if
    end for
end procedure

Question 1: In the first line, this procedure is taking a key. What is the key object that needs to be accepted by this function? It looks like this key already has the requisite number of 32-bit words for 128 or 192 (since this is the key expansion for 6 columns or less) but how would you get that from a user's random length password? Would PKCS7 have already been run so that the key is padded?

Question 2: Is this showing that the user's actual entered key is part of the key schedule or are all keys in the schedule derived from the user's actual raw input key?

Score:8
my flag

It looks like this key already has the requisite number of 32 bit words for 128 or 192 (since this is the key expansion for 6 columns or less) but how would you get that from a user's random length password?

How you derive the 128, 192 (or 256) bit key is outside of the AES specification. It takes as input that key; what you do to come up with the key is not its concern.

Now, we typically don't convert a user's password directly into a key; we normally either generate it from a Key Derivation Function (with inputs that may include the results of a key exchange operation), or possibly use the output of a secure random number generator directly (and contrive to somehow transmit this key to the other side). The problem with using a user's password directly is that the password is the weakest part of the system - it is far easier to try to guess a password than to break AES (or a key exchange operation).

Is this showing that the user's actual entered key is part of the key schedule or are all keys in the schedule derived from the user's actual raw input key?

The key expansion generates the 11, 13 or 15 subkeys that AES uses (depending on the key size). The initial 1, 3/2 or 2 blocks will be bits taken directly from the entered key; however that's not important to how AES works.

us flag
Thanks for this information.
Score:7
in flag

What is the key object that needs to be accepted by this function?

An array of bytes.

how would you get that from a user's random length password?

The usual practice is using Password-Based Key Derivation Functions (PBKDF) like PBKDF2, Bcrypt, Argon2, BalloonHash, etc. Keep in mind that they cannot increase the strength of the input. Therefore, a user must choose a good password with enough strength like a password generated with dicewire method.

In some applications like disk encryption, a uniform random key is generated for the disk encryption and this is encrypted from the key derived from the user's passwords. Still, the security depends on the quality of the password.

Also, the key material can be the source of a key exchange like DHKE, in this case a Key Derivation Function like HKDF must be applied to key material to derive AES key (bytes).

Would PKCS7 have already been run so that the key is padded?

No way, that is not secure. If you are designing a library, reject the user's (programmers') input if it is shorter than the target key size.

is this showing that the user's actual entered key is part of the key schedule or are all keys in the schedule derived from the user's actual raw input key?

The user's password should be processed with a PBKDF to derive the key. The key schedule needs a key array with size depending on the preferred AES (128,192,256). The key schedule doesn't distinguish the quality of the key material and it is not part of its design. The responsibility of the quality of the key material is on the user and libraries. The libraries that encrypt should have handled the passwords with a good PBKDF and entered the output into the key schedule. This process must be independent of the user - except for some warning about the quality of the password.

All in one;

  1. Get a password from the user and warn the user if the password is short.
  2. derive the desired key byte-array from the password with a PBKDF
  3. Supply the key schedule with the derived key byte-array.
us flag
"The user's password should be processed with a PBKDF to derive the key." Gotcha. Thanks. Its just that the book didn't seem to go into this as far as I can tell.
Maarten Bodewes avatar
in flag
What is the title of "the book"? The way an AES key is generated or derived is not part of the AES algorithm itself...
us flag
@MaartenBodewes "The Design of Rijndael" in chapter 3 where the key schedule is laid out. But also FIPS 197. It's totally fine if it isn't part of AES itself but that would explain why it isn't mention and why I wasn't certain. :D
@mirkaim I suspect most symmetric keys are not derived from user passwords at all. They are either generated from some asymmetric key-agreement protocol (for example TLS) or randomly generated (hopefully from a cryptographically secure random number generator), and then protected by encrypting with some other key.
Score:5
in flag

It looks like this key already has the requisite number of 32 bit words for 128 or 192 (since this is the key expansion for 6 columns or less) but how would you get that from a user's random length password?

Passwords are not keys by themselves.

To derive a key from a password you'd use a Password Based Key Derivation Function. You could use functions such as PBKDF2, Argon2 or Balloon hashing. Other well known algorithms are bcrypt and scrypt.

Would PKCS7 have already been run so that the key is padded?

No, PKCS#7 compatible padding is what you run on the plaintext (or - when implemented efficiently - on the block-sized buffer that is used for encryption / decryption during the last encryption operation). The key doesn't need a padding method when generated / derived correctly; it should always have the right size - and otherwise zero padding would just work fine.

Is this showing that the user's actual entered key is part of the key schedule or are all keys in the schedule derived from the user's actual raw input key?

Symmetric keys consist of bits / bytes. So an AES key consist of 128, 192 or 256 bits / 16, 24 or 32 bits respectively. Anything other than that is not an AES key. A string is generally not considered a key, although it could be a hex or base64 encoding of a key. If it is a string of any size then it is generally considered a password instead.

As for the key schedule internal to AES: No, the first round(s) can very well use the original input key. As you can see the value of j does not start with j. This makes sense, the key schedule makes sure that the subkeys are sufficiently different, so that information of a later subkey doesn't present any information about an earlier subkey.

us flag
Got it. Thanks a lot.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.