pcbc.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * PCBC: Propagating Cipher Block Chaining mode
  4. *
  5. * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
  6. * Written by David Howells (dhowells@redhat.com)
  7. *
  8. * Derived from cbc.c
  9. * - Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
  10. */
  11. #include <crypto/algapi.h>
  12. #include <crypto/internal/cipher.h>
  13. #include <crypto/internal/skcipher.h>
  14. #include <linux/err.h>
  15. #include <linux/init.h>
  16. #include <linux/kernel.h>
  17. #include <linux/module.h>
  18. static int crypto_pcbc_encrypt_segment(struct skcipher_request *req,
  19. struct skcipher_walk *walk,
  20. struct crypto_cipher *tfm)
  21. {
  22. int bsize = crypto_cipher_blocksize(tfm);
  23. unsigned int nbytes = walk->nbytes;
  24. u8 *src = walk->src.virt.addr;
  25. u8 *dst = walk->dst.virt.addr;
  26. u8 * const iv = walk->iv;
  27. do {
  28. crypto_xor(iv, src, bsize);
  29. crypto_cipher_encrypt_one(tfm, dst, iv);
  30. crypto_xor_cpy(iv, dst, src, bsize);
  31. src += bsize;
  32. dst += bsize;
  33. } while ((nbytes -= bsize) >= bsize);
  34. return nbytes;
  35. }
  36. static int crypto_pcbc_encrypt_inplace(struct skcipher_request *req,
  37. struct skcipher_walk *walk,
  38. struct crypto_cipher *tfm)
  39. {
  40. int bsize = crypto_cipher_blocksize(tfm);
  41. unsigned int nbytes = walk->nbytes;
  42. u8 *src = walk->src.virt.addr;
  43. u8 * const iv = walk->iv;
  44. u8 tmpbuf[MAX_CIPHER_BLOCKSIZE];
  45. do {
  46. memcpy(tmpbuf, src, bsize);
  47. crypto_xor(iv, src, bsize);
  48. crypto_cipher_encrypt_one(tfm, src, iv);
  49. crypto_xor_cpy(iv, tmpbuf, src, bsize);
  50. src += bsize;
  51. } while ((nbytes -= bsize) >= bsize);
  52. return nbytes;
  53. }
  54. static int crypto_pcbc_encrypt(struct skcipher_request *req)
  55. {
  56. struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
  57. struct crypto_cipher *cipher = skcipher_cipher_simple(tfm);
  58. struct skcipher_walk walk;
  59. unsigned int nbytes;
  60. int err;
  61. err = skcipher_walk_virt(&walk, req, false);
  62. while ((nbytes = walk.nbytes)) {
  63. if (walk.src.virt.addr == walk.dst.virt.addr)
  64. nbytes = crypto_pcbc_encrypt_inplace(req, &walk,
  65. cipher);
  66. else
  67. nbytes = crypto_pcbc_encrypt_segment(req, &walk,
  68. cipher);
  69. err = skcipher_walk_done(&walk, nbytes);
  70. }
  71. return err;
  72. }
  73. static int crypto_pcbc_decrypt_segment(struct skcipher_request *req,
  74. struct skcipher_walk *walk,
  75. struct crypto_cipher *tfm)
  76. {
  77. int bsize = crypto_cipher_blocksize(tfm);
  78. unsigned int nbytes = walk->nbytes;
  79. u8 *src = walk->src.virt.addr;
  80. u8 *dst = walk->dst.virt.addr;
  81. u8 * const iv = walk->iv;
  82. do {
  83. crypto_cipher_decrypt_one(tfm, dst, src);
  84. crypto_xor(dst, iv, bsize);
  85. crypto_xor_cpy(iv, dst, src, bsize);
  86. src += bsize;
  87. dst += bsize;
  88. } while ((nbytes -= bsize) >= bsize);
  89. return nbytes;
  90. }
  91. static int crypto_pcbc_decrypt_inplace(struct skcipher_request *req,
  92. struct skcipher_walk *walk,
  93. struct crypto_cipher *tfm)
  94. {
  95. int bsize = crypto_cipher_blocksize(tfm);
  96. unsigned int nbytes = walk->nbytes;
  97. u8 *src = walk->src.virt.addr;
  98. u8 * const iv = walk->iv;
  99. u8 tmpbuf[MAX_CIPHER_BLOCKSIZE] __aligned(__alignof__(u32));
  100. do {
  101. memcpy(tmpbuf, src, bsize);
  102. crypto_cipher_decrypt_one(tfm, src, src);
  103. crypto_xor(src, iv, bsize);
  104. crypto_xor_cpy(iv, src, tmpbuf, bsize);
  105. src += bsize;
  106. } while ((nbytes -= bsize) >= bsize);
  107. return nbytes;
  108. }
  109. static int crypto_pcbc_decrypt(struct skcipher_request *req)
  110. {
  111. struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
  112. struct crypto_cipher *cipher = skcipher_cipher_simple(tfm);
  113. struct skcipher_walk walk;
  114. unsigned int nbytes;
  115. int err;
  116. err = skcipher_walk_virt(&walk, req, false);
  117. while ((nbytes = walk.nbytes)) {
  118. if (walk.src.virt.addr == walk.dst.virt.addr)
  119. nbytes = crypto_pcbc_decrypt_inplace(req, &walk,
  120. cipher);
  121. else
  122. nbytes = crypto_pcbc_decrypt_segment(req, &walk,
  123. cipher);
  124. err = skcipher_walk_done(&walk, nbytes);
  125. }
  126. return err;
  127. }
  128. static int crypto_pcbc_create(struct crypto_template *tmpl, struct rtattr **tb)
  129. {
  130. struct skcipher_instance *inst;
  131. int err;
  132. inst = skcipher_alloc_instance_simple(tmpl, tb);
  133. if (IS_ERR(inst))
  134. return PTR_ERR(inst);
  135. inst->alg.encrypt = crypto_pcbc_encrypt;
  136. inst->alg.decrypt = crypto_pcbc_decrypt;
  137. err = skcipher_register_instance(tmpl, inst);
  138. if (err)
  139. inst->free(inst);
  140. return err;
  141. }
  142. static struct crypto_template crypto_pcbc_tmpl = {
  143. .name = "pcbc",
  144. .create = crypto_pcbc_create,
  145. .module = THIS_MODULE,
  146. };
  147. static int __init crypto_pcbc_module_init(void)
  148. {
  149. return crypto_register_template(&crypto_pcbc_tmpl);
  150. }
  151. static void __exit crypto_pcbc_module_exit(void)
  152. {
  153. crypto_unregister_template(&crypto_pcbc_tmpl);
  154. }
  155. subsys_initcall(crypto_pcbc_module_init);
  156. module_exit(crypto_pcbc_module_exit);
  157. MODULE_LICENSE("GPL");
  158. MODULE_DESCRIPTION("PCBC block cipher mode of operation");
  159. MODULE_ALIAS_CRYPTO("pcbc");
  160. MODULE_IMPORT_NS(CRYPTO_INTERNAL);