Commit ecfc43292f68566c144afca966b46b371c26d56c

Authored by Herbert Xu
1 parent 927eead52c

[CRYPTO] skcipher: Add skcipher_geniv_alloc/skcipher_geniv_free

This patch creates the infrastructure to help the construction of givcipher
templates that wrap around existing blkcipher/ablkcipher algorithms by adding
an IV generator to them.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Showing 4 changed files with 225 additions and 6 deletions Side-by-side Diff

... ... @@ -80,6 +80,7 @@
80 80 crt->setkey = setkey;
81 81 crt->encrypt = alg->encrypt;
82 82 crt->decrypt = alg->decrypt;
  83 + crt->base = __crypto_ablkcipher_cast(tfm);
83 84 crt->ivsize = alg->ivsize;
84 85  
85 86 return 0;
86 87  
... ... @@ -122,11 +123,13 @@
122 123 if (alg->ivsize > PAGE_SIZE / 8)
123 124 return -EINVAL;
124 125  
125   - crt->setkey = setkey;
  126 + crt->setkey = tfm->__crt_alg->cra_flags & CRYPTO_ALG_GENIV ?
  127 + alg->setkey : setkey;
126 128 crt->encrypt = alg->encrypt;
127 129 crt->decrypt = alg->decrypt;
128 130 crt->givencrypt = alg->givencrypt;
129 131 crt->givdecrypt = alg->givdecrypt ?: no_givdecrypt;
  132 + crt->base = __crypto_ablkcipher_cast(tfm);
130 133 crt->ivsize = alg->ivsize;
131 134  
132 135 return 0;
... ... @@ -154,6 +157,11 @@
154 157 #endif
155 158 };
156 159 EXPORT_SYMBOL_GPL(crypto_givcipher_type);
  160 +
  161 +const char *crypto_default_geniv(const struct crypto_alg *alg)
  162 +{
  163 + return alg->cra_flags & CRYPTO_ALG_ASYNC ? "eseqiv" : "chainiv";
  164 +}
157 165  
158 166 int crypto_grab_skcipher(struct crypto_skcipher_spawn *spawn, const char *name,
159 167 u32 type, u32 mask)
... ... @@ -14,8 +14,8 @@
14 14 *
15 15 */
16 16  
  17 +#include <crypto/internal/skcipher.h>
17 18 #include <crypto/scatterwalk.h>
18   -#include <linux/crypto.h>
19 19 #include <linux/errno.h>
20 20 #include <linux/hardirq.h>
21 21 #include <linux/kernel.h>
... ... @@ -450,6 +450,7 @@
450 450 crt->setkey = async_setkey;
451 451 crt->encrypt = async_encrypt;
452 452 crt->decrypt = async_decrypt;
  453 + crt->base = __crypto_ablkcipher_cast(tfm);
453 454 crt->ivsize = alg->ivsize;
454 455  
455 456 return 0;
... ... @@ -508,6 +509,188 @@
508 509 #endif
509 510 };
510 511 EXPORT_SYMBOL_GPL(crypto_blkcipher_type);
  512 +
  513 +static int crypto_grab_nivcipher(struct crypto_skcipher_spawn *spawn,
  514 + const char *name, u32 type, u32 mask)
  515 +{
  516 + struct crypto_alg *alg;
  517 + int err;
  518 +
  519 + type = crypto_skcipher_type(type);
  520 + mask = crypto_skcipher_mask(mask) | CRYPTO_ALG_GENIV;
  521 +
  522 + alg = crypto_alg_mod_lookup(name, type, mask);
  523 + if (IS_ERR(alg))
  524 + return PTR_ERR(alg);
  525 +
  526 + err = crypto_init_spawn(&spawn->base, alg, spawn->base.inst, mask);
  527 + crypto_mod_put(alg);
  528 + return err;
  529 +}
  530 +
  531 +struct crypto_instance *skcipher_geniv_alloc(struct crypto_template *tmpl,
  532 + struct rtattr **tb, u32 type,
  533 + u32 mask)
  534 +{
  535 + struct {
  536 + int (*setkey)(struct crypto_ablkcipher *tfm, const u8 *key,
  537 + unsigned int keylen);
  538 + int (*encrypt)(struct ablkcipher_request *req);
  539 + int (*decrypt)(struct ablkcipher_request *req);
  540 +
  541 + unsigned int min_keysize;
  542 + unsigned int max_keysize;
  543 + unsigned int ivsize;
  544 +
  545 + const char *geniv;
  546 + } balg;
  547 + const char *name;
  548 + struct crypto_skcipher_spawn *spawn;
  549 + struct crypto_attr_type *algt;
  550 + struct crypto_instance *inst;
  551 + struct crypto_alg *alg;
  552 + int err;
  553 +
  554 + algt = crypto_get_attr_type(tb);
  555 + err = PTR_ERR(algt);
  556 + if (IS_ERR(algt))
  557 + return ERR_PTR(err);
  558 +
  559 + if ((algt->type ^ (CRYPTO_ALG_TYPE_GIVCIPHER | CRYPTO_ALG_GENIV)) &
  560 + algt->mask)
  561 + return ERR_PTR(-EINVAL);
  562 +
  563 + name = crypto_attr_alg_name(tb[1]);
  564 + err = PTR_ERR(name);
  565 + if (IS_ERR(name))
  566 + return ERR_PTR(err);
  567 +
  568 + inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
  569 + if (!inst)
  570 + return ERR_PTR(-ENOMEM);
  571 +
  572 + spawn = crypto_instance_ctx(inst);
  573 +
  574 + /* Ignore async algorithms if necessary. */
  575 + mask |= crypto_requires_sync(algt->type, algt->mask);
  576 +
  577 + crypto_set_skcipher_spawn(spawn, inst);
  578 + err = crypto_grab_nivcipher(spawn, name, type, mask);
  579 + if (err)
  580 + goto err_free_inst;
  581 +
  582 + alg = crypto_skcipher_spawn_alg(spawn);
  583 +
  584 + if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) ==
  585 + CRYPTO_ALG_TYPE_BLKCIPHER) {
  586 + balg.ivsize = alg->cra_blkcipher.ivsize;
  587 + balg.min_keysize = alg->cra_blkcipher.min_keysize;
  588 + balg.max_keysize = alg->cra_blkcipher.max_keysize;
  589 +
  590 + balg.setkey = async_setkey;
  591 + balg.encrypt = async_encrypt;
  592 + balg.decrypt = async_decrypt;
  593 +
  594 + balg.geniv = alg->cra_blkcipher.geniv;
  595 + } else {
  596 + balg.ivsize = alg->cra_ablkcipher.ivsize;
  597 + balg.min_keysize = alg->cra_ablkcipher.min_keysize;
  598 + balg.max_keysize = alg->cra_ablkcipher.max_keysize;
  599 +
  600 + balg.setkey = alg->cra_ablkcipher.setkey;
  601 + balg.encrypt = alg->cra_ablkcipher.encrypt;
  602 + balg.decrypt = alg->cra_ablkcipher.decrypt;
  603 +
  604 + balg.geniv = alg->cra_ablkcipher.geniv;
  605 + }
  606 +
  607 + err = -EINVAL;
  608 + if (!balg.ivsize)
  609 + goto err_drop_alg;
  610 +
  611 + /*
  612 + * This is only true if we're constructing an algorithm with its
  613 + * default IV generator. For the default generator we elide the
  614 + * template name and double-check the IV generator.
  615 + */
  616 + if (algt->mask & CRYPTO_ALG_GENIV) {
  617 + if (!balg.geniv)
  618 + balg.geniv = crypto_default_geniv(alg);
  619 + err = -EAGAIN;
  620 + if (strcmp(tmpl->name, balg.geniv))
  621 + goto err_drop_alg;
  622 +
  623 + memcpy(inst->alg.cra_name, alg->cra_name, CRYPTO_MAX_ALG_NAME);
  624 + memcpy(inst->alg.cra_driver_name, alg->cra_driver_name,
  625 + CRYPTO_MAX_ALG_NAME);
  626 + } else {
  627 + err = -ENAMETOOLONG;
  628 + if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME,
  629 + "%s(%s)", tmpl->name, alg->cra_name) >=
  630 + CRYPTO_MAX_ALG_NAME)
  631 + goto err_drop_alg;
  632 + if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME,
  633 + "%s(%s)", tmpl->name, alg->cra_driver_name) >=
  634 + CRYPTO_MAX_ALG_NAME)
  635 + goto err_drop_alg;
  636 + }
  637 +
  638 + inst->alg.cra_flags = CRYPTO_ALG_TYPE_GIVCIPHER | CRYPTO_ALG_GENIV;
  639 + inst->alg.cra_flags |= alg->cra_flags & CRYPTO_ALG_ASYNC;
  640 + inst->alg.cra_priority = alg->cra_priority;
  641 + inst->alg.cra_blocksize = alg->cra_blocksize;
  642 + inst->alg.cra_alignmask = alg->cra_alignmask;
  643 + inst->alg.cra_type = &crypto_givcipher_type;
  644 +
  645 + inst->alg.cra_ablkcipher.ivsize = balg.ivsize;
  646 + inst->alg.cra_ablkcipher.min_keysize = balg.min_keysize;
  647 + inst->alg.cra_ablkcipher.max_keysize = balg.max_keysize;
  648 + inst->alg.cra_ablkcipher.geniv = balg.geniv;
  649 +
  650 + inst->alg.cra_ablkcipher.setkey = balg.setkey;
  651 + inst->alg.cra_ablkcipher.encrypt = balg.encrypt;
  652 + inst->alg.cra_ablkcipher.decrypt = balg.decrypt;
  653 +
  654 +out:
  655 + return inst;
  656 +
  657 +err_drop_alg:
  658 + crypto_drop_skcipher(spawn);
  659 +err_free_inst:
  660 + kfree(inst);
  661 + inst = ERR_PTR(err);
  662 + goto out;
  663 +}
  664 +EXPORT_SYMBOL_GPL(skcipher_geniv_alloc);
  665 +
  666 +void skcipher_geniv_free(struct crypto_instance *inst)
  667 +{
  668 + crypto_drop_skcipher(crypto_instance_ctx(inst));
  669 + kfree(inst);
  670 +}
  671 +EXPORT_SYMBOL_GPL(skcipher_geniv_free);
  672 +
  673 +int skcipher_geniv_init(struct crypto_tfm *tfm)
  674 +{
  675 + struct crypto_instance *inst = (void *)tfm->__crt_alg;
  676 + struct crypto_ablkcipher *cipher;
  677 +
  678 + cipher = crypto_spawn_skcipher(crypto_instance_ctx(inst));
  679 + if (IS_ERR(cipher))
  680 + return PTR_ERR(cipher);
  681 +
  682 + tfm->crt_ablkcipher.base = cipher;
  683 + tfm->crt_ablkcipher.reqsize += crypto_ablkcipher_reqsize(cipher);
  684 +
  685 + return 0;
  686 +}
  687 +EXPORT_SYMBOL_GPL(skcipher_geniv_init);
  688 +
  689 +void skcipher_geniv_exit(struct crypto_tfm *tfm)
  690 +{
  691 + crypto_free_ablkcipher(tfm->crt_ablkcipher.base);
  692 +}
  693 +EXPORT_SYMBOL_GPL(skcipher_geniv_exit);
511 694  
512 695 MODULE_LICENSE("GPL");
513 696 MODULE_DESCRIPTION("Generic block chaining cipher type");
include/crypto/internal/skcipher.h
... ... @@ -15,7 +15,10 @@
15 15  
16 16 #include <crypto/algapi.h>
17 17 #include <crypto/skcipher.h>
  18 +#include <linux/types.h>
18 19  
  20 +struct rtattr;
  21 +
19 22 struct crypto_skcipher_spawn {
20 23 struct crypto_spawn base;
21 24 };
... ... @@ -48,6 +51,21 @@
48 51 return __crypto_ablkcipher_cast(
49 52 crypto_spawn_tfm(&spawn->base, crypto_skcipher_type(0),
50 53 crypto_skcipher_mask(0)));
  54 +}
  55 +
  56 +const char *crypto_default_geniv(const struct crypto_alg *alg);
  57 +
  58 +struct crypto_instance *skcipher_geniv_alloc(struct crypto_template *tmpl,
  59 + struct rtattr **tb, u32 type,
  60 + u32 mask);
  61 +void skcipher_geniv_free(struct crypto_instance *inst);
  62 +int skcipher_geniv_init(struct crypto_tfm *tfm);
  63 +void skcipher_geniv_exit(struct crypto_tfm *tfm);
  64 +
  65 +static inline struct crypto_ablkcipher *skcipher_geniv_cipher(
  66 + struct crypto_ablkcipher *geniv)
  67 +{
  68 + return crypto_ablkcipher_crt(geniv)->base;
51 69 }
52 70  
53 71 static inline void *skcipher_givcrypt_reqctx(
include/linux/crypto.h
... ... @@ -53,6 +53,12 @@
53 53 #define CRYPTO_ALG_NEED_FALLBACK 0x00000100
54 54  
55 55 /*
  56 + * This bit is set for symmetric key ciphers that have already been wrapped
  57 + * with a generic IV generator to prevent them from being wrapped again.
  58 + */
  59 +#define CRYPTO_ALG_GENIV 0x00000200
  60 +
  61 +/*
56 62 * Transform masks and values (for crt_flags).
57 63 */
58 64 #define CRYPTO_TFM_REQ_MASK 0x000fff00
... ... @@ -331,6 +337,8 @@
331 337 int (*givencrypt)(struct skcipher_givcrypt_request *req);
332 338 int (*givdecrypt)(struct skcipher_givcrypt_request *req);
333 339  
  340 + struct crypto_ablkcipher *base;
  341 +
334 342 unsigned int ivsize;
335 343 unsigned int reqsize;
336 344 };
337 345  
... ... @@ -541,14 +549,14 @@
541 549  
542 550 static inline u32 crypto_skcipher_type(u32 type)
543 551 {
544   - type &= ~CRYPTO_ALG_TYPE_MASK;
  552 + type &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV);
545 553 type |= CRYPTO_ALG_TYPE_BLKCIPHER;
546 554 return type;
547 555 }
548 556  
549 557 static inline u32 crypto_skcipher_mask(u32 mask)
550 558 {
551   - mask &= ~CRYPTO_ALG_TYPE_MASK;
  559 + mask &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV);
552 560 mask |= CRYPTO_ALG_TYPE_BLKCIPHER_MASK;
553 561 return mask;
554 562 }
... ... @@ -623,7 +631,9 @@
623 631 static inline int crypto_ablkcipher_setkey(struct crypto_ablkcipher *tfm,
624 632 const u8 *key, unsigned int keylen)
625 633 {
626   - return crypto_ablkcipher_crt(tfm)->setkey(tfm, key, keylen);
  634 + struct ablkcipher_tfm *crt = crypto_ablkcipher_crt(tfm);
  635 +
  636 + return crt->setkey(crt->base, key, keylen);
627 637 }
628 638  
629 639 static inline struct crypto_ablkcipher *crypto_ablkcipher_reqtfm(
... ... @@ -655,7 +665,7 @@
655 665 static inline void ablkcipher_request_set_tfm(
656 666 struct ablkcipher_request *req, struct crypto_ablkcipher *tfm)
657 667 {
658   - req->base.tfm = crypto_ablkcipher_tfm(tfm);
  668 + req->base.tfm = crypto_ablkcipher_tfm(crypto_ablkcipher_crt(tfm)->base);
659 669 }
660 670  
661 671 static inline struct ablkcipher_request *ablkcipher_request_cast(