99#include <linux/scatterlist.h>
1010#include <linux/skbuff.h>
1111#include <crypto/skcipher.h>
12+ #include <crypto/sig.h>
1213
1314struct bpf_crypto_type_list {
1415 const struct bpf_crypto_type * type ;
@@ -57,6 +58,21 @@ struct bpf_crypto_ctx {
5758 refcount_t usage ;
5859};
5960
61+ #if IS_ENABLED (CONFIG_CRYPTO_ECDSA )
62+ /**
63+ * struct bpf_ecdsa_ctx - refcounted BPF ECDSA context structure
64+ * @tfm: The crypto_sig transform for ECDSA operations
65+ * @rcu: The RCU head used to free the context with RCU safety
66+ * @usage: Object reference counter. When the refcount goes to 0, the
67+ * memory is released with RCU safety.
68+ */
69+ struct bpf_ecdsa_ctx {
70+ struct crypto_sig * tfm ;
71+ struct rcu_head rcu ;
72+ refcount_t usage ;
73+ };
74+ #endif
75+
6076int bpf_crypto_register_type (const struct bpf_crypto_type * type )
6177{
6278 struct bpf_crypto_type_list * node ;
@@ -399,12 +415,206 @@ __bpf_kfunc int bpf_crypto_hash(struct bpf_crypto_ctx *ctx,
399415}
400416#endif /* CONFIG_CRYPTO_HASH2 */
401417
418+ #if IS_ENABLED (CONFIG_CRYPTO_ECDSA )
419+ /**
420+ * bpf_ecdsa_ctx_create() - Create a BPF ECDSA verification context
421+ * @algo_name: bpf_dynptr to the algorithm name (e.g., "p1363(ecdsa-nist-p256)")
422+ * @public_key: bpf_dynptr to the public key in uncompressed format (0x04 || x || y)
423+ * Must be 65 bytes for P-256, 97 for P-384, 133 for P-521
424+ * @err: Pointer to store error code on failure
425+ *
426+ * Creates an ECDSA verification context that can be reused for multiple
427+ * signature verifications. This function uses GFP_KERNEL allocation and
428+ * can only be called from sleepable BPF programs. Uses bpf_dynptr to ensure
429+ * safe memory access without risk of page faults.
430+ */
431+ __bpf_kfunc struct bpf_ecdsa_ctx *
432+ bpf_ecdsa_ctx_create (const struct bpf_dynptr * algo_name ,
433+ const struct bpf_dynptr * public_key , int * err )
434+ {
435+ const struct bpf_dynptr_kern * algo_kern = (struct bpf_dynptr_kern * )algo_name ;
436+ const struct bpf_dynptr_kern * key_kern = (struct bpf_dynptr_kern * )public_key ;
437+ struct bpf_ecdsa_ctx * ctx ;
438+ const char * algo_ptr ;
439+ const u8 * key_ptr ;
440+ u32 algo_len , key_len ;
441+ char algo [64 ];
442+ int ret ;
443+
444+ if (!err )
445+ return NULL ;
446+
447+ algo_len = __bpf_dynptr_size (algo_kern );
448+ key_len = __bpf_dynptr_size (key_kern );
449+
450+ if (algo_len == 0 || algo_len >= sizeof (algo )) {
451+ * err = - EINVAL ;
452+ return NULL ;
453+ }
454+
455+ if (key_len < 65 ) {
456+ * err = - EINVAL ;
457+ return NULL ;
458+ }
459+
460+ algo_ptr = __bpf_dynptr_data (algo_kern , algo_len );
461+ if (!algo_ptr ) {
462+ * err = - EINVAL ;
463+ return NULL ;
464+ }
465+
466+ key_ptr = __bpf_dynptr_data (key_kern , key_len );
467+ if (!key_ptr ) {
468+ * err = - EINVAL ;
469+ return NULL ;
470+ }
471+
472+ if (key_ptr [0 ] != 0x04 ) {
473+ * err = - EINVAL ;
474+ return NULL ;
475+ }
476+
477+ memcpy (algo , algo_ptr , algo_len );
478+ algo [algo_len ] = '\0' ;
479+
480+ ctx = kzalloc (sizeof (* ctx ), GFP_KERNEL );
481+ if (!ctx ) {
482+ * err = - ENOMEM ;
483+ return NULL ;
484+ }
485+
486+ ctx -> tfm = crypto_alloc_sig (algo , 0 , 0 );
487+ if (IS_ERR (ctx -> tfm )) {
488+ * err = PTR_ERR (ctx -> tfm );
489+ kfree (ctx );
490+ return NULL ;
491+ }
492+
493+ ret = crypto_sig_set_pubkey (ctx -> tfm , key_ptr , key_len );
494+ if (ret ) {
495+ * err = ret ;
496+ crypto_free_sig (ctx -> tfm );
497+ kfree (ctx );
498+ return NULL ;
499+ }
500+
501+ refcount_set (& ctx -> usage , 1 );
502+ * err = 0 ;
503+ return ctx ;
504+ }
505+
506+ /**
507+ * bpf_ecdsa_verify() - Verify ECDSA signature using pre-allocated context
508+ * @ctx: ECDSA context created by bpf_ecdsa_ctx_create()
509+ * @message: bpf_dynptr to the message hash to verify. Must be a trusted pointer.
510+ * @signature: bpf_dynptr to the ECDSA signature in r || s format. Must be a trusted pointer.
511+ * Must be 64 bytes for P-256, 96 for P-384, 132 for P-521
512+ *
513+ * Verifies an ECDSA signature using a pre-allocated context. This function
514+ * does not allocate memory and can be used in non-sleepable BPF programs.
515+ * Uses bpf_dynptr to ensure safe memory access without risk of page faults.
516+ */
517+ __bpf_kfunc int bpf_ecdsa_verify (struct bpf_ecdsa_ctx * ctx ,
518+ const struct bpf_dynptr * message ,
519+ const struct bpf_dynptr * signature )
520+ {
521+ const struct bpf_dynptr_kern * msg_kern = (struct bpf_dynptr_kern * )message ;
522+ const struct bpf_dynptr_kern * sig_kern = (struct bpf_dynptr_kern * )signature ;
523+ const u8 * msg_ptr , * sig_ptr ;
524+ u32 msg_len , sig_len ;
525+
526+ if (!ctx )
527+ return - EINVAL ;
528+
529+ msg_len = __bpf_dynptr_size (msg_kern );
530+ sig_len = __bpf_dynptr_size (sig_kern );
531+
532+ if (msg_len == 0 || sig_len == 0 )
533+ return - EINVAL ;
534+
535+ msg_ptr = __bpf_dynptr_data (msg_kern , msg_len );
536+ if (!msg_ptr )
537+ return - EINVAL ;
538+
539+ sig_ptr = __bpf_dynptr_data (sig_kern , sig_len );
540+ if (!sig_ptr )
541+ return - EINVAL ;
542+
543+ return crypto_sig_verify (ctx -> tfm , sig_ptr , sig_len , msg_ptr , msg_len );
544+ }
545+
546+ __bpf_kfunc struct bpf_ecdsa_ctx *
547+ bpf_ecdsa_ctx_acquire (struct bpf_ecdsa_ctx * ctx )
548+ {
549+ if (!refcount_inc_not_zero (& ctx -> usage ))
550+ return NULL ;
551+ return ctx ;
552+ }
553+
554+ static void ecdsa_free_cb (struct rcu_head * head )
555+ {
556+ struct bpf_ecdsa_ctx * ctx = container_of (head , struct bpf_ecdsa_ctx , rcu );
557+
558+ crypto_free_sig (ctx -> tfm );
559+ kfree (ctx );
560+ }
561+
562+ __bpf_kfunc void bpf_ecdsa_ctx_release (struct bpf_ecdsa_ctx * ctx )
563+ {
564+ if (refcount_dec_and_test (& ctx -> usage ))
565+ call_rcu (& ctx -> rcu , ecdsa_free_cb );
566+ }
567+
568+ /**
569+ * bpf_ecdsa_keysize() - Get the key size for ECDSA context
570+ * @ctx: ECDSA context
571+ *
572+ * Returns: Key size in bits, or negative error code on failure
573+ */
574+ __bpf_kfunc int bpf_ecdsa_keysize (struct bpf_ecdsa_ctx * ctx )
575+ {
576+ if (!ctx )
577+ return - EINVAL ;
578+
579+ return crypto_sig_keysize (ctx -> tfm );
580+ }
581+
582+ /**
583+ * bpf_ecdsa_digestsize() - Get the maximum digest size for ECDSA context
584+ * @ctx: ECDSA context
585+ */
586+ __bpf_kfunc int bpf_ecdsa_digestsize (struct bpf_ecdsa_ctx * ctx )
587+ {
588+ if (!ctx )
589+ return - EINVAL ;
590+
591+ return crypto_sig_digestsize (ctx -> tfm );
592+ }
593+
594+ /**
595+ * bpf_ecdsa_maxsize() - Get the maximum signature size for ECDSA context
596+ * @ctx: ECDSA context
597+ */
598+ __bpf_kfunc int bpf_ecdsa_maxsize (struct bpf_ecdsa_ctx * ctx )
599+ {
600+ if (!ctx )
601+ return - EINVAL ;
602+
603+ return crypto_sig_maxsize (ctx -> tfm );
604+ }
605+ #endif /* CONFIG_CRYPTO_ECDSA */
606+
402607__bpf_kfunc_end_defs ();
403608
404609BTF_KFUNCS_START (crypt_init_kfunc_btf_ids )
405610BTF_ID_FLAGS (func , bpf_crypto_ctx_create , KF_ACQUIRE | KF_RET_NULL | KF_SLEEPABLE )
406611BTF_ID_FLAGS (func , bpf_crypto_ctx_release , KF_RELEASE )
407612BTF_ID_FLAGS (func , bpf_crypto_ctx_acquire , KF_ACQUIRE | KF_RCU | KF_RET_NULL )
613+ #if IS_ENABLED (CONFIG_CRYPTO_ECDSA )
614+ BTF_ID_FLAGS (func , bpf_ecdsa_ctx_create , KF_ACQUIRE | KF_RET_NULL | KF_SLEEPABLE )
615+ BTF_ID_FLAGS (func , bpf_ecdsa_ctx_release , KF_RELEASE )
616+ BTF_ID_FLAGS (func , bpf_ecdsa_ctx_acquire , KF_ACQUIRE | KF_RCU | KF_RET_NULL )
617+ #endif
408618BTF_KFUNCS_END (crypt_init_kfunc_btf_ids )
409619
410620static const struct btf_kfunc_id_set crypt_init_kfunc_set = {
@@ -418,6 +628,12 @@ BTF_ID_FLAGS(func, bpf_crypto_encrypt, KF_RCU)
418628#if IS_ENABLED (CONFIG_CRYPTO_HASH2 )
419629BTF_ID_FLAGS (func , bpf_crypto_hash , KF_RCU )
420630#endif
631+ #if IS_ENABLED (CONFIG_CRYPTO_ECDSA )
632+ BTF_ID_FLAGS (func , bpf_ecdsa_verify , 0 )
633+ BTF_ID_FLAGS (func , bpf_ecdsa_keysize , 0 )
634+ BTF_ID_FLAGS (func , bpf_ecdsa_digestsize , 0 )
635+ BTF_ID_FLAGS (func , bpf_ecdsa_maxsize , 0 )
636+ #endif
421637BTF_KFUNCS_END (crypt_kfunc_btf_ids )
422638
423639static const struct btf_kfunc_id_set crypt_kfunc_set = {
@@ -428,6 +644,10 @@ static const struct btf_kfunc_id_set crypt_kfunc_set = {
428644BTF_ID_LIST (bpf_crypto_dtor_ids )
429645BTF_ID (struct , bpf_crypto_ctx )
430646BTF_ID (func , bpf_crypto_ctx_release )
647+ #if IS_ENABLED (CONFIG_CRYPTO_ECDSA )
648+ BTF_ID (struct , bpf_ecdsa_ctx )
649+ BTF_ID (func , bpf_ecdsa_ctx_release )
650+ #endif
431651
432652static int __init crypto_kfunc_init (void )
433653{
@@ -437,6 +657,12 @@ static int __init crypto_kfunc_init(void)
437657 .btf_id = bpf_crypto_dtor_ids [0 ],
438658 .kfunc_btf_id = bpf_crypto_dtor_ids [1 ]
439659 },
660+ #if IS_ENABLED (CONFIG_CRYPTO_ECDSA )
661+ {
662+ .btf_id = bpf_crypto_dtor_ids [2 ],
663+ .kfunc_btf_id = bpf_crypto_dtor_ids [3 ]
664+ },
665+ #endif
440666 };
441667
442668 ret = register_btf_kfunc_id_set (BPF_PROG_TYPE_SCHED_CLS , & crypt_kfunc_set );
@@ -445,6 +671,10 @@ static int __init crypto_kfunc_init(void)
445671 ret = ret ?: register_btf_kfunc_id_set (BPF_PROG_TYPE_SYSCALL , & crypt_kfunc_set );
446672 ret = ret ?: register_btf_kfunc_id_set (BPF_PROG_TYPE_SYSCALL ,
447673 & crypt_init_kfunc_set );
674+ ret = ret ?: register_btf_kfunc_id_set (BPF_PROG_TYPE_SCHED_CLS ,
675+ & crypt_init_kfunc_set );
676+ ret = ret ?: register_btf_kfunc_id_set (BPF_PROG_TYPE_XDP ,
677+ & crypt_init_kfunc_set );
448678 return ret ?: register_btf_id_dtor_kfuncs (bpf_crypto_dtors ,
449679 ARRAY_SIZE (bpf_crypto_dtors ),
450680 THIS_MODULE );
0 commit comments