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 | }; |