ablkcipher.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /*
  2. * Asynchronous block chaining cipher operations.
  3. *
  4. * This is the asynchronous version of blkcipher.c indicating completion
  5. * via a callback.
  6. *
  7. * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
  8. *
  9. * This program is free software; you can redistribute it and/or modify it
  10. * under the terms of the GNU General Public License as published by the Free
  11. * Software Foundation; either version 2 of the License, or (at your option)
  12. * any later version.
  13. *
  14. */
  15. #include <crypto/internal/skcipher.h>
  16. #include <linux/err.h>
  17. #include <linux/init.h>
  18. #include <linux/kernel.h>
  19. #include <linux/module.h>
  20. #include <linux/slab.h>
  21. #include <linux/seq_file.h>
  22. #include "internal.h"
  23. static int setkey_unaligned(struct crypto_ablkcipher *tfm, const u8 *key,
  24. unsigned int keylen)
  25. {
  26. struct ablkcipher_alg *cipher = crypto_ablkcipher_alg(tfm);
  27. unsigned long alignmask = crypto_ablkcipher_alignmask(tfm);
  28. int ret;
  29. u8 *buffer, *alignbuffer;
  30. unsigned long absize;
  31. absize = keylen + alignmask;
  32. buffer = kmalloc(absize, GFP_ATOMIC);
  33. if (!buffer)
  34. return -ENOMEM;
  35. alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
  36. memcpy(alignbuffer, key, keylen);
  37. ret = cipher->setkey(tfm, alignbuffer, keylen);
  38. memset(alignbuffer, 0, keylen);
  39. kfree(buffer);
  40. return ret;
  41. }
  42. static int setkey(struct crypto_ablkcipher *tfm, const u8 *key,
  43. unsigned int keylen)
  44. {
  45. struct ablkcipher_alg *cipher = crypto_ablkcipher_alg(tfm);
  46. unsigned long alignmask = crypto_ablkcipher_alignmask(tfm);
  47. if (keylen < cipher->min_keysize || keylen > cipher->max_keysize) {
  48. crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
  49. return -EINVAL;
  50. }
  51. if ((unsigned long)key & alignmask)
  52. return setkey_unaligned(tfm, key, keylen);
  53. return cipher->setkey(tfm, key, keylen);
  54. }
  55. static unsigned int crypto_ablkcipher_ctxsize(struct crypto_alg *alg, u32 type,
  56. u32 mask)
  57. {
  58. return alg->cra_ctxsize;
  59. }
  60. static int crypto_init_ablkcipher_ops(struct crypto_tfm *tfm, u32 type,
  61. u32 mask)
  62. {
  63. struct ablkcipher_alg *alg = &tfm->__crt_alg->cra_ablkcipher;
  64. struct ablkcipher_tfm *crt = &tfm->crt_ablkcipher;
  65. if (alg->ivsize > PAGE_SIZE / 8)
  66. return -EINVAL;
  67. crt->setkey = setkey;
  68. crt->encrypt = alg->encrypt;
  69. crt->decrypt = alg->decrypt;
  70. crt->ivsize = alg->ivsize;
  71. return 0;
  72. }
  73. static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg)
  74. __attribute__ ((unused));
  75. static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg)
  76. {
  77. struct ablkcipher_alg *ablkcipher = &alg->cra_ablkcipher;
  78. seq_printf(m, "type : ablkcipher\n");
  79. seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
  80. seq_printf(m, "min keysize : %u\n", ablkcipher->min_keysize);
  81. seq_printf(m, "max keysize : %u\n", ablkcipher->max_keysize);
  82. seq_printf(m, "ivsize : %u\n", ablkcipher->ivsize);
  83. seq_printf(m, "geniv : %s\n", ablkcipher->geniv ?: "<default>");
  84. }
  85. const struct crypto_type crypto_ablkcipher_type = {
  86. .ctxsize = crypto_ablkcipher_ctxsize,
  87. .init = crypto_init_ablkcipher_ops,
  88. #ifdef CONFIG_PROC_FS
  89. .show = crypto_ablkcipher_show,
  90. #endif
  91. };
  92. EXPORT_SYMBOL_GPL(crypto_ablkcipher_type);
  93. static int no_givdecrypt(struct skcipher_givcrypt_request *req)
  94. {
  95. return -ENOSYS;
  96. }
  97. static int crypto_init_givcipher_ops(struct crypto_tfm *tfm, u32 type,
  98. u32 mask)
  99. {
  100. struct ablkcipher_alg *alg = &tfm->__crt_alg->cra_ablkcipher;
  101. struct ablkcipher_tfm *crt = &tfm->crt_ablkcipher;
  102. if (alg->ivsize > PAGE_SIZE / 8)
  103. return -EINVAL;
  104. crt->setkey = setkey;
  105. crt->encrypt = alg->encrypt;
  106. crt->decrypt = alg->decrypt;
  107. crt->givencrypt = alg->givencrypt;
  108. crt->givdecrypt = alg->givdecrypt ?: no_givdecrypt;
  109. crt->ivsize = alg->ivsize;
  110. return 0;
  111. }
  112. static void crypto_givcipher_show(struct seq_file *m, struct crypto_alg *alg)
  113. __attribute__ ((unused));
  114. static void crypto_givcipher_show(struct seq_file *m, struct crypto_alg *alg)
  115. {
  116. struct ablkcipher_alg *ablkcipher = &alg->cra_ablkcipher;
  117. seq_printf(m, "type : givcipher\n");
  118. seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
  119. seq_printf(m, "min keysize : %u\n", ablkcipher->min_keysize);
  120. seq_printf(m, "max keysize : %u\n", ablkcipher->max_keysize);
  121. seq_printf(m, "ivsize : %u\n", ablkcipher->ivsize);
  122. seq_printf(m, "geniv : %s\n", ablkcipher->geniv ?: "<built-in>");
  123. }
  124. const struct crypto_type crypto_givcipher_type = {
  125. .ctxsize = crypto_ablkcipher_ctxsize,
  126. .init = crypto_init_givcipher_ops,
  127. #ifdef CONFIG_PROC_FS
  128. .show = crypto_givcipher_show,
  129. #endif
  130. };
  131. EXPORT_SYMBOL_GPL(crypto_givcipher_type);
  132. int crypto_grab_skcipher(struct crypto_skcipher_spawn *spawn, const char *name,
  133. u32 type, u32 mask)
  134. {
  135. struct crypto_alg *alg;
  136. int err;
  137. type = crypto_skcipher_type(type);
  138. mask = crypto_skcipher_mask(mask);
  139. alg = crypto_alg_mod_lookup(name, type, mask);
  140. if (IS_ERR(alg))
  141. return PTR_ERR(alg);
  142. err = crypto_init_spawn(&spawn->base, alg, spawn->base.inst, mask);
  143. crypto_mod_put(alg);
  144. return err;
  145. }
  146. EXPORT_SYMBOL_GPL(crypto_grab_skcipher);
  147. MODULE_LICENSE("GPL");
  148. MODULE_DESCRIPTION("Asynchronous block chaining cipher type");