aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);