aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2005-07-06 16:51:52 -0400
committerDavid S. Miller <davem@davemloft.net>2005-07-06 16:51:52 -0400
commit40725181b74be6b0e3bdc8c05bd1e0b9873ec5cc (patch)
treeabbc1057a5e0bd77385d17cfc6146617151e93bc
parentc774e93e2152d0be2612739418689e6e6400f4eb (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.c38
-rw-r--r--crypto/internal.h5
-rw-r--r--include/linux/crypto.h28
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
26struct 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
34static inline void xor_64(u8 *a, const u8 *b) 26static 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
45static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm)
46{
47 return (void *)&tfm[1];
48}
49
50struct crypto_alg *crypto_alg_lookup(const char *name); 45struct 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
63struct scatterlist; 63struct scatterlist;
64struct crypto_tfm;
65
66struct 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
78struct digest_alg { 100struct 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 */
139struct crypto_tfm;
140 161
141struct cipher_tfm { 162struct 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
290static 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 */