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: Herbert Xu <herbert@gondor.apana.org.au>
/* ====== Encryption/decryption routines ====== */
/* These are the real call to PadLock. */
/* ====== Encryption/decryption routines ====== */
/* 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,
void *control_word)
{
static inline void padlock_xcrypt(const u8 *input, u8 *output, void *key,
void *control_word)
{
static inline void aes_crypt(const u8 *in, u8 *out, u32 *key,
struct cword *cword)
{
static inline void aes_crypt(const u8 *in, u8 *out, u32 *key,
struct cword *cword)
{
- asm volatile ("pushfl; popfl");
-
/* padlock_xcrypt requires at least two blocks of data. */
if (unlikely(!(((unsigned long)in ^ (PAGE_SIZE - AES_BLOCK_SIZE)) &
(PAGE_SIZE - 1)))) {
/* padlock_xcrypt requires at least two blocks of data. */
if (unlikely(!(((unsigned long)in ^ (PAGE_SIZE - AES_BLOCK_SIZE)) &
(PAGE_SIZE - 1)))) {
- asm volatile ("pushfl; popfl"); /* enforce key reload. */
asm volatile ("test $1, %%cl;"
"je 1f;"
"lea -1(%%ecx), %%eax;"
asm volatile ("test $1, %%cl;"
"je 1f;"
"lea -1(%%ecx), %%eax;"
static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key,
u8 *iv, void *control_word, u32 count)
{
static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key,
u8 *iv, void *control_word, u32 count)
{
- /* Enforce key reload. */
- asm volatile ("pushfl; popfl");
/* rep xcryptcbc */
asm volatile (".byte 0xf3,0x0f,0xa7,0xd0"
: "+S" (input), "+D" (output), "+a" (iv)
/* rep xcryptcbc */
asm volatile (".byte 0xf3,0x0f,0xa7,0xd0"
: "+S" (input), "+D" (output), "+a" (iv)
static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
struct aes_ctx *ctx = aes_ctx(tfm);
static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
struct aes_ctx *ctx = aes_ctx(tfm);
aes_crypt(in, out, ctx->E, &ctx->cword.encrypt);
}
static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
struct aes_ctx *ctx = aes_ctx(tfm);
aes_crypt(in, out, ctx->E, &ctx->cword.encrypt);
}
static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
struct aes_ctx *ctx = aes_ctx(tfm);
aes_crypt(in, out, ctx->D, &ctx->cword.decrypt);
}
aes_crypt(in, out, ctx->D, &ctx->cword.decrypt);
}
struct blkcipher_walk walk;
int err;
struct blkcipher_walk walk;
int err;
blkcipher_walk_init(&walk, dst, src, nbytes);
err = blkcipher_walk_virt(desc, &walk);
blkcipher_walk_init(&walk, dst, src, nbytes);
err = blkcipher_walk_virt(desc, &walk);
struct blkcipher_walk walk;
int err;
struct blkcipher_walk walk;
int err;
blkcipher_walk_init(&walk, dst, src, nbytes);
err = blkcipher_walk_virt(desc, &walk);
blkcipher_walk_init(&walk, dst, src, nbytes);
err = blkcipher_walk_virt(desc, &walk);
struct blkcipher_walk walk;
int err;
struct blkcipher_walk walk;
int err;
blkcipher_walk_init(&walk, dst, src, nbytes);
err = blkcipher_walk_virt(desc, &walk);
blkcipher_walk_init(&walk, dst, src, nbytes);
err = blkcipher_walk_virt(desc, &walk);
struct blkcipher_walk walk;
int err;
struct blkcipher_walk walk;
int err;
blkcipher_walk_init(&walk, dst, src, nbytes);
err = blkcipher_walk_virt(desc, &walk);
blkcipher_walk_init(&walk, dst, src, nbytes);
err = blkcipher_walk_virt(desc, &walk);