forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
crypto: cipher - remove crt_u.cipher (struct cipher_tfm)
Of the three fields in crt_u.cipher (struct cipher_tfm), ->cit_setkey() is pointless because it always points to setkey() in crypto/cipher.c. ->cit_decrypt_one() and ->cit_encrypt_one() are slightly less pointless, since if the algorithm doesn't have an alignmask, they are set directly to ->cia_encrypt() and ->cia_decrypt(). However, this "optimization" isn't worthwhile because: - The "cipher" algorithm type is the only algorithm still using crt_u, so it's bloating every struct crypto_tfm for every algorithm type. - If the algorithm has an alignmask, this "optimization" actually makes things slower, as it causes 2 indirect calls per block rather than 1. - It adds extra code complexity. - Some templates already call ->cia_encrypt()/->cia_decrypt() directly instead of going through ->cit_encrypt_one()/->cit_decrypt_one(). - The "cipher" algorithm type never gives optimal performance anyway. For that, a higher-level type such as skcipher needs to be used. Therefore, just remove the extra indirection, and make crypto_cipher_setkey(), crypto_cipher_encrypt_one(), and crypto_cipher_decrypt_one() be direct calls into crypto/cipher.c. Also remove the unused function crypto_cipher_cast(). Signed-off-by: Eric Biggers <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
- Loading branch information
Showing
4 changed files
with
43 additions
and
114 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,7 @@ | |
/* | ||
* Cryptographic API. | ||
* | ||
* Cipher operations. | ||
* Single-block cipher operations. | ||
* | ||
* Copyright (c) 2002 James Morris <[email protected]> | ||
* Copyright (c) 2005 Herbert Xu <[email protected]> | ||
|
@@ -16,11 +16,11 @@ | |
#include <linux/string.h> | ||
#include "internal.h" | ||
|
||
static int setkey_unaligned(struct crypto_tfm *tfm, const u8 *key, | ||
static int setkey_unaligned(struct crypto_cipher *tfm, const u8 *key, | ||
unsigned int keylen) | ||
{ | ||
struct cipher_alg *cia = &tfm->__crt_alg->cra_cipher; | ||
unsigned long alignmask = crypto_tfm_alg_alignmask(tfm); | ||
struct cipher_alg *cia = crypto_cipher_alg(tfm); | ||
unsigned long alignmask = crypto_cipher_alignmask(tfm); | ||
int ret; | ||
u8 *buffer, *alignbuffer; | ||
unsigned long absize; | ||
|
@@ -32,83 +32,63 @@ static int setkey_unaligned(struct crypto_tfm *tfm, const u8 *key, | |
|
||
alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); | ||
memcpy(alignbuffer, key, keylen); | ||
ret = cia->cia_setkey(tfm, alignbuffer, keylen); | ||
ret = cia->cia_setkey(crypto_cipher_tfm(tfm), alignbuffer, keylen); | ||
memset(alignbuffer, 0, keylen); | ||
kfree(buffer); | ||
return ret; | ||
|
||
} | ||
|
||
static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) | ||
int crypto_cipher_setkey(struct crypto_cipher *tfm, | ||
const u8 *key, unsigned int keylen) | ||
{ | ||
struct cipher_alg *cia = &tfm->__crt_alg->cra_cipher; | ||
unsigned long alignmask = crypto_tfm_alg_alignmask(tfm); | ||
struct cipher_alg *cia = crypto_cipher_alg(tfm); | ||
unsigned long alignmask = crypto_cipher_alignmask(tfm); | ||
|
||
tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK; | ||
crypto_cipher_clear_flags(tfm, CRYPTO_TFM_RES_MASK); | ||
if (keylen < cia->cia_min_keysize || keylen > cia->cia_max_keysize) { | ||
tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; | ||
crypto_cipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); | ||
return -EINVAL; | ||
} | ||
|
||
if ((unsigned long)key & alignmask) | ||
return setkey_unaligned(tfm, key, keylen); | ||
|
||
return cia->cia_setkey(tfm, key, keylen); | ||
return cia->cia_setkey(crypto_cipher_tfm(tfm), key, keylen); | ||
} | ||
EXPORT_SYMBOL_GPL(crypto_cipher_setkey); | ||
|
||
static void cipher_crypt_unaligned(void (*fn)(struct crypto_tfm *, u8 *, | ||
const u8 *), | ||
struct crypto_tfm *tfm, | ||
u8 *dst, const u8 *src) | ||
static inline void cipher_crypt_one(struct crypto_cipher *tfm, | ||
u8 *dst, const u8 *src, bool enc) | ||
{ | ||
unsigned long alignmask = crypto_tfm_alg_alignmask(tfm); | ||
unsigned int size = crypto_tfm_alg_blocksize(tfm); | ||
u8 buffer[MAX_CIPHER_BLOCKSIZE + MAX_CIPHER_ALIGNMASK]; | ||
u8 *tmp = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); | ||
|
||
memcpy(tmp, src, size); | ||
fn(tfm, tmp, tmp); | ||
memcpy(dst, tmp, size); | ||
} | ||
|
||
static void cipher_encrypt_unaligned(struct crypto_tfm *tfm, | ||
u8 *dst, const u8 *src) | ||
{ | ||
unsigned long alignmask = crypto_tfm_alg_alignmask(tfm); | ||
struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; | ||
unsigned long alignmask = crypto_cipher_alignmask(tfm); | ||
struct cipher_alg *cia = crypto_cipher_alg(tfm); | ||
void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = | ||
enc ? cia->cia_encrypt : cia->cia_decrypt; | ||
|
||
if (unlikely(((unsigned long)dst | (unsigned long)src) & alignmask)) { | ||
cipher_crypt_unaligned(cipher->cia_encrypt, tfm, dst, src); | ||
return; | ||
unsigned int bs = crypto_cipher_blocksize(tfm); | ||
u8 buffer[MAX_CIPHER_BLOCKSIZE + MAX_CIPHER_ALIGNMASK]; | ||
u8 *tmp = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); | ||
|
||
memcpy(tmp, src, bs); | ||
fn(crypto_cipher_tfm(tfm), tmp, tmp); | ||
memcpy(dst, tmp, bs); | ||
} else { | ||
fn(crypto_cipher_tfm(tfm), dst, src); | ||
} | ||
|
||
cipher->cia_encrypt(tfm, dst, src); | ||
} | ||
|
||
static void cipher_decrypt_unaligned(struct crypto_tfm *tfm, | ||
u8 *dst, const u8 *src) | ||
void crypto_cipher_encrypt_one(struct crypto_cipher *tfm, | ||
u8 *dst, const u8 *src) | ||
{ | ||
unsigned long alignmask = crypto_tfm_alg_alignmask(tfm); | ||
struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; | ||
|
||
if (unlikely(((unsigned long)dst | (unsigned long)src) & alignmask)) { | ||
cipher_crypt_unaligned(cipher->cia_decrypt, tfm, dst, src); | ||
return; | ||
} | ||
|
||
cipher->cia_decrypt(tfm, dst, src); | ||
cipher_crypt_one(tfm, dst, src, true); | ||
} | ||
EXPORT_SYMBOL_GPL(crypto_cipher_encrypt_one); | ||
|
||
int crypto_init_cipher_ops(struct crypto_tfm *tfm) | ||
void crypto_cipher_decrypt_one(struct crypto_cipher *tfm, | ||
u8 *dst, const u8 *src) | ||
{ | ||
struct cipher_tfm *ops = &tfm->crt_cipher; | ||
struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; | ||
|
||
ops->cit_setkey = setkey; | ||
ops->cit_encrypt_one = crypto_tfm_alg_alignmask(tfm) ? | ||
cipher_encrypt_unaligned : cipher->cia_encrypt; | ||
ops->cit_decrypt_one = crypto_tfm_alg_alignmask(tfm) ? | ||
cipher_decrypt_unaligned : cipher->cia_decrypt; | ||
|
||
return 0; | ||
cipher_crypt_one(tfm, dst, src, false); | ||
} | ||
EXPORT_SYMBOL_GPL(crypto_cipher_decrypt_one); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters