@@ -171,7 +171,12 @@ bpf_crypto_ctx_create(const struct bpf_crypto_params *params, u32 params__sz,
171171 goto err_module_put ;
172172 }
173173
174- if (!params -> key_len || params -> key_len > sizeof (params -> key )) {
174+ /* Hash operations don't require a key, but cipher operations do */
175+ if (params -> key_len > sizeof (params -> key )) {
176+ * err = - EINVAL ;
177+ goto err_module_put ;
178+ }
179+ if (!params -> key_len && type -> setkey ) {
175180 * err = - EINVAL ;
176181 goto err_module_put ;
177182 }
@@ -195,16 +200,19 @@ bpf_crypto_ctx_create(const struct bpf_crypto_params *params, u32 params__sz,
195200 goto err_free_tfm ;
196201 }
197202
198- * err = type -> setkey (ctx -> tfm , params -> key , params -> key_len );
199- if (* err )
200- goto err_free_tfm ;
203+ if (params -> key_len ) {
204+ * err = type -> setkey (ctx -> tfm , params -> key , params -> key_len );
205+ if (* err )
206+ goto err_free_tfm ;
201207
202- if (type -> get_flags (ctx -> tfm ) & CRYPTO_TFM_NEED_KEY ) {
203- * err = - EINVAL ;
204- goto err_free_tfm ;
208+ if (type -> get_flags (ctx -> tfm ) & CRYPTO_TFM_NEED_KEY ) {
209+ * err = - EINVAL ;
210+ goto err_free_tfm ;
211+ }
205212 }
206213
207- ctx -> siv_len = type -> ivsize (ctx -> tfm ) + type -> statesize (ctx -> tfm );
214+ if (type -> ivsize && type -> statesize )
215+ ctx -> siv_len = type -> ivsize (ctx -> tfm ) + type -> statesize (ctx -> tfm );
208216
209217 refcount_set (& ctx -> usage , 1 );
210218
@@ -343,6 +351,54 @@ __bpf_kfunc int bpf_crypto_encrypt(struct bpf_crypto_ctx *ctx,
343351 return bpf_crypto_crypt (ctx , src_kern , dst_kern , siv_kern , false);
344352}
345353
354+ #if IS_ENABLED (CONFIG_CRYPTO_HASH2 )
355+ /**
356+ * bpf_crypto_hash() - Compute hash using configured context
357+ * @ctx: The crypto context being used. The ctx must be a trusted pointer.
358+ * @data: bpf_dynptr to the input data to hash. Must be a trusted pointer.
359+ * @out: bpf_dynptr to the output buffer. Must be a trusted pointer.
360+ *
361+ * Computes hash of the input data using the crypto context. The output buffer
362+ * must be at least as large as the digest size of the hash algorithm.
363+ */
364+ __bpf_kfunc int bpf_crypto_hash (struct bpf_crypto_ctx * ctx ,
365+ const struct bpf_dynptr * data ,
366+ const struct bpf_dynptr * out )
367+ {
368+ const struct bpf_dynptr_kern * data_kern = (struct bpf_dynptr_kern * )data ;
369+ const struct bpf_dynptr_kern * out_kern = (struct bpf_dynptr_kern * )out ;
370+ u64 data_len , out_len ;
371+ const u8 * data_ptr ;
372+ u8 * out_ptr ;
373+
374+ if (!ctx -> type -> hash )
375+ return - EOPNOTSUPP ;
376+
377+ data_len = __bpf_dynptr_size (data_kern );
378+ out_len = __bpf_dynptr_size (out_kern );
379+
380+ if (data_len == 0 )
381+ return - EINVAL ;
382+
383+ if (!ctx -> type -> digestsize )
384+ return - EOPNOTSUPP ;
385+
386+ unsigned int digestsize = ctx -> type -> digestsize (ctx -> tfm );
387+ if (out_len < digestsize )
388+ return - EINVAL ;
389+
390+ data_ptr = __bpf_dynptr_data (data_kern , data_len );
391+ if (!data_ptr )
392+ return - EINVAL ;
393+
394+ out_ptr = __bpf_dynptr_data_rw (out_kern , out_len );
395+ if (!out_ptr )
396+ return - EINVAL ;
397+
398+ return ctx -> type -> hash (ctx -> tfm , data_ptr , out_ptr , data_len );
399+ }
400+ #endif /* CONFIG_CRYPTO_HASH2 */
401+
346402__bpf_kfunc_end_defs ();
347403
348404BTF_KFUNCS_START (crypt_init_kfunc_btf_ids )
@@ -359,6 +415,9 @@ static const struct btf_kfunc_id_set crypt_init_kfunc_set = {
359415BTF_KFUNCS_START (crypt_kfunc_btf_ids )
360416BTF_ID_FLAGS (func , bpf_crypto_decrypt , KF_RCU )
361417BTF_ID_FLAGS (func , bpf_crypto_encrypt , KF_RCU )
418+ #if IS_ENABLED (CONFIG_CRYPTO_HASH2 )
419+ BTF_ID_FLAGS (func , bpf_crypto_hash , KF_RCU )
420+ #endif
362421BTF_KFUNCS_END (crypt_kfunc_btf_ids )
363422
364423static const struct btf_kfunc_id_set crypt_kfunc_set = {
@@ -383,6 +442,7 @@ static int __init crypto_kfunc_init(void)
383442 ret = register_btf_kfunc_id_set (BPF_PROG_TYPE_SCHED_CLS , & crypt_kfunc_set );
384443 ret = ret ?: register_btf_kfunc_id_set (BPF_PROG_TYPE_SCHED_ACT , & crypt_kfunc_set );
385444 ret = ret ?: register_btf_kfunc_id_set (BPF_PROG_TYPE_XDP , & crypt_kfunc_set );
445+ ret = ret ?: register_btf_kfunc_id_set (BPF_PROG_TYPE_SYSCALL , & crypt_kfunc_set );
386446 ret = ret ?: register_btf_kfunc_id_set (BPF_PROG_TYPE_SYSCALL ,
387447 & crypt_init_kfunc_set );
388448 return ret ?: register_btf_id_dtor_kfuncs (bpf_crypto_dtors ,
0 commit comments