diff options
Diffstat (limited to 'crypto/aes_generic.c')
-rw-r--r-- | crypto/aes_generic.c | 56 |
1 files changed, 47 insertions, 9 deletions
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) | |||
229 | ctx->key_enc[8 * i + 15] = t; \ | 229 | ctx->key_enc[8 * i + 15] = t; \ |
230 | } while (0) | 230 | } while (0) |
231 | 231 | ||
232 | int crypto_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, | 232 | /** |
233 | * crypto_aes_expand_key - Expands the AES key as described in FIPS-197 | ||
234 | * @ctx: The location where the computed key will be stored. | ||
235 | * @in_key: The supplied key. | ||
236 | * @key_len: The length of the supplied key. | ||
237 | * | ||
238 | * Returns 0 on success. The function fails only if an invalid key size (or | ||
239 | * pointer) is supplied. | ||
240 | * The expanded key size is 240 bytes (max of 14 rounds with a unique 16 bytes | ||
241 | * key schedule plus a 16 bytes key which is used before the first round). | ||
242 | * The decryption key is prepared for the "Equivalent Inverse Cipher" as | ||
243 | * described in FIPS-197. The first slot (16 bytes) of each key (enc or dec) is | ||
244 | * for the initial combination, the second slot for the first round and so on. | ||
245 | */ | ||
246 | int crypto_aes_expand_key(struct crypto_aes_ctx *ctx, const u8 *in_key, | ||
233 | unsigned int key_len) | 247 | unsigned int key_len) |
234 | { | 248 | { |
235 | struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm); | ||
236 | const __le32 *key = (const __le32 *)in_key; | 249 | const __le32 *key = (const __le32 *)in_key; |
237 | u32 *flags = &tfm->crt_flags; | ||
238 | u32 i, t, u, v, w, j; | 250 | u32 i, t, u, v, w, j; |
239 | 251 | ||
240 | if (key_len % 8) { | 252 | if (key_len != AES_KEYSIZE_128 && key_len != AES_KEYSIZE_192 && |
241 | *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; | 253 | key_len != AES_KEYSIZE_256) |
242 | return -EINVAL; | 254 | return -EINVAL; |
243 | } | ||
244 | 255 | ||
245 | ctx->key_length = key_len; | 256 | ctx->key_length = key_len; |
246 | 257 | ||
@@ -250,20 +261,20 @@ int crypto_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, | |||
250 | ctx->key_dec[key_len + 27] = ctx->key_enc[3] = le32_to_cpu(key[3]); | 261 | ctx->key_dec[key_len + 27] = ctx->key_enc[3] = le32_to_cpu(key[3]); |
251 | 262 | ||
252 | switch (key_len) { | 263 | switch (key_len) { |
253 | case 16: | 264 | case AES_KEYSIZE_128: |
254 | t = ctx->key_enc[3]; | 265 | t = ctx->key_enc[3]; |
255 | for (i = 0; i < 10; ++i) | 266 | for (i = 0; i < 10; ++i) |
256 | loop4(i); | 267 | loop4(i); |
257 | break; | 268 | break; |
258 | 269 | ||
259 | case 24: | 270 | case AES_KEYSIZE_192: |
260 | ctx->key_enc[4] = le32_to_cpu(key[4]); | 271 | ctx->key_enc[4] = le32_to_cpu(key[4]); |
261 | t = ctx->key_enc[5] = le32_to_cpu(key[5]); | 272 | t = ctx->key_enc[5] = le32_to_cpu(key[5]); |
262 | for (i = 0; i < 8; ++i) | 273 | for (i = 0; i < 8; ++i) |
263 | loop6(i); | 274 | loop6(i); |
264 | break; | 275 | break; |
265 | 276 | ||
266 | case 32: | 277 | case AES_KEYSIZE_256: |
267 | ctx->key_enc[4] = le32_to_cpu(key[4]); | 278 | ctx->key_enc[4] = le32_to_cpu(key[4]); |
268 | ctx->key_enc[5] = le32_to_cpu(key[5]); | 279 | ctx->key_enc[5] = le32_to_cpu(key[5]); |
269 | ctx->key_enc[6] = le32_to_cpu(key[6]); | 280 | 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 | } | 295 | } |
285 | return 0; | 296 | return 0; |
286 | } | 297 | } |
298 | EXPORT_SYMBOL_GPL(crypto_aes_expand_key); | ||
299 | |||
300 | /** | ||
301 | * crypto_aes_set_key - Set the AES key. | ||
302 | * @tfm: The %crypto_tfm that is used in the context. | ||
303 | * @in_key: The input key. | ||
304 | * @key_len: The size of the key. | ||
305 | * | ||
306 | * Returns 0 on success, on failure the %CRYPTO_TFM_RES_BAD_KEY_LEN flag in tfm | ||
307 | * is set. The function uses crypto_aes_expand_key() to expand the key. | ||
308 | * &crypto_aes_ctx _must_ be the private data embedded in @tfm which is | ||
309 | * retrieved with crypto_tfm_ctx(). | ||
310 | */ | ||
311 | int crypto_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, | ||
312 | unsigned int key_len) | ||
313 | { | ||
314 | struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm); | ||
315 | u32 *flags = &tfm->crt_flags; | ||
316 | int ret; | ||
317 | |||
318 | ret = crypto_aes_expand_key(ctx, in_key, key_len); | ||
319 | if (!ret) | ||
320 | return 0; | ||
321 | |||
322 | *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; | ||
323 | return -EINVAL; | ||
324 | } | ||
287 | EXPORT_SYMBOL_GPL(crypto_aes_set_key); | 325 | EXPORT_SYMBOL_GPL(crypto_aes_set_key); |
288 | 326 | ||
289 | /* encrypt a block of text */ | 327 | /* encrypt a block of text */ |