History

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().

Eric Biggers committed 6 years ago

Commit e8cfed51 parent c441a904 files · +43 −114Browse files

Unified · Split

4 files
  1. crypto/api.c +1 −14
  2. crypto/cipher.c +36 −56
  3. crypto/internal.h +0 −2
  4. include/linux/crypto.h +6 −42
crypto/api.c+1−14
@@ -295,20 +295,7 @@ static int crypto_init_ops(struct crypto_tfm *tfm, u32 type, u32 mask) · 294 unmodified lines
295 295
296 if (type_obj)296 if (type_obj)
297 return type_obj->init(tfm, type, mask);297 return type_obj->init(tfm, type, mask);
298 298 return 0;
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;
312}299}
313 300
314static void crypto_exit_ops(struct crypto_tfm *tfm)301static void crypto_exit_ops(struct crypto_tfm *tfm)
crypto/cipher.c+36−56
@@ -2,7 +2,7 @@ · 1 unmodified line
2/*2/*
3 * Cryptographic API.3 * Cryptographic API.
4 *4 *
5 * Cipher operations.5 * Single-block cipher operations.
6 *6 *
7 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>7 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
8 * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au>8 * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au>
@@ -16,11 +16,11 @@ · 7 unmodified lines
16#include <linux/string.h>16#include <linux/string.h>
17#include "internal.h"17#include "internal.h"
18 18
19static int setkey_unaligned(struct crypto_tfm *tfm, const u8 *key,19static int setkey_unaligned(struct crypto_cipher *tfm, const u8 *key,
20 unsigned int keylen)20 unsigned int keylen)
21{21{
22 struct cipher_alg *cia = &tfm->__crt_alg->cra_cipher;22 struct cipher_alg *cia = crypto_cipher_alg(tfm);
23 unsigned long alignmask = crypto_tfm_alg_alignmask(tfm);23 unsigned long alignmask = crypto_cipher_alignmask(tfm);
24 int ret;24 int ret;
25 u8 *buffer, *alignbuffer;25 u8 *buffer, *alignbuffer;
26 unsigned long absize;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 alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);33 alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
34 memcpy(alignbuffer, key, keylen);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 memset(alignbuffer, 0, keylen);36 memset(alignbuffer, 0, keylen);
37 kfree(buffer);37 kfree(buffer);
38 return ret;38 return ret;
39 39
40}40}
41 41
42static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)42int 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 struct cipher_alg *cia = crypto_cipher_alg(tfm);
45 unsigned long alignmask = crypto_tfm_alg_alignmask(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 if (keylen < cia->cia_min_keysize || keylen > cia->cia_max_keysize) {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 return -EINVAL;51 return -EINVAL;
51 }52 }
52 53
53 if ((unsigned long)key & alignmask)54 if ((unsigned long)key & alignmask)
54 return setkey_unaligned(tfm, key, keylen);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}
59EXPORT_SYMBOL_GPL(crypto_cipher_setkey);
58 60
59static void cipher_crypt_unaligned(void (*fn)(struct crypto_tfm *, u8 *,61static inline void cipher_crypt_one(struct crypto_cipher *tfm,
60 const u8 *),62 u8 *dst, const u8 *src, bool enc)
61 struct crypto_tfm *tfm,
62 u8 *dst, const u8 *src)
63{63{
64 unsigned long alignmask = crypto_tfm_alg_alignmask(tfm);64 unsigned long alignmask = crypto_cipher_alignmask(tfm);
65 unsigned int size = crypto_tfm_alg_blocksize(tfm);65 struct cipher_alg *cia = crypto_cipher_alg(tfm);
66 u8 buffer[MAX_CIPHER_BLOCKSIZE + MAX_CIPHER_ALIGNMASK];66 void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
67 u8 *tmp = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);67 enc ? cia->cia_encrypt : cia->cia_decrypt;
68
69 memcpy(tmp, src, size);
70 fn(tfm, tmp, tmp);
71 memcpy(dst, tmp, size);
72}
73
74static 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;
79 68
80 if (unlikely(((unsigned long)dst | (unsigned long)src) & alignmask)) {69 if (unlikely(((unsigned long)dst | (unsigned long)src) & alignmask)) {
81 cipher_crypt_unaligned(cipher->cia_encrypt, tfm, dst, src);70 unsigned int bs = crypto_cipher_blocksize(tfm);
82 return;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
88static void cipher_decrypt_unaligned(struct crypto_tfm *tfm,82void crypto_cipher_encrypt_one(struct crypto_cipher *tfm,
89 u8 *dst, const u8 *src)83 u8 *dst, const u8 *src)
90{84{
91 unsigned long alignmask = crypto_tfm_alg_alignmask(tfm);85 cipher_crypt_one(tfm, dst, src, true);
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);
100}86}
87EXPORT_SYMBOL_GPL(crypto_cipher_encrypt_one);
101 88
102int crypto_init_cipher_ops(struct crypto_tfm *tfm)89void crypto_cipher_decrypt_one(struct crypto_cipher *tfm,
90 u8 *dst, const u8 *src)
103{91{
104 struct cipher_tfm *ops = &tfm->crt_cipher;92 cipher_crypt_one(tfm, dst, src, false);
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;
114}93}
94EXPORT_SYMBOL_GPL(crypto_cipher_decrypt_one);
crypto/internal.h+0−2
@@ -58,8 +58,6 @@ static inline unsigned int crypto_compress_ctxsize(struct crypto_alg *alg) · 57 unmodified lines
58struct crypto_alg *crypto_mod_get(struct crypto_alg *alg);58struct crypto_alg *crypto_mod_get(struct crypto_alg *alg);
59struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask);59struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask);
60 60
61int crypto_init_cipher_ops(struct crypto_tfm *tfm);
62
63struct crypto_larval *crypto_larval_alloc(const char *name, u32 type, u32 mask);61struct crypto_larval *crypto_larval_alloc(const char *name, u32 type, u32 mask);
64void crypto_larval_kill(struct crypto_alg *alg);62void crypto_larval_kill(struct crypto_alg *alg);
65void crypto_alg_tested(const char *name, int err);63void crypto_alg_tested(const char *name, int err);
include/linux/crypto.h+6−42
@@ -599,23 +599,10 @@ int crypto_has_alg(const char *name, u32 type, u32 mask); · 598 unmodified lines
599 * crypto_free_*(), as well as the various helpers below.599 * crypto_free_*(), as well as the various helpers below.
600 */600 */
601 601
602struct 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
611struct crypto_tfm {602struct crypto_tfm {
612 603
613 u32 crt_flags;604 u32 crt_flags;
614 605
615 union {
616 struct cipher_tfm cipher;
617 } crt_u;
618
619 void (*exit)(struct crypto_tfm *tfm);606 void (*exit)(struct crypto_tfm *tfm);
620 607
621 struct crypto_alg *__crt_alg;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 return (struct crypto_cipher *)tfm;739 return (struct crypto_cipher *)tfm;
753}740}
754 741
755static 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 * crypto_alloc_cipher() - allocate single block cipher handle743 * crypto_alloc_cipher() - allocate single block cipher handle
763 * @alg_name: is the cra_name / name or cra_driver_name / driver name of the744 * @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 return crypto_has_alg(alg_name, type, mask);796 return crypto_has_alg(alg_name, type, mask);
816}797}
817 798
818static 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 * crypto_cipher_blocksize() - obtain block size for cipher800 * crypto_cipher_blocksize() - obtain block size for cipher
825 * @tfm: cipher handle801 * @tfm: cipher handle
@@ -873,12 +849,8 @@ static inline void crypto_cipher_clear_flags(struct crypto_cipher *tfm, · 47 unmodified lines
873 *849 *
874 * Return: 0 if the setting of the key was successful; < 0 if an error occurred850 * Return: 0 if the setting of the key was successful; < 0 if an error occurred
875 */851 */
876static inline int crypto_cipher_setkey(struct crypto_cipher *tfm,852int crypto_cipher_setkey(struct crypto_cipher *tfm,
877 const u8 *key, unsigned int keylen)853 const u8 *key, unsigned int keylen);
878{
879 return crypto_cipher_crt(tfm)->cit_setkey(crypto_cipher_tfm(tfm),
880 key, keylen);
881}
882 854
883/**855/**
884 * crypto_cipher_encrypt_one() - encrypt one block of plaintext856 * 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 * Invoke the encryption operation of one block. The caller must ensure that861 * Invoke the encryption operation of one block. The caller must ensure that
890 * the plaintext and ciphertext buffers are at least one block in size.862 * the plaintext and ciphertext buffers are at least one block in size.
891 */863 */
892static inline void crypto_cipher_encrypt_one(struct crypto_cipher *tfm,864void crypto_cipher_encrypt_one(struct crypto_cipher *tfm,
893 u8 *dst, const u8 *src)865 u8 *dst, const u8 *src);
894{
895 crypto_cipher_crt(tfm)->cit_encrypt_one(crypto_cipher_tfm(tfm),
896 dst, src);
897}
898 866
899/**867/**
900 * crypto_cipher_decrypt_one() - decrypt one block of ciphertext868 * 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 * Invoke the decryption operation of one block. The caller must ensure that873 * Invoke the decryption operation of one block. The caller must ensure that
906 * the plaintext and ciphertext buffers are at least one block in size.874 * the plaintext and ciphertext buffers are at least one block in size.
907 */875 */
908static inline void crypto_cipher_decrypt_one(struct crypto_cipher *tfm,876void crypto_cipher_decrypt_one(struct crypto_cipher *tfm,
909 u8 *dst, const u8 *src)877 u8 *dst, const u8 *src);
910{
911 crypto_cipher_crt(tfm)->cit_decrypt_one(crypto_cipher_tfm(tfm),
912 dst, src);
913}
914 878
915static inline struct crypto_comp *__crypto_comp_cast(struct crypto_tfm *tfm)879static inline struct crypto_comp *__crypto_comp_cast(struct crypto_tfm *tfm)
916{880{

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t