Commit 866cd902 authored by Herbert Xu's avatar Herbert Xu

[CRYPTO] padlock: Only reset the key once for each CBC and ECB operation

Currently we reset the key for each segment fed to the xcrypt instructions.
This patch optimises this for CBC and ECB so that we only do this once for
each encrypt/decrypt operation.
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 1c5dfe6a
...@@ -417,6 +417,11 @@ static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, ...@@ -417,6 +417,11 @@ static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
/* ====== Encryption/decryption routines ====== */ /* ====== Encryption/decryption routines ====== */
/* These are the real call to PadLock. */ /* These are the real call to PadLock. */
static inline void padlock_reset_key(void)
{
asm volatile ("pushfl; popfl");
}
static inline void padlock_xcrypt(const u8 *input, u8 *output, void *key, static inline void padlock_xcrypt(const u8 *input, u8 *output, void *key,
void *control_word) void *control_word)
{ {
...@@ -437,8 +442,6 @@ static void aes_crypt_copy(const u8 *in, u8 *out, u32 *key, struct cword *cword) ...@@ -437,8 +442,6 @@ static void aes_crypt_copy(const u8 *in, u8 *out, u32 *key, struct cword *cword)
static inline void aes_crypt(const u8 *in, u8 *out, u32 *key, static inline void aes_crypt(const u8 *in, u8 *out, u32 *key,
struct cword *cword) struct cword *cword)
{ {
asm volatile ("pushfl; popfl");
/* padlock_xcrypt requires at least two blocks of data. */ /* padlock_xcrypt requires at least two blocks of data. */
if (unlikely(!(((unsigned long)in ^ (PAGE_SIZE - AES_BLOCK_SIZE)) & if (unlikely(!(((unsigned long)in ^ (PAGE_SIZE - AES_BLOCK_SIZE)) &
(PAGE_SIZE - 1)))) { (PAGE_SIZE - 1)))) {
...@@ -457,7 +460,6 @@ static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key, ...@@ -457,7 +460,6 @@ static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key,
return; return;
} }
asm volatile ("pushfl; popfl"); /* enforce key reload. */
asm volatile ("test $1, %%cl;" asm volatile ("test $1, %%cl;"
"je 1f;" "je 1f;"
"lea -1(%%ecx), %%eax;" "lea -1(%%ecx), %%eax;"
...@@ -474,8 +476,6 @@ static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key, ...@@ -474,8 +476,6 @@ static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key,
static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key, static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key,
u8 *iv, void *control_word, u32 count) u8 *iv, void *control_word, u32 count)
{ {
/* Enforce key reload. */
asm volatile ("pushfl; popfl");
/* rep xcryptcbc */ /* rep xcryptcbc */
asm volatile (".byte 0xf3,0x0f,0xa7,0xd0" asm volatile (".byte 0xf3,0x0f,0xa7,0xd0"
: "+S" (input), "+D" (output), "+a" (iv) : "+S" (input), "+D" (output), "+a" (iv)
...@@ -486,12 +486,14 @@ static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key, ...@@ -486,12 +486,14 @@ static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key,
static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{ {
struct aes_ctx *ctx = aes_ctx(tfm); struct aes_ctx *ctx = aes_ctx(tfm);
padlock_reset_key();
aes_crypt(in, out, ctx->E, &ctx->cword.encrypt); aes_crypt(in, out, ctx->E, &ctx->cword.encrypt);
} }
static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{ {
struct aes_ctx *ctx = aes_ctx(tfm); struct aes_ctx *ctx = aes_ctx(tfm);
padlock_reset_key();
aes_crypt(in, out, ctx->D, &ctx->cword.decrypt); aes_crypt(in, out, ctx->D, &ctx->cword.decrypt);
} }
...@@ -524,6 +526,8 @@ static int ecb_aes_encrypt(struct blkcipher_desc *desc, ...@@ -524,6 +526,8 @@ static int ecb_aes_encrypt(struct blkcipher_desc *desc,
struct blkcipher_walk walk; struct blkcipher_walk walk;
int err; int err;
padlock_reset_key();
blkcipher_walk_init(&walk, dst, src, nbytes); blkcipher_walk_init(&walk, dst, src, nbytes);
err = blkcipher_walk_virt(desc, &walk); err = blkcipher_walk_virt(desc, &walk);
...@@ -546,6 +550,8 @@ static int ecb_aes_decrypt(struct blkcipher_desc *desc, ...@@ -546,6 +550,8 @@ static int ecb_aes_decrypt(struct blkcipher_desc *desc,
struct blkcipher_walk walk; struct blkcipher_walk walk;
int err; int err;
padlock_reset_key();
blkcipher_walk_init(&walk, dst, src, nbytes); blkcipher_walk_init(&walk, dst, src, nbytes);
err = blkcipher_walk_virt(desc, &walk); err = blkcipher_walk_virt(desc, &walk);
...@@ -590,6 +596,8 @@ static int cbc_aes_encrypt(struct blkcipher_desc *desc, ...@@ -590,6 +596,8 @@ static int cbc_aes_encrypt(struct blkcipher_desc *desc,
struct blkcipher_walk walk; struct blkcipher_walk walk;
int err; int err;
padlock_reset_key();
blkcipher_walk_init(&walk, dst, src, nbytes); blkcipher_walk_init(&walk, dst, src, nbytes);
err = blkcipher_walk_virt(desc, &walk); err = blkcipher_walk_virt(desc, &walk);
...@@ -614,6 +622,8 @@ static int cbc_aes_decrypt(struct blkcipher_desc *desc, ...@@ -614,6 +622,8 @@ static int cbc_aes_decrypt(struct blkcipher_desc *desc,
struct blkcipher_walk walk; struct blkcipher_walk walk;
int err; int err;
padlock_reset_key();
blkcipher_walk_init(&walk, dst, src, nbytes); blkcipher_walk_init(&walk, dst, src, nbytes);
err = blkcipher_walk_virt(desc, &walk); err = blkcipher_walk_virt(desc, &walk);
......
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