diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2005-07-06 16:51:52 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2005-07-06 16:51:52 -0400 |
commit | 40725181b74be6b0e3bdc8c05bd1e0b9873ec5cc (patch) | |
tree | abbc1057a5e0bd77385d17cfc6146617151e93bc | |
parent | c774e93e2152d0be2612739418689e6e6400f4eb (diff) |
[CRYPTO] Add support for low-level multi-block operations
This patch adds hooks for cipher algorithms to implement multi-block
ECB/CBC operations directly. This is expected to provide significant
performance boots to the VIA Padlock.
It could also be used for improving software implementations such as
AES where operating on multiple blocks at a time may enable certain
optimisations.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | crypto/cipher.c | 38 | ||||
-rw-r--r-- | crypto/internal.h | 5 | ||||
-rw-r--r-- | include/linux/crypto.h | 28 |
3 files changed, 45 insertions, 26 deletions
diff --git a/crypto/cipher.c b/crypto/cipher.c index c4243345b154..54c4a560070d 100644 --- a/crypto/cipher.c +++ b/crypto/cipher.c | |||
@@ -23,14 +23,6 @@ | |||
23 | #include "internal.h" | 23 | #include "internal.h" |
24 | #include "scatterwalk.h" | 24 | #include "scatterwalk.h" |
25 | 25 | ||
26 | struct cipher_desc { | ||
27 | struct crypto_tfm *tfm; | ||
28 | void (*crfn)(void *ctx, u8 *dst, const u8 *src); | ||
29 | unsigned int (*prfn)(const struct cipher_desc *desc, u8 *dst, | ||
30 | const u8 *src, unsigned int nbytes); | ||
31 | void *info; | ||
32 | }; | ||
33 | |||
34 | static inline void xor_64(u8 *a, const u8 *b) | 26 | static inline void xor_64(u8 *a, const u8 *b) |
35 | { | 27 | { |
36 | ((u32 *)a)[0] ^= ((u32 *)b)[0]; | 28 | ((u32 *)a)[0] ^= ((u32 *)b)[0]; |
@@ -224,10 +216,11 @@ static int ecb_encrypt(struct crypto_tfm *tfm, | |||
224 | struct scatterlist *src, unsigned int nbytes) | 216 | struct scatterlist *src, unsigned int nbytes) |
225 | { | 217 | { |
226 | struct cipher_desc desc; | 218 | struct cipher_desc desc; |
219 | struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; | ||
227 | 220 | ||
228 | desc.tfm = tfm; | 221 | desc.tfm = tfm; |
229 | desc.crfn = tfm->__crt_alg->cra_cipher.cia_encrypt; | 222 | desc.crfn = cipher->cia_encrypt; |
230 | desc.prfn = ecb_process; | 223 | desc.prfn = cipher->cia_encrypt_ecb ?: ecb_process; |
231 | 224 | ||
232 | return crypt(&desc, dst, src, nbytes); | 225 | return crypt(&desc, dst, src, nbytes); |
233 | } | 226 | } |
@@ -238,10 +231,11 @@ static int ecb_decrypt(struct crypto_tfm *tfm, | |||
238 | unsigned int nbytes) | 231 | unsigned int nbytes) |
239 | { | 232 | { |
240 | struct cipher_desc desc; | 233 | struct cipher_desc desc; |
234 | struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; | ||
241 | 235 | ||
242 | desc.tfm = tfm; | 236 | desc.tfm = tfm; |
243 | desc.crfn = tfm->__crt_alg->cra_cipher.cia_decrypt; | 237 | desc.crfn = cipher->cia_decrypt; |
244 | desc.prfn = ecb_process; | 238 | desc.prfn = cipher->cia_decrypt_ecb ?: ecb_process; |
245 | 239 | ||
246 | return crypt(&desc, dst, src, nbytes); | 240 | return crypt(&desc, dst, src, nbytes); |
247 | } | 241 | } |
@@ -252,10 +246,11 @@ static int cbc_encrypt(struct crypto_tfm *tfm, | |||
252 | unsigned int nbytes) | 246 | unsigned int nbytes) |
253 | { | 247 | { |
254 | struct cipher_desc desc; | 248 | struct cipher_desc desc; |
249 | struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; | ||
255 | 250 | ||
256 | desc.tfm = tfm; | 251 | desc.tfm = tfm; |
257 | desc.crfn = tfm->__crt_alg->cra_cipher.cia_encrypt; | 252 | desc.crfn = cipher->cia_encrypt; |
258 | desc.prfn = cbc_process_encrypt; | 253 | desc.prfn = cipher->cia_encrypt_cbc ?: cbc_process_encrypt; |
259 | desc.info = tfm->crt_cipher.cit_iv; | 254 | desc.info = tfm->crt_cipher.cit_iv; |
260 | 255 | ||
261 | return crypt(&desc, dst, src, nbytes); | 256 | return crypt(&desc, dst, src, nbytes); |
@@ -267,10 +262,11 @@ static int cbc_encrypt_iv(struct crypto_tfm *tfm, | |||
267 | unsigned int nbytes, u8 *iv) | 262 | unsigned int nbytes, u8 *iv) |
268 | { | 263 | { |
269 | struct cipher_desc desc; | 264 | struct cipher_desc desc; |
265 | struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; | ||
270 | 266 | ||
271 | desc.tfm = tfm; | 267 | desc.tfm = tfm; |
272 | desc.crfn = tfm->__crt_alg->cra_cipher.cia_encrypt; | 268 | desc.crfn = cipher->cia_encrypt; |
273 | desc.prfn = cbc_process_encrypt; | 269 | desc.prfn = cipher->cia_encrypt_cbc ?: cbc_process_encrypt; |
274 | desc.info = iv; | 270 | desc.info = iv; |
275 | 271 | ||
276 | return crypt(&desc, dst, src, nbytes); | 272 | return crypt(&desc, dst, src, nbytes); |
@@ -282,10 +278,11 @@ static int cbc_decrypt(struct crypto_tfm *tfm, | |||
282 | unsigned int nbytes) | 278 | unsigned int nbytes) |
283 | { | 279 | { |
284 | struct cipher_desc desc; | 280 | struct cipher_desc desc; |
281 | struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; | ||
285 | 282 | ||
286 | desc.tfm = tfm; | 283 | desc.tfm = tfm; |
287 | desc.crfn = tfm->__crt_alg->cra_cipher.cia_decrypt; | 284 | desc.crfn = cipher->cia_decrypt; |
288 | desc.prfn = cbc_process_decrypt; | 285 | desc.prfn = cipher->cia_decrypt_cbc ?: cbc_process_decrypt; |
289 | desc.info = tfm->crt_cipher.cit_iv; | 286 | desc.info = tfm->crt_cipher.cit_iv; |
290 | 287 | ||
291 | return crypt(&desc, dst, src, nbytes); | 288 | return crypt(&desc, dst, src, nbytes); |
@@ -297,10 +294,11 @@ static int cbc_decrypt_iv(struct crypto_tfm *tfm, | |||
297 | unsigned int nbytes, u8 *iv) | 294 | unsigned int nbytes, u8 *iv) |
298 | { | 295 | { |
299 | struct cipher_desc desc; | 296 | struct cipher_desc desc; |
297 | struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; | ||
300 | 298 | ||
301 | desc.tfm = tfm; | 299 | desc.tfm = tfm; |
302 | desc.crfn = tfm->__crt_alg->cra_cipher.cia_decrypt; | 300 | desc.crfn = cipher->cia_decrypt; |
303 | desc.prfn = cbc_process_decrypt; | 301 | desc.prfn = cipher->cia_decrypt_cbc ?: cbc_process_decrypt; |
304 | desc.info = iv; | 302 | desc.info = iv; |
305 | 303 | ||
306 | return crypt(&desc, dst, src, nbytes); | 304 | return crypt(&desc, dst, src, nbytes); |
diff --git a/crypto/internal.h b/crypto/internal.h index 964b9a60ca24..5ed383f7dce6 100644 --- a/crypto/internal.h +++ b/crypto/internal.h | |||
@@ -42,11 +42,6 @@ static inline void crypto_yield(struct crypto_tfm *tfm) | |||
42 | cond_resched(); | 42 | cond_resched(); |
43 | } | 43 | } |
44 | 44 | ||
45 | static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm) | ||
46 | { | ||
47 | return (void *)&tfm[1]; | ||
48 | } | ||
49 | |||
50 | struct crypto_alg *crypto_alg_lookup(const char *name); | 45 | struct crypto_alg *crypto_alg_lookup(const char *name); |
51 | 46 | ||
52 | /* A far more intelligent version of this is planned. For now, just | 47 | /* A far more intelligent version of this is planned. For now, just |
diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 387da6a3e58c..26ce01c25745 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h | |||
@@ -61,6 +61,15 @@ | |||
61 | #define CRYPTO_DIR_DECRYPT 0 | 61 | #define CRYPTO_DIR_DECRYPT 0 |
62 | 62 | ||
63 | struct scatterlist; | 63 | struct scatterlist; |
64 | struct crypto_tfm; | ||
65 | |||
66 | struct cipher_desc { | ||
67 | struct crypto_tfm *tfm; | ||
68 | void (*crfn)(void *ctx, u8 *dst, const u8 *src); | ||
69 | unsigned int (*prfn)(const struct cipher_desc *desc, u8 *dst, | ||
70 | const u8 *src, unsigned int nbytes); | ||
71 | void *info; | ||
72 | }; | ||
64 | 73 | ||
65 | /* | 74 | /* |
66 | * Algorithms: modular crypto algorithm implementations, managed | 75 | * Algorithms: modular crypto algorithm implementations, managed |
@@ -73,6 +82,19 @@ struct cipher_alg { | |||
73 | unsigned int keylen, u32 *flags); | 82 | unsigned int keylen, u32 *flags); |
74 | void (*cia_encrypt)(void *ctx, u8 *dst, const u8 *src); | 83 | void (*cia_encrypt)(void *ctx, u8 *dst, const u8 *src); |
75 | void (*cia_decrypt)(void *ctx, u8 *dst, const u8 *src); | 84 | void (*cia_decrypt)(void *ctx, u8 *dst, const u8 *src); |
85 | |||
86 | unsigned int (*cia_encrypt_ecb)(const struct cipher_desc *desc, | ||
87 | u8 *dst, const u8 *src, | ||
88 | unsigned int nbytes); | ||
89 | unsigned int (*cia_decrypt_ecb)(const struct cipher_desc *desc, | ||
90 | u8 *dst, const u8 *src, | ||
91 | unsigned int nbytes); | ||
92 | unsigned int (*cia_encrypt_cbc)(const struct cipher_desc *desc, | ||
93 | u8 *dst, const u8 *src, | ||
94 | unsigned int nbytes); | ||
95 | unsigned int (*cia_decrypt_cbc)(const struct cipher_desc *desc, | ||
96 | u8 *dst, const u8 *src, | ||
97 | unsigned int nbytes); | ||
76 | }; | 98 | }; |
77 | 99 | ||
78 | struct digest_alg { | 100 | struct digest_alg { |
@@ -136,7 +158,6 @@ static inline int crypto_alg_available(const char *name, u32 flags) | |||
136 | * and core processing logic. Managed via crypto_alloc_tfm() and | 158 | * and core processing logic. Managed via crypto_alloc_tfm() and |
137 | * crypto_free_tfm(), as well as the various helpers below. | 159 | * crypto_free_tfm(), as well as the various helpers below. |
138 | */ | 160 | */ |
139 | struct crypto_tfm; | ||
140 | 161 | ||
141 | struct cipher_tfm { | 162 | struct cipher_tfm { |
142 | void *cit_iv; | 163 | void *cit_iv; |
@@ -266,6 +287,11 @@ static inline unsigned int crypto_tfm_alg_digestsize(struct crypto_tfm *tfm) | |||
266 | return tfm->__crt_alg->cra_digest.dia_digestsize; | 287 | return tfm->__crt_alg->cra_digest.dia_digestsize; |
267 | } | 288 | } |
268 | 289 | ||
290 | static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm) | ||
291 | { | ||
292 | return (void *)&tfm[1]; | ||
293 | } | ||
294 | |||
269 | /* | 295 | /* |
270 | * API wrappers. | 296 | * API wrappers. |
271 | */ | 297 | */ |