aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2006-08-13 06:58:18 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2006-09-20 21:41:51 -0400
commitf28776a369b12f9a03a822a8e1090ed670a41f4f (patch)
treeb1eb08db2d7ad5c83a4b2784aea3af0502d127b3
parente853c3cfa8cc24869ecd2526e589bcb176bc12e9 (diff)
[CRYPTO] cipher: Added encrypt_one/decrypt_one
This patch adds two new operations for the simple cipher that encrypts or decrypts a single block at a time. This will be the main interface after the existing block operations have moved over to the new block ciphers. It also adds the crypto_cipher type which is currently only used on the new operations but will be extended to setkey as well once existing users have been converted to use block ciphers where applicable. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--crypto/cipher.c48
-rw-r--r--include/crypto/algapi.h5
-rw-r--r--include/linux/crypto.h96
3 files changed, 149 insertions, 0 deletions
diff --git a/crypto/cipher.c b/crypto/cipher.c
index f573c59ed9dc..d8ca0ec8d0be 100644
--- a/crypto/cipher.c
+++ b/crypto/cipher.c
@@ -388,12 +388,60 @@ int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags)
388 return 0; 388 return 0;
389} 389}
390 390
391static void cipher_crypt_unaligned(void (*fn)(struct crypto_tfm *, u8 *,
392 const u8 *),
393 struct crypto_tfm *tfm,
394 u8 *dst, const u8 *src)
395{
396 unsigned long alignmask = crypto_tfm_alg_alignmask(tfm);
397 unsigned int size = crypto_tfm_alg_blocksize(tfm);
398 u8 buffer[size + alignmask];
399 u8 *tmp = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
400
401 memcpy(tmp, src, size);
402 fn(tfm, tmp, tmp);
403 memcpy(dst, tmp, size);
404}
405
406static void cipher_encrypt_unaligned(struct crypto_tfm *tfm,
407 u8 *dst, const u8 *src)
408{
409 unsigned long alignmask = crypto_tfm_alg_alignmask(tfm);
410 struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher;
411
412 if (unlikely(((unsigned long)dst | (unsigned long)src) & alignmask)) {
413 cipher_crypt_unaligned(cipher->cia_encrypt, tfm, dst, src);
414 return;
415 }
416
417 cipher->cia_encrypt(tfm, dst, src);
418}
419
420static void cipher_decrypt_unaligned(struct crypto_tfm *tfm,
421 u8 *dst, const u8 *src)
422{
423 unsigned long alignmask = crypto_tfm_alg_alignmask(tfm);
424 struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher;
425
426 if (unlikely(((unsigned long)dst | (unsigned long)src) & alignmask)) {
427 cipher_crypt_unaligned(cipher->cia_decrypt, tfm, dst, src);
428 return;
429 }
430
431 cipher->cia_decrypt(tfm, dst, src);
432}
433
391int crypto_init_cipher_ops(struct crypto_tfm *tfm) 434int crypto_init_cipher_ops(struct crypto_tfm *tfm)
392{ 435{
393 int ret = 0; 436 int ret = 0;
394 struct cipher_tfm *ops = &tfm->crt_cipher; 437 struct cipher_tfm *ops = &tfm->crt_cipher;
438 struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher;
395 439
396 ops->cit_setkey = setkey; 440 ops->cit_setkey = setkey;
441 ops->cit_encrypt_one = crypto_tfm_alg_alignmask(tfm) ?
442 cipher_encrypt_unaligned : cipher->cia_encrypt;
443 ops->cit_decrypt_one = crypto_tfm_alg_alignmask(tfm) ?
444 cipher_decrypt_unaligned : cipher->cia_decrypt;
397 445
398 switch (tfm->crt_cipher.cit_mode) { 446 switch (tfm->crt_cipher.cit_mode) {
399 case CRYPTO_TFM_MODE_ECB: 447 case CRYPTO_TFM_MODE_ECB:
diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h
index c533c0a291af..6f9fb27b2071 100644
--- a/include/crypto/algapi.h
+++ b/include/crypto/algapi.h
@@ -69,5 +69,10 @@ static inline void *crypto_instance_ctx(struct crypto_instance *inst)
69 return inst->__ctx; 69 return inst->__ctx;
70} 70}
71 71
72static inline struct cipher_alg *crypto_cipher_alg(struct crypto_cipher *tfm)
73{
74 return &crypto_cipher_tfm(tfm)->__crt_alg->cra_cipher;
75}
76
72#endif /* _CRYPTO_ALGAPI_H */ 77#endif /* _CRYPTO_ALGAPI_H */
73 78
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index 8e9c407b00d2..fdecee83878c 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -224,6 +224,8 @@ struct cipher_tfm {
224 struct scatterlist *src, 224 struct scatterlist *src,
225 unsigned int nbytes, u8 *iv); 225 unsigned int nbytes, u8 *iv);
226 void (*cit_xor_block)(u8 *dst, const u8 *src); 226 void (*cit_xor_block)(u8 *dst, const u8 *src);
227 void (*cit_encrypt_one)(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
228 void (*cit_decrypt_one)(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
227}; 229};
228 230
229struct digest_tfm { 231struct digest_tfm {
@@ -268,6 +270,8 @@ struct crypto_tfm {
268 void *__crt_ctx[] CRYPTO_MINALIGN_ATTR; 270 void *__crt_ctx[] CRYPTO_MINALIGN_ATTR;
269}; 271};
270 272
273#define crypto_cipher crypto_tfm
274
271enum { 275enum {
272 CRYPTOA_UNSPEC, 276 CRYPTOA_UNSPEC,
273 CRYPTOA_ALG, 277 CRYPTOA_ALG,
@@ -347,6 +351,21 @@ static inline unsigned int crypto_tfm_alg_alignmask(struct crypto_tfm *tfm)
347 return tfm->__crt_alg->cra_alignmask; 351 return tfm->__crt_alg->cra_alignmask;
348} 352}
349 353
354static inline u32 crypto_tfm_get_flags(struct crypto_tfm *tfm)
355{
356 return tfm->crt_flags;
357}
358
359static inline void crypto_tfm_set_flags(struct crypto_tfm *tfm, u32 flags)
360{
361 tfm->crt_flags |= flags;
362}
363
364static inline void crypto_tfm_clear_flags(struct crypto_tfm *tfm, u32 flags)
365{
366 tfm->crt_flags &= ~flags;
367}
368
350static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm) 369static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm)
351{ 370{
352 return tfm->__crt_ctx; 371 return tfm->__crt_ctx;
@@ -361,6 +380,83 @@ static inline unsigned int crypto_tfm_ctx_alignment(void)
361/* 380/*
362 * API wrappers. 381 * API wrappers.
363 */ 382 */
383static inline struct crypto_cipher *__crypto_cipher_cast(struct crypto_tfm *tfm)
384{
385 return (struct crypto_cipher *)tfm;
386}
387
388static inline struct crypto_cipher *crypto_cipher_cast(struct crypto_tfm *tfm)
389{
390 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
391 return __crypto_cipher_cast(tfm);
392}
393
394static inline struct crypto_cipher *crypto_alloc_cipher(const char *alg_name,
395 u32 type, u32 mask)
396{
397 type &= ~CRYPTO_ALG_TYPE_MASK;
398 type |= CRYPTO_ALG_TYPE_CIPHER;
399 mask |= CRYPTO_ALG_TYPE_MASK;
400
401 return __crypto_cipher_cast(crypto_alloc_base(alg_name, type, mask));
402}
403
404static inline struct crypto_tfm *crypto_cipher_tfm(struct crypto_cipher *tfm)
405{
406 return tfm;
407}
408
409static inline void crypto_free_cipher(struct crypto_cipher *tfm)
410{
411 crypto_free_tfm(crypto_cipher_tfm(tfm));
412}
413
414static inline struct cipher_tfm *crypto_cipher_crt(struct crypto_cipher *tfm)
415{
416 return &crypto_cipher_tfm(tfm)->crt_cipher;
417}
418
419static inline unsigned int crypto_cipher_blocksize(struct crypto_cipher *tfm)
420{
421 return crypto_tfm_alg_blocksize(crypto_cipher_tfm(tfm));
422}
423
424static inline unsigned int crypto_cipher_alignmask(struct crypto_cipher *tfm)
425{
426 return crypto_tfm_alg_alignmask(crypto_cipher_tfm(tfm));
427}
428
429static inline u32 crypto_cipher_get_flags(struct crypto_cipher *tfm)
430{
431 return crypto_tfm_get_flags(crypto_cipher_tfm(tfm));
432}
433
434static inline void crypto_cipher_set_flags(struct crypto_cipher *tfm,
435 u32 flags)
436{
437 crypto_tfm_set_flags(crypto_cipher_tfm(tfm), flags);
438}
439
440static inline void crypto_cipher_clear_flags(struct crypto_cipher *tfm,
441 u32 flags)
442{
443 crypto_tfm_clear_flags(crypto_cipher_tfm(tfm), flags);
444}
445
446static inline void crypto_cipher_encrypt_one(struct crypto_cipher *tfm,
447 u8 *dst, const u8 *src)
448{
449 crypto_cipher_crt(tfm)->cit_encrypt_one(crypto_cipher_tfm(tfm),
450 dst, src);
451}
452
453static inline void crypto_cipher_decrypt_one(struct crypto_cipher *tfm,
454 u8 *dst, const u8 *src)
455{
456 crypto_cipher_crt(tfm)->cit_decrypt_one(crypto_cipher_tfm(tfm),
457 dst, src);
458}
459
364static inline void crypto_digest_init(struct crypto_tfm *tfm) 460static inline void crypto_digest_init(struct crypto_tfm *tfm)
365{ 461{
366 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); 462 BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);