ablkcipher.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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/algapi.h>
  16. #include <linux/errno.h>
  17. #include <linux/init.h>
  18. #include <linux/module.h>
  19. #include <linux/seq_file.h>
  20. static int setkey_unaligned(struct crypto_ablkcipher *tfm, const u8 *key, unsigned int keylen)
  21. {
  22. struct ablkcipher_alg *cipher = crypto_ablkcipher_alg(tfm);
  23. unsigned long alignmask = crypto_ablkcipher_alignmask(tfm);
  24. int ret;
  25. u8 *buffer, *alignbuffer;
  26. unsigned long absize;
  27. absize = keylen + alignmask;
  28. buffer = kmalloc(absize, GFP_ATOMIC);
  29. if (!buffer)
  30. return -ENOMEM;
  31. alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
  32. memcpy(alignbuffer, key, keylen);
  33. ret = cipher->setkey(tfm, alignbuffer, keylen);
  34. memset(alignbuffer, 0, absize);
  35. kfree(buffer);
  36. return ret;
  37. }
  38. static int setkey(struct crypto_ablkcipher *tfm, const u8 *key,
  39. unsigned int keylen)
  40. {
  41. struct ablkcipher_alg *cipher = crypto_ablkcipher_alg(tfm);
  42. unsigned long alignmask = crypto_ablkcipher_alignmask(tfm);
  43. if (keylen < cipher->min_keysize || keylen > cipher->max_keysize) {
  44. crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
  45. return -EINVAL;
  46. }
  47. if ((unsigned long)key & alignmask)
  48. return setkey_unaligned(tfm, key, keylen);
  49. return cipher->setkey(tfm, key, keylen);
  50. }
  51. static unsigned int crypto_ablkcipher_ctxsize(struct crypto_alg *alg, u32 type,
  52. u32 mask)
  53. {
  54. return alg->cra_ctxsize;
  55. }
  56. static int crypto_init_ablkcipher_ops(struct crypto_tfm *tfm, u32 type,
  57. u32 mask)
  58. {
  59. struct ablkcipher_alg *alg = &tfm->__crt_alg->cra_ablkcipher;
  60. struct ablkcipher_tfm *crt = &tfm->crt_ablkcipher;
  61. if (alg->ivsize > PAGE_SIZE / 8)
  62. return -EINVAL;
  63. crt->setkey = setkey;
  64. crt->encrypt = alg->encrypt;
  65. crt->decrypt = alg->decrypt;
  66. crt->ivsize = alg->ivsize;
  67. return 0;
  68. }
  69. static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg)
  70. __attribute__ ((unused));
  71. static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg)
  72. {
  73. struct ablkcipher_alg *ablkcipher = &alg->cra_ablkcipher;
  74. seq_printf(m, "type : ablkcipher\n");
  75. seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
  76. seq_printf(m, "min keysize : %u\n", ablkcipher->min_keysize);
  77. seq_printf(m, "max keysize : %u\n", ablkcipher->max_keysize);
  78. seq_printf(m, "ivsize : %u\n", ablkcipher->ivsize);
  79. if (ablkcipher->queue) {
  80. seq_printf(m, "qlen : %u\n", ablkcipher->queue->qlen);
  81. seq_printf(m, "max qlen : %u\n", ablkcipher->queue->max_qlen);
  82. }
  83. }
  84. const struct crypto_type crypto_ablkcipher_type = {
  85. .ctxsize = crypto_ablkcipher_ctxsize,
  86. .init = crypto_init_ablkcipher_ops,
  87. #ifdef CONFIG_PROC_FS
  88. .show = crypto_ablkcipher_show,
  89. #endif
  90. };
  91. EXPORT_SYMBOL_GPL(crypto_ablkcipher_type);
  92. MODULE_LICENSE("GPL");
  93. MODULE_DESCRIPTION("Asynchronous block chaining cipher type");