curve25519.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. // SPDX-License-Identifier: GPL-2.0 OR MIT
  2. /*
  3. * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
  4. *
  5. * This is an implementation of the Curve25519 ECDH algorithm, using either an
  6. * architecture-optimized implementation or a generic implementation. The
  7. * generic implementation is either 32-bit, or 64-bit with 128-bit integers,
  8. * depending on what is supported by the target compiler.
  9. *
  10. * Information: https://cr.yp.to/ecdh.html
  11. */
  12. #include <crypto/curve25519.h>
  13. #include <crypto/utils.h>
  14. #include <linux/export.h>
  15. #include <linux/init.h>
  16. #include <linux/module.h>
  17. static const u8 curve25519_null_point[CURVE25519_KEY_SIZE] __aligned(32) = { 0 };
  18. static const u8 curve25519_base_point[CURVE25519_KEY_SIZE] __aligned(32) = { 9 };
  19. #ifdef CONFIG_CRYPTO_LIB_CURVE25519_ARCH
  20. #include "curve25519.h" /* $(SRCARCH)/curve25519.h */
  21. #else
  22. static void curve25519_arch(u8 mypublic[CURVE25519_KEY_SIZE],
  23. const u8 secret[CURVE25519_KEY_SIZE],
  24. const u8 basepoint[CURVE25519_KEY_SIZE])
  25. {
  26. curve25519_generic(mypublic, secret, basepoint);
  27. }
  28. static void curve25519_base_arch(u8 pub[CURVE25519_KEY_SIZE],
  29. const u8 secret[CURVE25519_KEY_SIZE])
  30. {
  31. curve25519_generic(pub, secret, curve25519_base_point);
  32. }
  33. #endif
  34. bool __must_check
  35. curve25519(u8 mypublic[CURVE25519_KEY_SIZE],
  36. const u8 secret[CURVE25519_KEY_SIZE],
  37. const u8 basepoint[CURVE25519_KEY_SIZE])
  38. {
  39. curve25519_arch(mypublic, secret, basepoint);
  40. return crypto_memneq(mypublic, curve25519_null_point,
  41. CURVE25519_KEY_SIZE);
  42. }
  43. EXPORT_SYMBOL(curve25519);
  44. bool __must_check
  45. curve25519_generate_public(u8 pub[CURVE25519_KEY_SIZE],
  46. const u8 secret[CURVE25519_KEY_SIZE])
  47. {
  48. if (unlikely(!crypto_memneq(secret, curve25519_null_point,
  49. CURVE25519_KEY_SIZE)))
  50. return false;
  51. curve25519_base_arch(pub, secret);
  52. return crypto_memneq(pub, curve25519_null_point, CURVE25519_KEY_SIZE);
  53. }
  54. EXPORT_SYMBOL(curve25519_generate_public);
  55. #ifdef curve25519_mod_init_arch
  56. static int __init curve25519_mod_init(void)
  57. {
  58. curve25519_mod_init_arch();
  59. return 0;
  60. }
  61. subsys_initcall(curve25519_mod_init);
  62. static void __exit curve25519_mod_exit(void)
  63. {
  64. }
  65. module_exit(curve25519_mod_exit);
  66. #endif
  67. MODULE_LICENSE("GPL v2");
  68. MODULE_DESCRIPTION("Curve25519 algorithm");
  69. MODULE_AUTHOR("Jason A. Donenfeld <Jason@zx2c4.com>");