diff --git a/crypto/aes_generic.c b/crypto/aes_generic.c index cf30af74480f..136dc98d8a03 100644 --- a/crypto/aes_generic.c +++ b/crypto/aes_generic.c @@ -229,18 +229,29 @@ static void __init gen_tabs(void) ctx->key_enc[8 * i + 15] = t; \ } while (0) -int crypto_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, +/** + * crypto_aes_expand_key - Expands the AES key as described in FIPS-197 + * @ctx: The location where the computed key will be stored. + * @in_key: The supplied key. + * @key_len: The length of the supplied key. + * + * Returns 0 on success. The function fails only if an invalid key size (or + * pointer) is supplied. + * The expanded key size is 240 bytes (max of 14 rounds with a unique 16 bytes + * key schedule plus a 16 bytes key which is used before the first round). + * The decryption key is prepared for the "Equivalent Inverse Cipher" as + * described in FIPS-197. The first slot (16 bytes) of each key (enc or dec) is + * for the initial combination, the second slot for the first round and so on. + */ +int crypto_aes_expand_key(struct crypto_aes_ctx *ctx, const u8 *in_key, unsigned int key_len) { - struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm); const __le32 *key = (const __le32 *)in_key; - u32 *flags = &tfm->crt_flags; u32 i, t, u, v, w, j; - if (key_len % 8) { - *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + if (key_len != AES_KEYSIZE_128 && key_len != AES_KEYSIZE_192 && + key_len != AES_KEYSIZE_256) return -EINVAL; - } ctx->key_length = key_len; @@ -250,20 +261,20 @@ int crypto_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, ctx->key_dec[key_len + 27] = ctx->key_enc[3] = le32_to_cpu(key[3]); switch (key_len) { - case 16: + case AES_KEYSIZE_128: t = ctx->key_enc[3]; for (i = 0; i < 10; ++i) loop4(i); break; - case 24: + case AES_KEYSIZE_192: ctx->key_enc[4] = le32_to_cpu(key[4]); t = ctx->key_enc[5] = le32_to_cpu(key[5]); for (i = 0; i < 8; ++i) loop6(i); break; - case 32: + case AES_KEYSIZE_256: ctx->key_enc[4] = le32_to_cpu(key[4]); ctx->key_enc[5] = le32_to_cpu(key[5]); ctx->key_enc[6] = le32_to_cpu(key[6]); @@ -284,6 +295,33 @@ int crypto_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, } return 0; } +EXPORT_SYMBOL_GPL(crypto_aes_expand_key); + +/** + * crypto_aes_set_key - Set the AES key. + * @tfm: The %crypto_tfm that is used in the context. + * @in_key: The input key. + * @key_len: The size of the key. + * + * Returns 0 on success, on failure the %CRYPTO_TFM_RES_BAD_KEY_LEN flag in tfm + * is set. The function uses crypto_aes_expand_key() to expand the key. + * &crypto_aes_ctx _must_ be the private data embedded in @tfm which is + * retrieved with crypto_tfm_ctx(). + */ +int crypto_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, + unsigned int key_len) +{ + struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm); + u32 *flags = &tfm->crt_flags; + int ret; + + ret = crypto_aes_expand_key(ctx, in_key, key_len); + if (!ret) + return 0; + + *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; +} EXPORT_SYMBOL_GPL(crypto_aes_set_key); /* encrypt a block of text */ diff --git a/include/crypto/aes.h b/include/crypto/aes.h index d480b76715a8..40008d67ee3d 100644 --- a/include/crypto/aes.h +++ b/include/crypto/aes.h @@ -14,11 +14,13 @@ #define AES_KEYSIZE_192 24 #define AES_KEYSIZE_256 32 #define AES_BLOCK_SIZE 16 +#define AES_MAX_KEYLENGTH (15 * 16) +#define AES_MAX_KEYLENGTH_U32 (AES_MAX_KEYLENGTH / sizeof(u32)) struct crypto_aes_ctx { u32 key_length; - u32 key_enc[60]; - u32 key_dec[60]; + u32 key_enc[AES_MAX_KEYLENGTH_U32]; + u32 key_dec[AES_MAX_KEYLENGTH_U32]; }; extern u32 crypto_ft_tab[4][256]; @@ -28,4 +30,6 @@ extern u32 crypto_il_tab[4][256]; int crypto_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, unsigned int key_len); +int crypto_aes_expand_key(struct crypto_aes_ctx *ctx, const u8 *in_key, + unsigned int key_len); #endif