]> Git Repo - J-linux.git/blob - tools/testing/selftests/bpf/progs/crypto_sanity.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / tools / testing / selftests / bpf / progs / crypto_sanity.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */
3
4 #include "vmlinux.h"
5 #include "bpf_tracing_net.h"
6 #include <bpf/bpf_helpers.h>
7 #include <bpf/bpf_endian.h>
8 #include <bpf/bpf_tracing.h>
9 #include "bpf_misc.h"
10 #include "bpf_kfuncs.h"
11 #include "crypto_common.h"
12
13 unsigned char key[256] = {};
14 u16 udp_test_port = 7777;
15 u32 authsize, key_len;
16 char algo[128] = {};
17 char dst[16] = {};
18 int status;
19
20 static int skb_dynptr_validate(struct __sk_buff *skb, struct bpf_dynptr *psrc)
21 {
22         struct ipv6hdr ip6h;
23         struct udphdr udph;
24         u32 offset;
25
26         if (skb->protocol != __bpf_constant_htons(ETH_P_IPV6))
27                 return -1;
28
29         if (bpf_skb_load_bytes(skb, ETH_HLEN, &ip6h, sizeof(ip6h)))
30                 return -1;
31
32         if (ip6h.nexthdr != IPPROTO_UDP)
33                 return -1;
34
35         if (bpf_skb_load_bytes(skb, ETH_HLEN + sizeof(ip6h), &udph, sizeof(udph)))
36                 return -1;
37
38         if (udph.dest != __bpf_htons(udp_test_port))
39                 return -1;
40
41         offset = ETH_HLEN + sizeof(ip6h) + sizeof(udph);
42         if (skb->len < offset + 16)
43                 return -1;
44
45         /* let's make sure that 16 bytes of payload are in the linear part of skb */
46         bpf_skb_pull_data(skb, offset + 16);
47         bpf_dynptr_from_skb(skb, 0, psrc);
48         bpf_dynptr_adjust(psrc, offset, offset + 16);
49
50         return 0;
51 }
52
53 SEC("syscall")
54 int skb_crypto_setup(void *ctx)
55 {
56         struct bpf_crypto_params params = {
57                 .type = "skcipher",
58                 .key_len = key_len,
59                 .authsize = authsize,
60         };
61         struct bpf_crypto_ctx *cctx;
62         int err = 0;
63
64         status = 0;
65
66         if (key_len > 256) {
67                 status = -EINVAL;
68                 return 0;
69         }
70
71         __builtin_memcpy(&params.algo, algo, sizeof(algo));
72         __builtin_memcpy(&params.key, key, sizeof(key));
73         cctx = bpf_crypto_ctx_create(&params, sizeof(params), &err);
74
75         if (!cctx) {
76                 status = err;
77                 return 0;
78         }
79
80         err = crypto_ctx_insert(cctx);
81         if (err && err != -EEXIST)
82                 status = err;
83
84         return 0;
85 }
86
87 SEC("tc")
88 int decrypt_sanity(struct __sk_buff *skb)
89 {
90         struct __crypto_ctx_value *v;
91         struct bpf_crypto_ctx *ctx;
92         struct bpf_dynptr psrc, pdst;
93         int err;
94
95         err = skb_dynptr_validate(skb, &psrc);
96         if (err < 0) {
97                 status = err;
98                 return TC_ACT_SHOT;
99         }
100
101         v = crypto_ctx_value_lookup();
102         if (!v) {
103                 status = -ENOENT;
104                 return TC_ACT_SHOT;
105         }
106
107         ctx = v->ctx;
108         if (!ctx) {
109                 status = -ENOENT;
110                 return TC_ACT_SHOT;
111         }
112
113         /* dst is a global variable to make testing part easier to check. In real
114          * production code, a percpu map should be used to store the result.
115          */
116         bpf_dynptr_from_mem(dst, sizeof(dst), 0, &pdst);
117
118         status = bpf_crypto_decrypt(ctx, &psrc, &pdst, NULL);
119
120         return TC_ACT_SHOT;
121 }
122
123 SEC("tc")
124 int encrypt_sanity(struct __sk_buff *skb)
125 {
126         struct __crypto_ctx_value *v;
127         struct bpf_crypto_ctx *ctx;
128         struct bpf_dynptr psrc, pdst;
129         int err;
130
131         status = 0;
132
133         err = skb_dynptr_validate(skb, &psrc);
134         if (err < 0) {
135                 status = err;
136                 return TC_ACT_SHOT;
137         }
138
139         v = crypto_ctx_value_lookup();
140         if (!v) {
141                 status = -ENOENT;
142                 return TC_ACT_SHOT;
143         }
144
145         ctx = v->ctx;
146         if (!ctx) {
147                 status = -ENOENT;
148                 return TC_ACT_SHOT;
149         }
150
151         /* dst is a global variable to make testing part easier to check. In real
152          * production code, a percpu map should be used to store the result.
153          */
154         bpf_dynptr_from_mem(dst, sizeof(dst), 0, &pdst);
155
156         status = bpf_crypto_encrypt(ctx, &psrc, &pdst, NULL);
157
158         return TC_ACT_SHOT;
159 }
160
161 char __license[] SEC("license") = "GPL";
This page took 0.035697 seconds and 4 git commands to generate.