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().
Unified · Split
| @@ -295,20 +295,7 @@ static int crypto_init_ops(struct crypto_tfm *tfm, u32 type, u32 mask) · 294 unmodified lines | ||
| 295 | 295 | |
| 296 | 296 | if (type_obj) |
| 297 | 297 | return type_obj->init(tfm, type, mask); |
| 298 | − | |
| 299 | − switch (crypto_tfm_alg_type(tfm)) { | |
| 300 | − case CRYPTO_ALG_TYPE_CIPHER: | |
| 301 | − return crypto_init_cipher_ops(tfm); | |
| 302 | − | |
| 303 | − case CRYPTO_ALG_TYPE_COMPRESS: | |
| 304 | − return 0; | |
| 305 | − | |
| 306 | − default: | |
| 307 | − break; | |
| 308 | − } | |
| 309 | − | |
| 310 | − BUG(); | |
| 311 | − return -EINVAL; | |
| 298 | + return 0; | |
| 312 | 299 | } |
| 313 | 300 | |
| 314 | 301 | static void crypto_exit_ops(struct crypto_tfm *tfm) |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | /* |
| 3 | 3 | * Cryptographic API. |
| 4 | 4 | * |
| 5 | − * Cipher operations. | |
| 5 | + * Single-block cipher operations. | |
| 6 | 6 | * |
| 7 | 7 | * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> |
| 8 | 8 | * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au> |
| @@ -16,11 +16,11 @@ · 7 unmodified lines | ||
| 16 | 16 | #include <linux/string.h> |
| 17 | 17 | #include "internal.h" |
| 18 | 18 | |
| 19 | −static int setkey_unaligned(struct crypto_tfm *tfm, const u8 *key, | |
| 19 | +static int setkey_unaligned(struct crypto_cipher *tfm, const u8 *key, | |
| 20 | 20 | unsigned int keylen) |
| 21 | 21 | { |
| 22 | − struct cipher_alg *cia = &tfm->__crt_alg->cra_cipher; | |
| 23 | − unsigned long alignmask = crypto_tfm_alg_alignmask(tfm); | |
| 22 | + struct cipher_alg *cia = crypto_cipher_alg(tfm); | |
| 23 | + unsigned long alignmask = crypto_cipher_alignmask(tfm); | |
| 24 | 24 | int ret; |
| 25 | 25 | u8 *buffer, *alignbuffer; |
| 26 | 26 | unsigned long absize; |
| @@ -32,83 +32,63 @@ static int setkey_unaligned(struct crypto_tfm *tfm, const u8 *key, · 5 unmodified lines | ||
| 32 | 32 | |
| 33 | 33 | alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); |
| 34 | 34 | memcpy(alignbuffer, key, keylen); |
| 35 | − ret = cia->cia_setkey(tfm, alignbuffer, keylen); | |
| 35 | + ret = cia->cia_setkey(crypto_cipher_tfm(tfm), alignbuffer, keylen); | |
| 36 | 36 | memset(alignbuffer, 0, keylen); |
| 37 | 37 | kfree(buffer); |
| 38 | 38 | return ret; |
| 39 | 39 | |
| 40 | 40 | } |
| 41 | 41 | |
| 42 | −static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) | |
| 42 | +int crypto_cipher_setkey(struct crypto_cipher *tfm, | |
| 43 | + const u8 *key, unsigned int keylen) | |
| 43 | 44 | { |
| 44 | − struct cipher_alg *cia = &tfm->__crt_alg->cra_cipher; | |
| 45 | − unsigned long alignmask = crypto_tfm_alg_alignmask(tfm); | |
| 45 | + struct cipher_alg *cia = crypto_cipher_alg(tfm); | |
| 46 | + unsigned long alignmask = crypto_cipher_alignmask(tfm); | |
| 46 | 47 | |
| 47 | − tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK; | |
| 48 | + crypto_cipher_clear_flags(tfm, CRYPTO_TFM_RES_MASK); | |
| 48 | 49 | if (keylen < cia->cia_min_keysize || keylen > cia->cia_max_keysize) { |
| 49 | − tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; | |
| 50 | + crypto_cipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); | |
| 50 | 51 | return -EINVAL; |
| 51 | 52 | } |
| 52 | 53 | |
| 53 | 54 | if ((unsigned long)key & alignmask) |
| 54 | 55 | return setkey_unaligned(tfm, key, keylen); |
| 55 | 56 | |
| 56 | − return cia->cia_setkey(tfm, key, keylen); | |
| 57 | + return cia->cia_setkey(crypto_cipher_tfm(tfm), key, keylen); | |
| 57 | 58 | } |
| 59 | +EXPORT_SYMBOL_GPL(crypto_cipher_setkey); | |
| 58 | 60 | |
| 59 | −static void cipher_crypt_unaligned(void (*fn)(struct crypto_tfm *, u8 *, | |
| 60 | − const u8 *), | |
| 61 | − struct crypto_tfm *tfm, | |
| 62 | − u8 *dst, const u8 *src) | |
| 61 | +static inline void cipher_crypt_one(struct crypto_cipher *tfm, | |
| 62 | + u8 *dst, const u8 *src, bool enc) | |
| 63 | 63 | { |
| 64 | − unsigned long alignmask = crypto_tfm_alg_alignmask(tfm); | |
| 65 | − unsigned int size = crypto_tfm_alg_blocksize(tfm); | |
| 66 | − u8 buffer[MAX_CIPHER_BLOCKSIZE + MAX_CIPHER_ALIGNMASK]; | |
| 67 | − u8 *tmp = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); | |
| 68 | − | |
| 69 | − memcpy(tmp, src, size); | |
| 70 | − fn(tfm, tmp, tmp); | |
| 71 | − memcpy(dst, tmp, size); | |
| 72 | −} | |
| 73 | − | |
| 74 | −static void cipher_encrypt_unaligned(struct crypto_tfm *tfm, | |
| 75 | − u8 *dst, const u8 *src) | |
| 76 | −{ | |
| 77 | − unsigned long alignmask = crypto_tfm_alg_alignmask(tfm); | |
| 78 | − struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; | |
| 64 | + unsigned long alignmask = crypto_cipher_alignmask(tfm); | |
| 65 | + struct cipher_alg *cia = crypto_cipher_alg(tfm); | |
| 66 | + void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = | |
| 67 | + enc ? cia->cia_encrypt : cia->cia_decrypt; | |
| 79 | 68 | |
| 80 | 69 | if (unlikely(((unsigned long)dst | (unsigned long)src) & alignmask)) { |
| 81 | − cipher_crypt_unaligned(cipher->cia_encrypt, tfm, dst, src); | |
| 82 | − return; | |
| 70 | + unsigned int bs = crypto_cipher_blocksize(tfm); | |
| 71 | + u8 buffer[MAX_CIPHER_BLOCKSIZE + MAX_CIPHER_ALIGNMASK]; | |
| 72 | + u8 *tmp = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); | |
| 73 | + | |
| 74 | + memcpy(tmp, src, bs); | |
| 75 | + fn(crypto_cipher_tfm(tfm), tmp, tmp); | |
| 76 | + memcpy(dst, tmp, bs); | |
| 77 | + } else { | |
| 78 | + fn(crypto_cipher_tfm(tfm), dst, src); | |
| 83 | 79 | } |
| 84 | − | |
| 85 | − cipher->cia_encrypt(tfm, dst, src); | |
| 86 | 80 | } |
| 87 | 81 | |
| 88 | −static void cipher_decrypt_unaligned(struct crypto_tfm *tfm, | |
| 89 | − u8 *dst, const u8 *src) | |
| 82 | +void crypto_cipher_encrypt_one(struct crypto_cipher *tfm, | |
| 83 | + u8 *dst, const u8 *src) | |
| 90 | 84 | { |
| 91 | − unsigned long alignmask = crypto_tfm_alg_alignmask(tfm); | |
| 92 | − struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; | |
| 93 | − | |
| 94 | − if (unlikely(((unsigned long)dst | (unsigned long)src) & alignmask)) { | |
| 95 | − cipher_crypt_unaligned(cipher->cia_decrypt, tfm, dst, src); | |
| 96 | − return; | |
| 97 | − } | |
| 98 | − | |
| 99 | − cipher->cia_decrypt(tfm, dst, src); | |
| 85 | + cipher_crypt_one(tfm, dst, src, true); | |
| 100 | 86 | } |
| 87 | +EXPORT_SYMBOL_GPL(crypto_cipher_encrypt_one); | |
| 101 | 88 | |
| 102 | −int crypto_init_cipher_ops(struct crypto_tfm *tfm) | |
| 89 | +void crypto_cipher_decrypt_one(struct crypto_cipher *tfm, | |
| 90 | + u8 *dst, const u8 *src) | |
| 103 | 91 | { |
| 104 | − struct cipher_tfm *ops = &tfm->crt_cipher; | |
| 105 | − struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; | |
| 106 | − | |
| 107 | − ops->cit_setkey = setkey; | |
| 108 | − ops->cit_encrypt_one = crypto_tfm_alg_alignmask(tfm) ? | |
| 109 | − cipher_encrypt_unaligned : cipher->cia_encrypt; | |
| 110 | − ops->cit_decrypt_one = crypto_tfm_alg_alignmask(tfm) ? | |
| 111 | − cipher_decrypt_unaligned : cipher->cia_decrypt; | |
| 112 | − | |
| 113 | − return 0; | |
| 92 | + cipher_crypt_one(tfm, dst, src, false); | |
| 114 | 93 | } |
| 94 | +EXPORT_SYMBOL_GPL(crypto_cipher_decrypt_one); | |
| @@ -58,8 +58,6 @@ static inline unsigned int crypto_compress_ctxsize(struct crypto_alg *alg) · 57 unmodified lines | ||
| 58 | 58 | struct crypto_alg *crypto_mod_get(struct crypto_alg *alg); |
| 59 | 59 | struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask); |
| 60 | 60 | |
| 61 | −int crypto_init_cipher_ops(struct crypto_tfm *tfm); | |
| 62 | − | |
| 63 | 61 | struct crypto_larval *crypto_larval_alloc(const char *name, u32 type, u32 mask); |
| 64 | 62 | void crypto_larval_kill(struct crypto_alg *alg); |
| 65 | 63 | void crypto_alg_tested(const char *name, int err); |
| @@ -599,23 +599,10 @@ int crypto_has_alg(const char *name, u32 type, u32 mask); · 598 unmodified lines | ||
| 599 | 599 | * crypto_free_*(), as well as the various helpers below. |
| 600 | 600 | */ |
| 601 | 601 | |
| 602 | −struct cipher_tfm { | |
| 603 | − int (*cit_setkey)(struct crypto_tfm *tfm, | |
| 604 | − const u8 *key, unsigned int keylen); | |
| 605 | − void (*cit_encrypt_one)(struct crypto_tfm *tfm, u8 *dst, const u8 *src); | |
| 606 | − void (*cit_decrypt_one)(struct crypto_tfm *tfm, u8 *dst, const u8 *src); | |
| 607 | −}; | |
| 608 | − | |
| 609 | −#define crt_cipher crt_u.cipher | |
| 610 | − | |
| 611 | 602 | struct crypto_tfm { |
| 612 | 603 | |
| 613 | 604 | u32 crt_flags; |
| 614 | 605 | |
| 615 | − union { | |
| 616 | − struct cipher_tfm cipher; | |
| 617 | − } crt_u; | |
| 618 | − | |
| 619 | 606 | void (*exit)(struct crypto_tfm *tfm); |
| 620 | 607 | |
| 621 | 608 | struct crypto_alg *__crt_alg; |
| @@ -752,12 +739,6 @@ static inline struct crypto_cipher *__crypto_cipher_cast(struct crypto_tfm *tfm) · 130 unmodified lines | ||
| 752 | 739 | return (struct crypto_cipher *)tfm; |
| 753 | 740 | } |
| 754 | 741 | |
| 755 | −static inline struct crypto_cipher *crypto_cipher_cast(struct crypto_tfm *tfm) | |
| 756 | −{ | |
| 757 | − BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); | |
| 758 | − return __crypto_cipher_cast(tfm); | |
| 759 | −} | |
| 760 | − | |
| 761 | 742 | /** |
| 762 | 743 | * crypto_alloc_cipher() - allocate single block cipher handle |
| 763 | 744 | * @alg_name: is the cra_name / name or cra_driver_name / driver name of the |
| @@ -815,11 +796,6 @@ static inline int crypto_has_cipher(const char *alg_name, u32 type, u32 mask) · 51 unmodified lines | ||
| 815 | 796 | return crypto_has_alg(alg_name, type, mask); |
| 816 | 797 | } |
| 817 | 798 | |
| 818 | −static inline struct cipher_tfm *crypto_cipher_crt(struct crypto_cipher *tfm) | |
| 819 | −{ | |
| 820 | − return &crypto_cipher_tfm(tfm)->crt_cipher; | |
| 821 | −} | |
| 822 | − | |
| 823 | 799 | /** |
| 824 | 800 | * crypto_cipher_blocksize() - obtain block size for cipher |
| 825 | 801 | * @tfm: cipher handle |
| @@ -873,12 +849,8 @@ static inline void crypto_cipher_clear_flags(struct crypto_cipher *tfm, · 47 unmodified lines | ||
| 873 | 849 | * |
| 874 | 850 | * Return: 0 if the setting of the key was successful; < 0 if an error occurred |
| 875 | 851 | */ |
| 876 | −static inline int crypto_cipher_setkey(struct crypto_cipher *tfm, | |
| 877 | − const u8 *key, unsigned int keylen) | |
| 878 | −{ | |
| 879 | − return crypto_cipher_crt(tfm)->cit_setkey(crypto_cipher_tfm(tfm), | |
| 880 | − key, keylen); | |
| 881 | −} | |
| 852 | +int crypto_cipher_setkey(struct crypto_cipher *tfm, | |
| 853 | + const u8 *key, unsigned int keylen); | |
| 882 | 854 | |
| 883 | 855 | /** |
| 884 | 856 | * crypto_cipher_encrypt_one() - encrypt one block of plaintext |
| @@ -889,12 +861,8 @@ static inline int crypto_cipher_setkey(struct crypto_cipher *tfm, · 4 unmodified lines | ||
| 889 | 861 | * Invoke the encryption operation of one block. The caller must ensure that |
| 890 | 862 | * the plaintext and ciphertext buffers are at least one block in size. |
| 891 | 863 | */ |
| 892 | −static inline void crypto_cipher_encrypt_one(struct crypto_cipher *tfm, | |
| 893 | − u8 *dst, const u8 *src) | |
| 894 | −{ | |
| 895 | − crypto_cipher_crt(tfm)->cit_encrypt_one(crypto_cipher_tfm(tfm), | |
| 896 | − dst, src); | |
| 897 | −} | |
| 864 | +void crypto_cipher_encrypt_one(struct crypto_cipher *tfm, | |
| 865 | + u8 *dst, const u8 *src); | |
| 898 | 866 | |
| 899 | 867 | /** |
| 900 | 868 | * crypto_cipher_decrypt_one() - decrypt one block of ciphertext |
| @@ -905,12 +873,8 @@ static inline void crypto_cipher_encrypt_one(struct crypto_cipher *tfm, · 4 unmodified lines | ||
| 905 | 873 | * Invoke the decryption operation of one block. The caller must ensure that |
| 906 | 874 | * the plaintext and ciphertext buffers are at least one block in size. |
| 907 | 875 | */ |
| 908 | −static inline void crypto_cipher_decrypt_one(struct crypto_cipher *tfm, | |
| 909 | − u8 *dst, const u8 *src) | |
| 910 | −{ | |
| 911 | − crypto_cipher_crt(tfm)->cit_decrypt_one(crypto_cipher_tfm(tfm), | |
| 912 | − dst, src); | |
| 913 | −} | |
| 876 | +void crypto_cipher_decrypt_one(struct crypto_cipher *tfm, | |
| 877 | + u8 *dst, const u8 *src); | |
| 914 | 878 | |
| 915 | 879 | static inline struct crypto_comp *__crypto_comp_cast(struct crypto_tfm *tfm) |
| 916 | 880 | { |