brintos

brintos / linux-shallow public Read only

0
0
Text · 3.2 KiB · 645be6c Raw
162 lines · c
1// SPDX-License-Identifier: GPL-2.02/* 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 13unsigned char key[256] = {};14u16 udp_test_port = 7777;15u32 authsize, key_len;16char algo[128] = {};17char dst[16] = {};18int status;19 20static 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 53SEC("syscall")54int 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 87SEC("tc")88int 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 real114	 * 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 123SEC("tc")124int 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 real152	 * 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 161char __license[] SEC("license") = "GPL";162