tcp_fastopen.c 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #include <linux/err.h>
  2. #include <linux/init.h>
  3. #include <linux/kernel.h>
  4. #include <linux/list.h>
  5. #include <linux/tcp.h>
  6. #include <linux/rcupdate.h>
  7. #include <linux/rculist.h>
  8. #include <net/inetpeer.h>
  9. #include <net/tcp.h>
  10. int sysctl_tcp_fastopen __read_mostly;
  11. struct tcp_fastopen_context __rcu *tcp_fastopen_ctx;
  12. static DEFINE_SPINLOCK(tcp_fastopen_ctx_lock);
  13. static void tcp_fastopen_ctx_free(struct rcu_head *head)
  14. {
  15. struct tcp_fastopen_context *ctx =
  16. container_of(head, struct tcp_fastopen_context, rcu);
  17. crypto_free_cipher(ctx->tfm);
  18. kfree(ctx);
  19. }
  20. int tcp_fastopen_reset_cipher(void *key, unsigned int len)
  21. {
  22. int err;
  23. struct tcp_fastopen_context *ctx, *octx;
  24. ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
  25. if (!ctx)
  26. return -ENOMEM;
  27. ctx->tfm = crypto_alloc_cipher("aes", 0, 0);
  28. if (IS_ERR(ctx->tfm)) {
  29. err = PTR_ERR(ctx->tfm);
  30. error: kfree(ctx);
  31. pr_err("TCP: TFO aes cipher alloc error: %d\n", err);
  32. return err;
  33. }
  34. err = crypto_cipher_setkey(ctx->tfm, key, len);
  35. if (err) {
  36. pr_err("TCP: TFO cipher key error: %d\n", err);
  37. crypto_free_cipher(ctx->tfm);
  38. goto error;
  39. }
  40. memcpy(ctx->key, key, len);
  41. spin_lock(&tcp_fastopen_ctx_lock);
  42. octx = rcu_dereference_protected(tcp_fastopen_ctx,
  43. lockdep_is_held(&tcp_fastopen_ctx_lock));
  44. rcu_assign_pointer(tcp_fastopen_ctx, ctx);
  45. spin_unlock(&tcp_fastopen_ctx_lock);
  46. if (octx)
  47. call_rcu(&octx->rcu, tcp_fastopen_ctx_free);
  48. return err;
  49. }
  50. /* Computes the fastopen cookie for the peer.
  51. * The peer address is a 128 bits long (pad with zeros for IPv4).
  52. *
  53. * The caller must check foc->len to determine if a valid cookie
  54. * has been generated successfully.
  55. */
  56. void tcp_fastopen_cookie_gen(__be32 addr, struct tcp_fastopen_cookie *foc)
  57. {
  58. __be32 peer_addr[4] = { addr, 0, 0, 0 };
  59. struct tcp_fastopen_context *ctx;
  60. rcu_read_lock();
  61. ctx = rcu_dereference(tcp_fastopen_ctx);
  62. if (ctx) {
  63. crypto_cipher_encrypt_one(ctx->tfm,
  64. foc->val,
  65. (__u8 *)peer_addr);
  66. foc->len = TCP_FASTOPEN_COOKIE_SIZE;
  67. }
  68. rcu_read_unlock();
  69. }
  70. static int __init tcp_fastopen_init(void)
  71. {
  72. __u8 key[TCP_FASTOPEN_KEY_LENGTH];
  73. get_random_bytes(key, sizeof(key));
  74. tcp_fastopen_reset_cipher(key, sizeof(key));
  75. return 0;
  76. }
  77. late_initcall(tcp_fastopen_init);