Skip to content

Commit acaad38

Browse files
committed
perf: embed Hmac in cookie_checker to eliminate make_cookie malloc (ue7.14)
make_cookie() previously malloc'd an 832-byte Hmac struct on every call. It is only called under rate-limiting conditions (never on the normal data path), so serialisation on the existing secret_lock write semaphore is acceptable. Add a struct Hmac make_cookie_hmac field to struct cookie_checker (embedded in the heap-allocated struct wg_device). Restructure make_cookie() to hold secret_lock for write throughout, covering both the optional secret refresh and the Hmac operation, eliminating the per-call kmalloc/free of the Hmac struct.
1 parent 41ae73b commit acaad38

2 files changed

Lines changed: 28 additions & 26 deletions

File tree

kernel-src/cookie.c

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -103,52 +103,49 @@ static int __must_check compute_mac2(u8 mac2[COOKIE_LEN], const void *message, s
103103
static int __must_check make_cookie(u8 cookie[COOKIE_LEN], struct sk_buff *skb,
104104
struct cookie_checker *checker)
105105
{
106-
int ret;
107-
struct Hmac *wc_hmac; /* sizeof(struct Hmac) is 832 if SHA3 is enabled. */
108-
109-
wc_hmac = (struct Hmac *)malloc(sizeof(*wc_hmac));
110-
if (! wc_hmac)
111-
return -ENOMEM;
106+
int ret = 0;
112107

113-
ret = wc_HmacInit(wc_hmac, NULL /* heap */, INVALID_DEVID);
114-
if (ret < 0)
115-
goto out_hmac_uninited;
108+
/* Take write lock for the entire operation to ensure exclusive access
109+
* to checker->make_cookie_hmac. make_cookie is only invoked under
110+
* rate-limiting conditions, so serialising on the write lock is fine.
111+
*/
112+
down_write(&checker->secret_lock);
116113

117-
if ((ret == 0) && wg_birthdate_has_expired(checker->secret_birthdate,
114+
if (wg_birthdate_has_expired(checker->secret_birthdate,
118115
COOKIE_SECRET_MAX_AGE)) {
119-
down_write(&checker->secret_lock);
120116
ret = wc_get_random_bytes(checker->secret, NOISE_HASH_LEN);
121117
if (ret == 0)
122118
checker->secret_birthdate = ktime_get_coarse_boottime_ns();
123-
up_write(&checker->secret_lock);
124119
}
125120

126-
if (ret == 0) {
127-
down_read(&checker->secret_lock);
121+
if (ret == 0)
122+
ret = wc_HmacInit(&checker->make_cookie_hmac, NULL /* heap */, INVALID_DEVID);
128123

129-
ret = wc_HmacSetKey(wc_hmac, WC_SHA256, checker->secret, NOISE_HASH_LEN);
124+
if (ret == 0) {
125+
ret = wc_HmacSetKey(&checker->make_cookie_hmac, WC_SHA256,
126+
checker->secret, NOISE_HASH_LEN);
130127

131128
if ((ret == 0) && (skb->protocol == htons(ETH_P_IP)))
132-
ret = wc_HmacUpdate(wc_hmac, (u8 *)&ip_hdr(skb)->saddr,
129+
ret = wc_HmacUpdate(&checker->make_cookie_hmac,
130+
(u8 *)&ip_hdr(skb)->saddr,
133131
(word32)sizeof(struct in_addr));
134132
else if ((ret == 0) && (skb->protocol == htons(ETH_P_IPV6)))
135-
ret = wc_HmacUpdate(wc_hmac, (u8 *)&ipv6_hdr(skb)->saddr,
133+
ret = wc_HmacUpdate(&checker->make_cookie_hmac,
134+
(u8 *)&ipv6_hdr(skb)->saddr,
136135
(word32)sizeof(struct in6_addr));
137-
136+
138137
if (ret == 0)
139-
ret = wc_HmacUpdate(wc_hmac, (u8 *)&udp_hdr(skb)->source, sizeof(__be16));
138+
ret = wc_HmacUpdate(&checker->make_cookie_hmac,
139+
(u8 *)&udp_hdr(skb)->source,
140+
sizeof(__be16));
140141

141142
if (ret == 0)
142-
ret = wc_HmacFinal(wc_hmac, cookie);
143+
ret = wc_HmacFinal(&checker->make_cookie_hmac, cookie);
143144

144-
up_read(&checker->secret_lock);
145+
wc_HmacFree(&checker->make_cookie_hmac);
145146
}
146147

147-
wc_HmacFree(wc_hmac);
148-
149-
out_hmac_uninited:
150-
151-
free(wc_hmac);
148+
up_write(&checker->secret_lock);
152149

153150
return ret;
154151
}

kernel-src/cookie.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#define _WG_COOKIE_H
1010

1111
#include "messages.h"
12+
#include "wolfcrypt_glue.h"
1213
#include <linux/rwsem.h>
1314

1415
struct wg_peer;
@@ -19,6 +20,10 @@ struct cookie_checker {
1920
u8 message_mac1_key[NOISE_SYMMETRIC_KEY_LEN];
2021
u64 secret_birthdate;
2122
struct rw_semaphore secret_lock;
23+
/* Scratch buffer for make_cookie() — avoids per-call kmalloc of the
24+
* 832-byte Hmac struct. Used only while secret_lock is held for write.
25+
*/
26+
struct Hmac make_cookie_hmac;
2227
struct wg_device *device;
2328
};
2429

0 commit comments

Comments
 (0)