aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/cipher.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/cipher.c')
-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: