diff options
| author | Herbert Xu <herbert@gondor.apana.org.au> | 2005-07-06 16:52:43 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2005-07-06 16:52:43 -0400 |
| commit | 28e8c3ad9464de54a632f00ab3df88fa5f4652d1 (patch) | |
| tree | ba62694afc67bcd6dc817d137e8259cb526a51c6 | |
| parent | 6789b2dc455b90efc9c88886c9366adc9abb7347 (diff) | |
[PADLOCK] Implement multi-block operations
By operating on multiple blocks at once, we expect to extract more
performance out of the VIA Padlock.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | drivers/crypto/padlock-aes.c | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index 5f28909d4012..d2745ff4699c 100644 --- a/drivers/crypto/padlock-aes.c +++ b/drivers/crypto/padlock-aes.c | |||
| @@ -390,7 +390,7 @@ aes_set_key(void *ctx_arg, const uint8_t *in_key, unsigned int key_len, uint32_t | |||
| 390 | 390 | ||
| 391 | /* ====== Encryption/decryption routines ====== */ | 391 | /* ====== Encryption/decryption routines ====== */ |
| 392 | 392 | ||
| 393 | /* This is the real call to PadLock. */ | 393 | /* These are the real call to PadLock. */ |
| 394 | static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key, | 394 | static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key, |
| 395 | void *control_word, u32 count) | 395 | void *control_word, u32 count) |
| 396 | { | 396 | { |
| @@ -400,6 +400,17 @@ static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key, | |||
| 400 | : "d"(control_word), "b"(key), "c"(count)); | 400 | : "d"(control_word), "b"(key), "c"(count)); |
| 401 | } | 401 | } |
| 402 | 402 | ||
| 403 | static inline void padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key, | ||
| 404 | u8 *iv, void *control_word, u32 count) | ||
| 405 | { | ||
| 406 | /* Enforce key reload. */ | ||
| 407 | asm volatile ("pushfl; popfl"); | ||
| 408 | /* rep xcryptcbc */ | ||
| 409 | asm volatile (".byte 0xf3,0x0f,0xa7,0xd0" | ||
| 410 | : "+S" (input), "+D" (output), "+a" (iv) | ||
| 411 | : "d" (control_word), "b" (key), "c" (count)); | ||
| 412 | } | ||
| 413 | |||
| 403 | static void | 414 | static void |
| 404 | aes_encrypt(void *ctx_arg, uint8_t *out, const uint8_t *in) | 415 | aes_encrypt(void *ctx_arg, uint8_t *out, const uint8_t *in) |
| 405 | { | 416 | { |
| @@ -414,6 +425,42 @@ aes_decrypt(void *ctx_arg, uint8_t *out, const uint8_t *in) | |||
| 414 | padlock_xcrypt_ecb(in, out, ctx->D, &ctx->cword.decrypt, 1); | 425 | padlock_xcrypt_ecb(in, out, ctx->D, &ctx->cword.decrypt, 1); |
| 415 | } | 426 | } |
| 416 | 427 | ||
| 428 | static unsigned int aes_encrypt_ecb(const struct cipher_desc *desc, u8 *out, | ||
| 429 | const u8 *in, unsigned int nbytes) | ||
| 430 | { | ||
| 431 | struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm)); | ||
| 432 | padlock_xcrypt_ecb(in, out, ctx->E, &ctx->cword.encrypt, | ||
| 433 | nbytes / AES_BLOCK_SIZE); | ||
| 434 | return nbytes & ~(AES_BLOCK_SIZE - 1); | ||
| 435 | } | ||
| 436 | |||
| 437 | static unsigned int aes_decrypt_ecb(const struct cipher_desc *desc, u8 *out, | ||
| 438 | const u8 *in, unsigned int nbytes) | ||
| 439 | { | ||
| 440 | struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm)); | ||
| 441 | padlock_xcrypt_ecb(in, out, ctx->D, &ctx->cword.decrypt, | ||
| 442 | nbytes / AES_BLOCK_SIZE); | ||
| 443 | return nbytes & ~(AES_BLOCK_SIZE - 1); | ||
| 444 | } | ||
| 445 | |||
| 446 | static unsigned int aes_encrypt_cbc(const struct cipher_desc *desc, u8 *out, | ||
| 447 | const u8 *in, unsigned int nbytes) | ||
| 448 | { | ||
| 449 | struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm)); | ||
| 450 | padlock_xcrypt_cbc(in, out, ctx->E, desc->info, &ctx->cword.encrypt, | ||
| 451 | nbytes / AES_BLOCK_SIZE); | ||
| 452 | return nbytes & ~(AES_BLOCK_SIZE - 1); | ||
| 453 | } | ||
| 454 | |||
| 455 | static unsigned int aes_decrypt_cbc(const struct cipher_desc *desc, u8 *out, | ||
| 456 | const u8 *in, unsigned int nbytes) | ||
| 457 | { | ||
| 458 | struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm)); | ||
| 459 | padlock_xcrypt_cbc(in, out, ctx->D, desc->info, &ctx->cword.decrypt, | ||
| 460 | nbytes / AES_BLOCK_SIZE); | ||
| 461 | return nbytes & ~(AES_BLOCK_SIZE - 1); | ||
| 462 | } | ||
| 463 | |||
| 417 | static struct crypto_alg aes_alg = { | 464 | static struct crypto_alg aes_alg = { |
| 418 | .cra_name = "aes", | 465 | .cra_name = "aes", |
| 419 | .cra_flags = CRYPTO_ALG_TYPE_CIPHER, | 466 | .cra_flags = CRYPTO_ALG_TYPE_CIPHER, |
| @@ -429,7 +476,11 @@ static struct crypto_alg aes_alg = { | |||
| 429 | .cia_max_keysize = AES_MAX_KEY_SIZE, | 476 | .cia_max_keysize = AES_MAX_KEY_SIZE, |
| 430 | .cia_setkey = aes_set_key, | 477 | .cia_setkey = aes_set_key, |
| 431 | .cia_encrypt = aes_encrypt, | 478 | .cia_encrypt = aes_encrypt, |
| 432 | .cia_decrypt = aes_decrypt | 479 | .cia_decrypt = aes_decrypt, |
| 480 | .cia_encrypt_ecb = aes_encrypt_ecb, | ||
| 481 | .cia_decrypt_ecb = aes_decrypt_ecb, | ||
| 482 | .cia_encrypt_cbc = aes_encrypt_cbc, | ||
| 483 | .cia_decrypt_cbc = aes_decrypt_cbc, | ||
| 433 | } | 484 | } |
| 434 | } | 485 | } |
| 435 | }; | 486 | }; |
