2 #include <linux/init.h>
3 #include <linux/kernel.h>
4 #include <linux/list.h>
6 #include <linux/rcupdate.h>
7 #include <linux/rculist.h>
8 #include <net/inetpeer.h>
11 int sysctl_tcp_fastopen __read_mostly
;
13 struct tcp_fastopen_context __rcu
*tcp_fastopen_ctx
;
15 static DEFINE_SPINLOCK(tcp_fastopen_ctx_lock
);
17 static void tcp_fastopen_ctx_free(struct rcu_head
*head
)
19 struct tcp_fastopen_context
*ctx
=
20 container_of(head
, struct tcp_fastopen_context
, rcu
);
21 crypto_free_cipher(ctx
->tfm
);
25 int tcp_fastopen_reset_cipher(void *key
, unsigned int len
)
28 struct tcp_fastopen_context
*ctx
, *octx
;
30 ctx
= kmalloc(sizeof(*ctx
), GFP_KERNEL
);
33 ctx
->tfm
= crypto_alloc_cipher("aes", 0, 0);
35 if (IS_ERR(ctx
->tfm
)) {
36 err
= PTR_ERR(ctx
->tfm
);
38 pr_err("TCP: TFO aes cipher alloc error: %d\n", err
);
41 err
= crypto_cipher_setkey(ctx
->tfm
, key
, len
);
43 pr_err("TCP: TFO cipher key error: %d\n", err
);
44 crypto_free_cipher(ctx
->tfm
);
47 memcpy(ctx
->key
, key
, len
);
49 spin_lock(&tcp_fastopen_ctx_lock
);
51 octx
= rcu_dereference_protected(tcp_fastopen_ctx
,
52 lockdep_is_held(&tcp_fastopen_ctx_lock
));
53 rcu_assign_pointer(tcp_fastopen_ctx
, ctx
);
54 spin_unlock(&tcp_fastopen_ctx_lock
);
57 call_rcu(&octx
->rcu
, tcp_fastopen_ctx_free
);
61 /* Computes the fastopen cookie for the IP path.
62 * The path is a 128 bits long (pad with zeros for IPv4).
64 * The caller must check foc->len to determine if a valid cookie
65 * has been generated successfully.
67 void tcp_fastopen_cookie_gen(__be32 src
, __be32 dst
,
68 struct tcp_fastopen_cookie
*foc
)
70 __be32 path
[4] = { src
, dst
, 0, 0 };
71 struct tcp_fastopen_context
*ctx
;
74 ctx
= rcu_dereference(tcp_fastopen_ctx
);
76 crypto_cipher_encrypt_one(ctx
->tfm
, foc
->val
, (__u8
*)path
);
77 foc
->len
= TCP_FASTOPEN_COOKIE_SIZE
;
82 static int __init
tcp_fastopen_init(void)
84 __u8 key
[TCP_FASTOPEN_KEY_LENGTH
];
86 get_random_bytes(key
, sizeof(key
));
87 tcp_fastopen_reset_cipher(key
, sizeof(key
));
91 late_initcall(tcp_fastopen_init
);