aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
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 /crypto
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>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/cipher.c48
1 files changed, 48 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: