Commit 5427663f authored by Sebastian Siewior's avatar Sebastian Siewior Committed by Herbert Xu

[CRYPTO] aes: Export generic setkey

The key expansion routine could be get little more generic, become
a kernel doc entry and then get exported.
Signed-off-by: default avatarSebastian Siewior <sebastian@breakpoint.cc>
Tested-by: default avatarStefan Hellermann <stefan@the2masters.de>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent c3715cb9
...@@ -229,18 +229,29 @@ static void __init gen_tabs(void) ...@@ -229,18 +229,29 @@ static void __init gen_tabs(void)
ctx->key_enc[8 * i + 15] = t; \ ctx->key_enc[8 * i + 15] = t; \
} while (0) } 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) unsigned int key_len)
{ {
struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm);
const __le32 *key = (const __le32 *)in_key; const __le32 *key = (const __le32 *)in_key;
u32 *flags = &tfm->crt_flags;
u32 i, t, u, v, w, j; u32 i, t, u, v, w, j;
if (key_len % 8) { if (key_len != AES_KEYSIZE_128 && key_len != AES_KEYSIZE_192 &&
*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; key_len != AES_KEYSIZE_256)
return -EINVAL; return -EINVAL;
}
ctx->key_length = key_len; ctx->key_length = key_len;
...@@ -250,20 +261,20 @@ int crypto_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, ...@@ -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]); ctx->key_dec[key_len + 27] = ctx->key_enc[3] = le32_to_cpu(key[3]);
switch (key_len) { switch (key_len) {
case 16: case AES_KEYSIZE_128:
t = ctx->key_enc[3]; t = ctx->key_enc[3];
for (i = 0; i < 10; ++i) for (i = 0; i < 10; ++i)
loop4(i); loop4(i);
break; break;
case 24: case AES_KEYSIZE_192:
ctx->key_enc[4] = le32_to_cpu(key[4]); ctx->key_enc[4] = le32_to_cpu(key[4]);
t = ctx->key_enc[5] = le32_to_cpu(key[5]); t = ctx->key_enc[5] = le32_to_cpu(key[5]);
for (i = 0; i < 8; ++i) for (i = 0; i < 8; ++i)
loop6(i); loop6(i);
break; break;
case 32: case AES_KEYSIZE_256:
ctx->key_enc[4] = le32_to_cpu(key[4]); ctx->key_enc[4] = le32_to_cpu(key[4]);
ctx->key_enc[5] = le32_to_cpu(key[5]); ctx->key_enc[5] = le32_to_cpu(key[5]);
ctx->key_enc[6] = le32_to_cpu(key[6]); 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, ...@@ -284,6 +295,33 @@ int crypto_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
} }
return 0; 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); EXPORT_SYMBOL_GPL(crypto_aes_set_key);
/* encrypt a block of text */ /* encrypt a block of text */
......
...@@ -14,11 +14,13 @@ ...@@ -14,11 +14,13 @@
#define AES_KEYSIZE_192 24 #define AES_KEYSIZE_192 24
#define AES_KEYSIZE_256 32 #define AES_KEYSIZE_256 32
#define AES_BLOCK_SIZE 16 #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 { struct crypto_aes_ctx {
u32 key_length; u32 key_length;
u32 key_enc[60]; u32 key_enc[AES_MAX_KEYLENGTH_U32];
u32 key_dec[60]; u32 key_dec[AES_MAX_KEYLENGTH_U32];
}; };
extern u32 crypto_ft_tab[4][256]; extern u32 crypto_ft_tab[4][256];
...@@ -28,4 +30,6 @@ extern u32 crypto_il_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, int crypto_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
unsigned int key_len); unsigned int key_len);
int crypto_aes_expand_key(struct crypto_aes_ctx *ctx, const u8 *in_key,
unsigned int key_len);
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment