curve25519-generic.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. #include <crypto/curve25519.h>
  3. #include <crypto/internal/kpp.h>
  4. #include <crypto/kpp.h>
  5. #include <linux/module.h>
  6. #include <linux/scatterlist.h>
  7. static int curve25519_set_secret(struct crypto_kpp *tfm, const void *buf,
  8. unsigned int len)
  9. {
  10. u8 *secret = kpp_tfm_ctx(tfm);
  11. if (!len)
  12. curve25519_generate_secret(secret);
  13. else if (len == CURVE25519_KEY_SIZE &&
  14. crypto_memneq(buf, curve25519_null_point, CURVE25519_KEY_SIZE))
  15. memcpy(secret, buf, CURVE25519_KEY_SIZE);
  16. else
  17. return -EINVAL;
  18. return 0;
  19. }
  20. static int curve25519_compute_value(struct kpp_request *req)
  21. {
  22. struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
  23. const u8 *secret = kpp_tfm_ctx(tfm);
  24. u8 public_key[CURVE25519_KEY_SIZE];
  25. u8 buf[CURVE25519_KEY_SIZE];
  26. int copied, nbytes;
  27. u8 const *bp;
  28. if (req->src) {
  29. copied = sg_copy_to_buffer(req->src,
  30. sg_nents_for_len(req->src,
  31. CURVE25519_KEY_SIZE),
  32. public_key, CURVE25519_KEY_SIZE);
  33. if (copied != CURVE25519_KEY_SIZE)
  34. return -EINVAL;
  35. bp = public_key;
  36. } else {
  37. bp = curve25519_base_point;
  38. }
  39. curve25519_generic(buf, secret, bp);
  40. /* might want less than we've got */
  41. nbytes = min_t(size_t, CURVE25519_KEY_SIZE, req->dst_len);
  42. copied = sg_copy_from_buffer(req->dst, sg_nents_for_len(req->dst,
  43. nbytes),
  44. buf, nbytes);
  45. if (copied != nbytes)
  46. return -EINVAL;
  47. return 0;
  48. }
  49. static unsigned int curve25519_max_size(struct crypto_kpp *tfm)
  50. {
  51. return CURVE25519_KEY_SIZE;
  52. }
  53. static struct kpp_alg curve25519_alg = {
  54. .base.cra_name = "curve25519",
  55. .base.cra_driver_name = "curve25519-generic",
  56. .base.cra_priority = 100,
  57. .base.cra_module = THIS_MODULE,
  58. .base.cra_ctxsize = CURVE25519_KEY_SIZE,
  59. .set_secret = curve25519_set_secret,
  60. .generate_public_key = curve25519_compute_value,
  61. .compute_shared_secret = curve25519_compute_value,
  62. .max_size = curve25519_max_size,
  63. };
  64. static int curve25519_init(void)
  65. {
  66. return crypto_register_kpp(&curve25519_alg);
  67. }
  68. static void curve25519_exit(void)
  69. {
  70. crypto_unregister_kpp(&curve25519_alg);
  71. }
  72. subsys_initcall(curve25519_init);
  73. module_exit(curve25519_exit);
  74. MODULE_ALIAS_CRYPTO("curve25519");
  75. MODULE_ALIAS_CRYPTO("curve25519-generic");
  76. MODULE_LICENSE("GPL");