From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from devnull.danielhodges.dev (vps-2f6e086e.vps.ovh.us [135.148.138.8]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D098D3043DB; Mon, 5 Jan 2026 17:44:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=135.148.138.8 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767635045; cv=none; b=KTLQOBpgFxAoXl0g1kCn0kNp6QJtTlqZaOIJIZYy7wsfkolNE+S9lYEFSWPhc2birxwFJGEKyVRnZE9AZh0HsokhoWIxHDwsh61ZhRBX4hh5xTM3qgRctlPODvzaQRuastnNVUp1AAvKC+ged2Xxd3v8z9nGOfgJYP9sPd7oPas= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767635045; c=relaxed/simple; bh=LIQ2RWQ/rdcmAdOs3BQYDxhIAkXIgtIE2/y/0QfGXcY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=T95jdQUhjStOofZquSzf13iOxk/PlSf3Q1tpgVyRdWEvt8CAXVBRbpNdI2yGdOARXR7tSnPZpw9vx8VlGpGhbw4QzveKKtSt2USnLTnnOxZQnKpJ8orairqqU7/mdCMNEwPOWCV9HkRF4RYZtHuszKzEjk4VBa4dR6VC7XsgRWI= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=danielhodges.dev; spf=pass smtp.mailfrom=danielhodges.dev; dkim=pass (2048-bit key) header.d=danielhodges.dev header.i=@danielhodges.dev header.b=E835BmqO; dkim=permerror (0-bit key) header.d=danielhodges.dev header.i=@danielhodges.dev header.b=XauI79+z; arc=none smtp.client-ip=135.148.138.8 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=danielhodges.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=danielhodges.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=danielhodges.dev header.i=@danielhodges.dev header.b="E835BmqO"; dkim=permerror (0-bit key) header.d=danielhodges.dev header.i=@danielhodges.dev header.b="XauI79+z" DKIM-Signature: v=1; a=rsa-sha256; s=202510r; d=danielhodges.dev; c=relaxed/relaxed; h=Message-ID:Date:Subject:To:From; t=1767634676; bh=VBJzN7USezqgJjm8fsrBxac CNv0aHzMvoebXe0qR4UQ=; b=E835BmqOLQBDDcrUAe/iFme+hZaOZUgyk3uFhhln+tQzn+yyTW MeCm5mVdx4Rqk0vtFT3LRpUSGZ41Yj3y5vIfuv/UODSoRgJQyiYUhkITzmoJ+TSJG5QuaaYVUt1 XQebRzsPHdonjd6pGJMNLc/iH0U7kx3vm1Mv0WrqjwsTuQI3z7IO7Ls/Ggwyv7GzGATv53+wsig XtKIO9+4K/REeJrZ+nkSR5hroLiAEfmcg5v8M/MtmDIZuugKWgTM5q9OMFtUNeYxxm3K3dViNKl HqzjgFA3yfPanRa/lxm92tS8yZkaBJr3fQJZXcoBr6HomzznxHgaa1AsTgEdwJf3q/g==; DKIM-Signature: v=1; a=ed25519-sha256; s=202510e; d=danielhodges.dev; c=relaxed/relaxed; h=Message-ID:Date:Subject:To:From; t=1767634676; bh=VBJzN7USezqgJjm8fsrBxac CNv0aHzMvoebXe0qR4UQ=; b=XauI79+zRQRgCKiyd0E382Zth4bdyv82/kyENxoNzEW+sssUkm 9MSN6eNZURKXqk3OwLKTZsf3Nk3YkJW/AuAA==; From: Daniel Hodges To: bpf@vger.kernel.org Cc: Alexei Starovoitov , Andrii Nakryiko , Daniel Borkmann , Vadim Fedorenko , Song Liu , Mykyta Yatsenko , Martin KaFai Lau , Eduard Zingerman , Hao Luo , Jiri Olsa , John Fastabend , KP Singh , Stanislav Fomichev , Yonghong Song , Herbert Xu , "David S . Miller" , linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Daniel Hodges Subject: [PATCH bpf-next v4 3/6] bpf: Add hash kfunc for cryptographic hashing Date: Mon, 5 Jan 2026 12:37:52 -0500 Message-ID: <20260105173755.22515-4-git@danielhodges.dev> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260105173755.22515-1-git@danielhodges.dev> References: <20260105173755.22515-1-git@danielhodges.dev> Precedence: bulk X-Mailing-List: linux-crypto@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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 --- kernel/bpf/crypto.c | 78 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 8 deletions(-) diff --git a/kernel/bpf/crypto.c b/kernel/bpf/crypto.c index 1ab79a6dec84..f593e7910d3d 100644 --- a/kernel/bpf/crypto.c +++ b/kernel/bpf/crypto.c @@ -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,19 @@ 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) { + *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); @@ -343,6 +351,55 @@ __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->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) @@ -359,6 +416,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 = { @@ -383,6 +443,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.51.0