aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/blkcipher.c70
-rw-r--r--include/linux/crypto.h199
2 files changed, 260 insertions, 9 deletions
diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c
index bf459179efe3..8edf40c835a7 100644
--- a/crypto/blkcipher.c
+++ b/crypto/blkcipher.c
@@ -349,13 +349,48 @@ static int setkey(struct crypto_tfm *tfm, const u8 *key,
349 return cipher->setkey(tfm, key, keylen); 349 return cipher->setkey(tfm, key, keylen);
350} 350}
351 351
352static int async_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
353 unsigned int keylen)
354{
355 return setkey(crypto_ablkcipher_tfm(tfm), key, keylen);
356}
357
358static int async_encrypt(struct ablkcipher_request *req)
359{
360 struct crypto_tfm *tfm = req->base.tfm;
361 struct blkcipher_alg *alg = &tfm->__crt_alg->cra_blkcipher;
362 struct blkcipher_desc desc = {
363 .tfm = __crypto_blkcipher_cast(tfm),
364 .info = req->info,
365 .flags = req->base.flags,
366 };
367
368
369 return alg->encrypt(&desc, req->dst, req->src, req->nbytes);
370}
371
372static int async_decrypt(struct ablkcipher_request *req)
373{
374 struct crypto_tfm *tfm = req->base.tfm;
375 struct blkcipher_alg *alg = &tfm->__crt_alg->cra_blkcipher;
376 struct blkcipher_desc desc = {
377 .tfm = __crypto_blkcipher_cast(tfm),
378 .info = req->info,
379 .flags = req->base.flags,
380 };
381
382 return alg->decrypt(&desc, req->dst, req->src, req->nbytes);
383}
384
352static unsigned int crypto_blkcipher_ctxsize(struct crypto_alg *alg, u32 type, 385static unsigned int crypto_blkcipher_ctxsize(struct crypto_alg *alg, u32 type,
353 u32 mask) 386 u32 mask)
354{ 387{
355 struct blkcipher_alg *cipher = &alg->cra_blkcipher; 388 struct blkcipher_alg *cipher = &alg->cra_blkcipher;
356 unsigned int len = alg->cra_ctxsize; 389 unsigned int len = alg->cra_ctxsize;
357 390
358 if (cipher->ivsize) { 391 type ^= CRYPTO_ALG_ASYNC;
392 mask &= CRYPTO_ALG_ASYNC;
393 if ((type & mask) && cipher->ivsize) {
359 len = ALIGN(len, (unsigned long)alg->cra_alignmask + 1); 394 len = ALIGN(len, (unsigned long)alg->cra_alignmask + 1);
360 len += cipher->ivsize; 395 len += cipher->ivsize;
361 } 396 }
@@ -363,16 +398,26 @@ static unsigned int crypto_blkcipher_ctxsize(struct crypto_alg *alg, u32 type,
363 return len; 398 return len;
364} 399}
365 400
366static int crypto_init_blkcipher_ops(struct crypto_tfm *tfm, u32 type, u32 mask) 401static int crypto_init_blkcipher_ops_async(struct crypto_tfm *tfm)
402{
403 struct ablkcipher_tfm *crt = &tfm->crt_ablkcipher;
404 struct blkcipher_alg *alg = &tfm->__crt_alg->cra_blkcipher;
405
406 crt->setkey = async_setkey;
407 crt->encrypt = async_encrypt;
408 crt->decrypt = async_decrypt;
409 crt->ivsize = alg->ivsize;
410
411 return 0;
412}
413
414static int crypto_init_blkcipher_ops_sync(struct crypto_tfm *tfm)
367{ 415{
368 struct blkcipher_tfm *crt = &tfm->crt_blkcipher; 416 struct blkcipher_tfm *crt = &tfm->crt_blkcipher;
369 struct blkcipher_alg *alg = &tfm->__crt_alg->cra_blkcipher; 417 struct blkcipher_alg *alg = &tfm->__crt_alg->cra_blkcipher;
370 unsigned long align = crypto_tfm_alg_alignmask(tfm) + 1; 418 unsigned long align = crypto_tfm_alg_alignmask(tfm) + 1;
371 unsigned long addr; 419 unsigned long addr;
372 420
373 if (alg->ivsize > PAGE_SIZE / 8)
374 return -EINVAL;
375
376 crt->setkey = setkey; 421 crt->setkey = setkey;
377 crt->encrypt = alg->encrypt; 422 crt->encrypt = alg->encrypt;
378 crt->decrypt = alg->decrypt; 423 crt->decrypt = alg->decrypt;
@@ -385,6 +430,21 @@ static int crypto_init_blkcipher_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
385 return 0; 430 return 0;
386} 431}
387 432
433static int crypto_init_blkcipher_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
434{
435 struct blkcipher_alg *alg = &tfm->__crt_alg->cra_blkcipher;
436
437 if (alg->ivsize > PAGE_SIZE / 8)
438 return -EINVAL;
439
440 type ^= CRYPTO_ALG_ASYNC;
441 mask &= CRYPTO_ALG_ASYNC;
442 if (type & mask)
443 return crypto_init_blkcipher_ops_sync(tfm);
444 else
445 return crypto_init_blkcipher_ops_async(tfm);
446}
447
388static void crypto_blkcipher_show(struct seq_file *m, struct crypto_alg *alg) 448static void crypto_blkcipher_show(struct seq_file *m, struct crypto_alg *alg)
389 __attribute__ ((unused)); 449 __attribute__ ((unused));
390static void crypto_blkcipher_show(struct seq_file *m, struct crypto_alg *alg) 450static void crypto_blkcipher_show(struct seq_file *m, struct crypto_alg *alg)
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index 779aa78ee643..d4d05313280c 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -56,6 +56,7 @@
56 56
57#define CRYPTO_TFM_REQ_WEAK_KEY 0x00000100 57#define CRYPTO_TFM_REQ_WEAK_KEY 0x00000100
58#define CRYPTO_TFM_REQ_MAY_SLEEP 0x00000200 58#define CRYPTO_TFM_REQ_MAY_SLEEP 0x00000200
59#define CRYPTO_TFM_REQ_MAY_BACKLOG 0x00000400
59#define CRYPTO_TFM_RES_WEAK_KEY 0x00100000 60#define CRYPTO_TFM_RES_WEAK_KEY 0x00100000
60#define CRYPTO_TFM_RES_BAD_KEY_LEN 0x00200000 61#define CRYPTO_TFM_RES_BAD_KEY_LEN 0x00200000
61#define CRYPTO_TFM_RES_BAD_KEY_SCHED 0x00400000 62#define CRYPTO_TFM_RES_BAD_KEY_SCHED 0x00400000
@@ -88,11 +89,37 @@
88#endif 89#endif
89 90
90struct scatterlist; 91struct scatterlist;
92struct crypto_ablkcipher;
93struct crypto_async_request;
91struct crypto_blkcipher; 94struct crypto_blkcipher;
92struct crypto_hash; 95struct crypto_hash;
93struct crypto_tfm; 96struct crypto_tfm;
94struct crypto_type; 97struct crypto_type;
95 98
99typedef void (*crypto_completion_t)(struct crypto_async_request *req, int err);
100
101struct crypto_async_request {
102 struct list_head list;
103 crypto_completion_t complete;
104 void *data;
105 struct crypto_tfm *tfm;
106
107 u32 flags;
108};
109
110struct ablkcipher_request {
111 struct crypto_async_request base;
112
113 unsigned int nbytes;
114
115 void *info;
116
117 struct scatterlist *src;
118 struct scatterlist *dst;
119
120 void *__ctx[] CRYPTO_MINALIGN_ATTR;
121};
122
96struct blkcipher_desc { 123struct blkcipher_desc {
97 struct crypto_blkcipher *tfm; 124 struct crypto_blkcipher *tfm;
98 void *info; 125 void *info;
@@ -232,6 +259,15 @@ static inline int crypto_has_alg(const char *name, u32 type, u32 mask)
232 * crypto_free_*(), as well as the various helpers below. 259 * crypto_free_*(), as well as the various helpers below.
233 */ 260 */
234 261
262struct ablkcipher_tfm {
263 int (*setkey)(struct crypto_ablkcipher *tfm, const u8 *key,
264 unsigned int keylen);
265 int (*encrypt)(struct ablkcipher_request *req);
266 int (*decrypt)(struct ablkcipher_request *req);
267 unsigned int ivsize;
268 unsigned int reqsize;
269};
270
235struct blkcipher_tfm { 271struct blkcipher_tfm {
236 void *iv; 272 void *iv;
237 int (*setkey)(struct crypto_tfm *tfm, const u8 *key, 273 int (*setkey)(struct crypto_tfm *tfm, const u8 *key,
@@ -290,6 +326,7 @@ struct compress_tfm {
290 u8 *dst, unsigned int *dlen); 326 u8 *dst, unsigned int *dlen);
291}; 327};
292 328
329#define crt_ablkcipher crt_u.ablkcipher
293#define crt_blkcipher crt_u.blkcipher 330#define crt_blkcipher crt_u.blkcipher
294#define crt_cipher crt_u.cipher 331#define crt_cipher crt_u.cipher
295#define crt_hash crt_u.hash 332#define crt_hash crt_u.hash
@@ -300,6 +337,7 @@ struct crypto_tfm {
300 u32 crt_flags; 337 u32 crt_flags;
301 338
302 union { 339 union {
340 struct ablkcipher_tfm ablkcipher;
303 struct blkcipher_tfm blkcipher; 341 struct blkcipher_tfm blkcipher;
304 struct cipher_tfm cipher; 342 struct cipher_tfm cipher;
305 struct hash_tfm hash; 343 struct hash_tfm hash;
@@ -311,6 +349,10 @@ struct crypto_tfm {
311 void *__crt_ctx[] CRYPTO_MINALIGN_ATTR; 349 void *__crt_ctx[] CRYPTO_MINALIGN_ATTR;
312}; 350};
313 351
352struct crypto_ablkcipher {
353 struct crypto_tfm base;
354};
355
314struct crypto_blkcipher { 356struct crypto_blkcipher {
315 struct crypto_tfm base; 357 struct crypto_tfm base;
316}; 358};
@@ -411,6 +453,155 @@ static inline unsigned int crypto_tfm_ctx_alignment(void)
411/* 453/*
412 * API wrappers. 454 * API wrappers.
413 */ 455 */
456static inline struct crypto_ablkcipher *__crypto_ablkcipher_cast(
457 struct crypto_tfm *tfm)
458{
459 return (struct crypto_ablkcipher *)tfm;
460}
461
462static inline struct crypto_ablkcipher *crypto_alloc_ablkcipher(
463 const char *alg_name, u32 type, u32 mask)
464{
465 type &= ~CRYPTO_ALG_TYPE_MASK;
466 type |= CRYPTO_ALG_TYPE_BLKCIPHER;
467 mask |= CRYPTO_ALG_TYPE_MASK;
468
469 return __crypto_ablkcipher_cast(
470 crypto_alloc_base(alg_name, type, mask));
471}
472
473static inline struct crypto_tfm *crypto_ablkcipher_tfm(
474 struct crypto_ablkcipher *tfm)
475{
476 return &tfm->base;
477}
478
479static inline void crypto_free_ablkcipher(struct crypto_ablkcipher *tfm)
480{
481 crypto_free_tfm(crypto_ablkcipher_tfm(tfm));
482}
483
484static inline int crypto_has_ablkcipher(const char *alg_name, u32 type,
485 u32 mask)
486{
487 type &= ~CRYPTO_ALG_TYPE_MASK;
488 type |= CRYPTO_ALG_TYPE_BLKCIPHER;
489 mask |= CRYPTO_ALG_TYPE_MASK;
490
491 return crypto_has_alg(alg_name, type, mask);
492}
493
494static inline struct ablkcipher_tfm *crypto_ablkcipher_crt(
495 struct crypto_ablkcipher *tfm)
496{
497 return &crypto_ablkcipher_tfm(tfm)->crt_ablkcipher;
498}
499
500static inline unsigned int crypto_ablkcipher_ivsize(
501 struct crypto_ablkcipher *tfm)
502{
503 return crypto_ablkcipher_crt(tfm)->ivsize;
504}
505
506static inline unsigned int crypto_ablkcipher_blocksize(
507 struct crypto_ablkcipher *tfm)
508{
509 return crypto_tfm_alg_blocksize(crypto_ablkcipher_tfm(tfm));
510}
511
512static inline unsigned int crypto_ablkcipher_alignmask(
513 struct crypto_ablkcipher *tfm)
514{
515 return crypto_tfm_alg_alignmask(crypto_ablkcipher_tfm(tfm));
516}
517
518static inline u32 crypto_ablkcipher_get_flags(struct crypto_ablkcipher *tfm)
519{
520 return crypto_tfm_get_flags(crypto_ablkcipher_tfm(tfm));
521}
522
523static inline void crypto_ablkcipher_set_flags(struct crypto_ablkcipher *tfm,
524 u32 flags)
525{
526 crypto_tfm_set_flags(crypto_ablkcipher_tfm(tfm), flags);
527}
528
529static inline void crypto_ablkcipher_clear_flags(struct crypto_ablkcipher *tfm,
530 u32 flags)
531{
532 crypto_tfm_clear_flags(crypto_ablkcipher_tfm(tfm), flags);
533}
534
535static inline int crypto_ablkcipher_setkey(struct crypto_ablkcipher *tfm,
536 const u8 *key, unsigned int keylen)
537{
538 return crypto_ablkcipher_crt(tfm)->setkey(tfm, key, keylen);
539}
540
541static inline struct crypto_ablkcipher *crypto_ablkcipher_reqtfm(
542 struct ablkcipher_request *req)
543{
544 return __crypto_ablkcipher_cast(req->base.tfm);
545}
546
547static inline int crypto_ablkcipher_encrypt(struct ablkcipher_request *req)
548{
549 struct ablkcipher_tfm *crt =
550 crypto_ablkcipher_crt(crypto_ablkcipher_reqtfm(req));
551 return crt->encrypt(req);
552}
553
554static inline int crypto_ablkcipher_decrypt(struct ablkcipher_request *req)
555{
556 struct ablkcipher_tfm *crt =
557 crypto_ablkcipher_crt(crypto_ablkcipher_reqtfm(req));
558 return crt->decrypt(req);
559}
560
561static inline int crypto_ablkcipher_reqsize(struct crypto_ablkcipher *tfm)
562{
563 return crypto_ablkcipher_crt(tfm)->reqsize;
564}
565
566static inline struct ablkcipher_request *ablkcipher_request_alloc(
567 struct crypto_ablkcipher *tfm, gfp_t gfp)
568{
569 struct ablkcipher_request *req;
570
571 req = kmalloc(sizeof(struct ablkcipher_request) +
572 crypto_ablkcipher_reqsize(tfm), gfp);
573
574 if (likely(req))
575 req->base.tfm = crypto_ablkcipher_tfm(tfm);
576
577 return req;
578}
579
580static inline void ablkcipher_request_free(struct ablkcipher_request *req)
581{
582 kfree(req);
583}
584
585static inline void ablkcipher_request_set_callback(
586 struct ablkcipher_request *req,
587 u32 flags, crypto_completion_t complete, void *data)
588{
589 req->base.complete = complete;
590 req->base.data = data;
591 req->base.flags = flags;
592}
593
594static inline void ablkcipher_request_set_crypt(
595 struct ablkcipher_request *req,
596 struct scatterlist *src, struct scatterlist *dst,
597 unsigned int nbytes, void *iv)
598{
599 req->src = src;
600 req->dst = dst;
601 req->nbytes = nbytes;
602 req->info = iv;
603}
604
414static inline struct crypto_blkcipher *__crypto_blkcipher_cast( 605static inline struct crypto_blkcipher *__crypto_blkcipher_cast(
415 struct crypto_tfm *tfm) 606 struct crypto_tfm *tfm)
416{ 607{
@@ -427,9 +618,9 @@ static inline struct crypto_blkcipher *crypto_blkcipher_cast(
427static inline struct crypto_blkcipher *crypto_alloc_blkcipher( 618static inline struct crypto_blkcipher *crypto_alloc_blkcipher(
428 const char *alg_name, u32 type, u32 mask) 619 const char *alg_name, u32 type, u32 mask)
429{ 620{
430 type &= ~CRYPTO_ALG_TYPE_MASK; 621 type &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC);
431 type |= CRYPTO_ALG_TYPE_BLKCIPHER; 622 type |= CRYPTO_ALG_TYPE_BLKCIPHER;
432 mask |= CRYPTO_ALG_TYPE_MASK; 623 mask |= CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC;
433 624
434 return __crypto_blkcipher_cast(crypto_alloc_base(alg_name, type, mask)); 625 return __crypto_blkcipher_cast(crypto_alloc_base(alg_name, type, mask));
435} 626}
@@ -447,9 +638,9 @@ static inline void crypto_free_blkcipher(struct crypto_blkcipher *tfm)
447 638
448static inline int crypto_has_blkcipher(const char *alg_name, u32 type, u32 mask) 639static inline int crypto_has_blkcipher(const char *alg_name, u32 type, u32 mask)
449{ 640{
450 type &= ~CRYPTO_ALG_TYPE_MASK; 641 type &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC);
451 type |= CRYPTO_ALG_TYPE_BLKCIPHER; 642 type |= CRYPTO_ALG_TYPE_BLKCIPHER;
452 mask |= CRYPTO_ALG_TYPE_MASK; 643 mask |= CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC;
453 644
454 return crypto_has_alg(alg_name, type, mask); 645 return crypto_has_alg(alg_name, type, mask);
455} 646}