From: Daniel Hodges <git@danielhodges.dev>
To: bpf@vger.kernel.org
Cc: Alexei Starovoitov <ast@kernel.org>,
Andrii Nakryiko <andrii@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Vadim Fedorenko <vadim.fedorenko@linux.dev>,
Song Liu <song@kernel.org>, Mykyta Yatsenko <yatsenko@meta.com>,
Martin KaFai Lau <martin.lau@linux.dev>,
Eduard Zingerman <eddyz87@gmail.com>, Hao Luo <haoluo@google.com>,
Jiri Olsa <jolsa@kernel.org>,
John Fastabend <john.fastabend@gmail.com>,
KP Singh <kpsingh@kernel.org>,
Stanislav Fomichev <sdf@fomichev.me>,
Yonghong Song <yonghong.song@linux.dev>,
Herbert Xu <herbert@gondor.apana.org.au>,
"David S . Miller" <davem@davemloft.net>,
linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-kselftest@vger.kernel.org,
Daniel Hodges <git@danielhodges.dev>
Subject: [PATCH bpf-next v5 4/7] bpf: Add hash kfunc for cryptographic hashing
Date: Tue, 20 Jan 2026 13:46:58 -0500 [thread overview]
Message-ID: <20260120184701.23082-5-git@danielhodges.dev> (raw)
In-Reply-To: <20260120184701.23082-1-git@danielhodges.dev>
Extend bpf_crypto_type structure with hash operations:
- hash(): Performs hashing operation
- digestsize(): Returns hash output size
Update bpf_crypto_ctx_create() to support keyless operations:
- Hash algorithms don't require keys, unlike ciphers
- Only validates key presence if type->setkey is defined
- Conditionally sets IV/state length for cipher operations only
Add bpf_crypto_hash() kfunc that works with any hash algorithm
registered in the kernel's crypto API through the BPF crypto type
system. This enables BPF programs to compute cryptographic hashes for
use cases such as content verification, integrity checking, and data
authentication.
Signed-off-by: Daniel Hodges <git@danielhodges.dev>
---
kernel/bpf/crypto.c | 87 ++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 78 insertions(+), 9 deletions(-)
diff --git a/kernel/bpf/crypto.c b/kernel/bpf/crypto.c
index 7e75a1936256..c8f354b1a2cb 100644
--- a/kernel/bpf/crypto.c
+++ b/kernel/bpf/crypto.c
@@ -139,7 +139,7 @@ __bpf_kfunc_start_defs();
* It may return NULL if no memory is available.
* @params: pointer to struct bpf_crypto_params which contains all the
* details needed to initialise crypto context.
- * @params__sz: size of steuct bpf_crypto_params usef by bpf program
+ * @params__sz: size of struct bpf_crypto_params used by bpf program
* @err: integer to store error code when NULL is returned.
*/
__bpf_kfunc struct bpf_crypto_ctx *
@@ -171,7 +171,12 @@ bpf_crypto_ctx_create(const struct bpf_crypto_params *params, u32 params__sz,
goto err_module_put;
}
- if (!params->key_len || params->key_len > sizeof(params->key)) {
+ /* Hash operations don't require a key, but cipher operations do */
+ if (params->key_len > sizeof(params->key)) {
+ *err = -EINVAL;
+ goto err_module_put;
+ }
+ if (!params->key_len && type->setkey) {
*err = -EINVAL;
goto err_module_put;
}
@@ -195,16 +200,23 @@ bpf_crypto_ctx_create(const struct bpf_crypto_params *params, u32 params__sz,
goto err_free_tfm;
}
- *err = type->setkey(ctx->tfm, params->key, params->key_len);
- if (*err)
- goto err_free_tfm;
+ if (params->key_len) {
+ if (!type->setkey) {
+ *err = -EINVAL;
+ goto err_free_tfm;
+ }
+ *err = type->setkey(ctx->tfm, params->key, params->key_len);
+ if (*err)
+ goto err_free_tfm;
- if (type->get_flags(ctx->tfm) & CRYPTO_TFM_NEED_KEY) {
- *err = -EINVAL;
- goto err_free_tfm;
+ if (type->get_flags(ctx->tfm) & CRYPTO_TFM_NEED_KEY) {
+ *err = -EINVAL;
+ goto err_free_tfm;
+ }
}
- ctx->siv_len = type->ivsize(ctx->tfm) + type->statesize(ctx->tfm);
+ if (type->ivsize && type->statesize)
+ ctx->siv_len = type->ivsize(ctx->tfm) + type->statesize(ctx->tfm);
refcount_set(&ctx->usage, 1);
@@ -349,6 +361,58 @@ __bpf_kfunc int bpf_crypto_encrypt(struct bpf_crypto_ctx *ctx,
return bpf_crypto_crypt(ctx, src_kern, dst_kern, siv_kern, false);
}
+#if IS_ENABLED(CONFIG_CRYPTO_HASH2)
+/**
+ * bpf_crypto_hash() - Compute hash using configured context
+ * @ctx: The crypto context being used. The ctx must be a trusted pointer.
+ * @data: bpf_dynptr to the input data to hash. Must be a trusted pointer.
+ * @out: bpf_dynptr to the output buffer. Must be a trusted pointer.
+ *
+ * Computes hash of the input data using the crypto context. The output buffer
+ * must be at least as large as the digest size of the hash algorithm.
+ */
+__bpf_kfunc int bpf_crypto_hash(struct bpf_crypto_ctx *ctx,
+ const struct bpf_dynptr *data,
+ const struct bpf_dynptr *out)
+{
+ const struct bpf_dynptr_kern *data_kern = (struct bpf_dynptr_kern *)data;
+ const struct bpf_dynptr_kern *out_kern = (struct bpf_dynptr_kern *)out;
+ unsigned int digestsize;
+ u64 data_len, out_len;
+ const u8 *data_ptr;
+ u8 *out_ptr;
+
+ if (ctx->type->type_id != BPF_CRYPTO_TYPE_HASH)
+ return -EINVAL;
+
+ if (!ctx->type->hash)
+ return -EOPNOTSUPP;
+
+ data_len = __bpf_dynptr_size(data_kern);
+ out_len = __bpf_dynptr_size(out_kern);
+
+ if (data_len == 0 || data_len > UINT_MAX)
+ return -EINVAL;
+
+ if (!ctx->type->digestsize)
+ return -EOPNOTSUPP;
+
+ digestsize = ctx->type->digestsize(ctx->tfm);
+ if (out_len < digestsize)
+ return -EINVAL;
+
+ data_ptr = __bpf_dynptr_data(data_kern, data_len);
+ if (!data_ptr)
+ return -EINVAL;
+
+ out_ptr = __bpf_dynptr_data_rw(out_kern, out_len);
+ if (!out_ptr)
+ return -EINVAL;
+
+ return ctx->type->hash(ctx->tfm, data_ptr, out_ptr, data_len);
+}
+#endif /* CONFIG_CRYPTO_HASH2 */
+
__bpf_kfunc_end_defs();
BTF_KFUNCS_START(crypt_init_kfunc_btf_ids)
@@ -365,6 +429,9 @@ static const struct btf_kfunc_id_set crypt_init_kfunc_set = {
BTF_KFUNCS_START(crypt_kfunc_btf_ids)
BTF_ID_FLAGS(func, bpf_crypto_decrypt, KF_RCU)
BTF_ID_FLAGS(func, bpf_crypto_encrypt, KF_RCU)
+#if IS_ENABLED(CONFIG_CRYPTO_HASH2)
+BTF_ID_FLAGS(func, bpf_crypto_hash, KF_RCU)
+#endif
BTF_KFUNCS_END(crypt_kfunc_btf_ids)
static const struct btf_kfunc_id_set crypt_kfunc_set = {
@@ -389,6 +456,8 @@ static int __init crypto_kfunc_init(void)
ret = register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS, &crypt_kfunc_set);
ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_ACT, &crypt_kfunc_set);
ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_XDP, &crypt_kfunc_set);
+ /* Register for SYSCALL programs to enable testing and debugging */
+ ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL, &crypt_kfunc_set);
ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL,
&crypt_init_kfunc_set);
return ret ?: register_btf_id_dtor_kfuncs(bpf_crypto_dtors,
--
2.52.0
next prev parent reply other threads:[~2026-01-20 18:47 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-20 18:46 [PATCH bpf-next v5 0/7] Add cryptographic hash and signature verification kfuncs to BPF Daniel Hodges
2026-01-20 18:46 ` [PATCH bpf-next v5 1/7] bpf: Extend bpf_crypto_type with hash operations Daniel Hodges
2026-01-20 18:46 ` [PATCH bpf-next v5 2/7] crypto: Add BPF hash algorithm type registration module Daniel Hodges
2026-01-20 19:13 ` bot+bpf-ci
2026-01-20 18:46 ` [PATCH bpf-next v5 3/7] crypto: Add BPF signature " Daniel Hodges
2026-01-20 19:13 ` bot+bpf-ci
2026-01-20 18:46 ` Daniel Hodges [this message]
2026-01-20 18:46 ` [PATCH bpf-next v5 5/7] selftests/bpf: Add tests for bpf_crypto_hash kfunc Daniel Hodges
2026-01-20 18:47 ` [PATCH bpf-next v5 6/7] bpf: Add signature verification kfuncs Daniel Hodges
2026-01-20 18:47 ` [PATCH bpf-next v5 7/7] selftests/bpf: Add tests for " Daniel Hodges
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260120184701.23082-5-git@danielhodges.dev \
--to=git@danielhodges.dev \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=eddyz87@gmail.com \
--cc=haoluo@google.com \
--cc=herbert@gondor.apana.org.au \
--cc=john.fastabend@gmail.com \
--cc=jolsa@kernel.org \
--cc=kpsingh@kernel.org \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=martin.lau@linux.dev \
--cc=sdf@fomichev.me \
--cc=song@kernel.org \
--cc=vadim.fedorenko@linux.dev \
--cc=yatsenko@meta.com \
--cc=yonghong.song@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox