cbc.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * CBC: Cipher Block Chaining mode
  4. *
  5. * Copyright (c) 2006-2016 Herbert Xu <herbert@gondor.apana.org.au>
  6. */
  7. #include <crypto/algapi.h>
  8. #include <crypto/cbc.h>
  9. #include <crypto/internal/skcipher.h>
  10. #include <linux/err.h>
  11. #include <linux/init.h>
  12. #include <linux/kernel.h>
  13. #include <linux/log2.h>
  14. #include <linux/module.h>
  15. static inline void crypto_cbc_encrypt_one(struct crypto_skcipher *tfm,
  16. const u8 *src, u8 *dst)
  17. {
  18. crypto_cipher_encrypt_one(skcipher_cipher_simple(tfm), dst, src);
  19. }
  20. static int crypto_cbc_encrypt(struct skcipher_request *req)
  21. {
  22. return crypto_cbc_encrypt_walk(req, crypto_cbc_encrypt_one);
  23. }
  24. static inline void crypto_cbc_decrypt_one(struct crypto_skcipher *tfm,
  25. const u8 *src, u8 *dst)
  26. {
  27. crypto_cipher_decrypt_one(skcipher_cipher_simple(tfm), dst, src);
  28. }
  29. static int crypto_cbc_decrypt(struct skcipher_request *req)
  30. {
  31. struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
  32. struct skcipher_walk walk;
  33. int err;
  34. err = skcipher_walk_virt(&walk, req, false);
  35. while (walk.nbytes) {
  36. err = crypto_cbc_decrypt_blocks(&walk, tfm,
  37. crypto_cbc_decrypt_one);
  38. err = skcipher_walk_done(&walk, err);
  39. }
  40. return err;
  41. }
  42. static int crypto_cbc_create(struct crypto_template *tmpl, struct rtattr **tb)
  43. {
  44. struct skcipher_instance *inst;
  45. struct crypto_alg *alg;
  46. int err;
  47. inst = skcipher_alloc_instance_simple(tmpl, tb, &alg);
  48. if (IS_ERR(inst))
  49. return PTR_ERR(inst);
  50. err = -EINVAL;
  51. if (!is_power_of_2(alg->cra_blocksize))
  52. goto out_free_inst;
  53. inst->alg.encrypt = crypto_cbc_encrypt;
  54. inst->alg.decrypt = crypto_cbc_decrypt;
  55. err = skcipher_register_instance(tmpl, inst);
  56. if (err)
  57. goto out_free_inst;
  58. goto out_put_alg;
  59. out_free_inst:
  60. inst->free(inst);
  61. out_put_alg:
  62. crypto_mod_put(alg);
  63. return err;
  64. }
  65. static struct crypto_template crypto_cbc_tmpl = {
  66. .name = "cbc",
  67. .create = crypto_cbc_create,
  68. .module = THIS_MODULE,
  69. };
  70. static int __init crypto_cbc_module_init(void)
  71. {
  72. return crypto_register_template(&crypto_cbc_tmpl);
  73. }
  74. static void __exit crypto_cbc_module_exit(void)
  75. {
  76. crypto_unregister_template(&crypto_cbc_tmpl);
  77. }
  78. subsys_initcall(crypto_cbc_module_init);
  79. module_exit(crypto_cbc_module_exit);
  80. MODULE_LICENSE("GPL");
  81. MODULE_DESCRIPTION("CBC block cipher mode of operation");
  82. MODULE_ALIAS_CRYPTO("cbc");