[PATCH v5 20/23] rust: public_key: Add crypto public key bindings

From: alistair23

Date: Tue Oct 27 2026 - 01:33:24 EST


From: Alistair Francis <alistair.francis@xxxxxxx>

Initial support for the kernel crypto public key (asymmetric-keys) bindings,
which will be used by the SPDM library.

This is just a few functions that the Rust SPDM implementation will use
in the next few commits.

Signed-off-by: Alistair Francis <alistair.francis@xxxxxxx>
---
rust/bindings/bindings_helper.h | 1 +
rust/kernel/lib.rs | 2 +
rust/kernel/public_key.rs | 69 +++++++++++++++++++++++++++++++++
3 files changed, 72 insertions(+)
create mode 100644 rust/kernel/public_key.rs

diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
index a2512fda77e1f..da8855899c530 100644
--- a/rust/bindings/bindings_helper.h
+++ b/rust/bindings/bindings_helper.h
@@ -29,6 +29,7 @@
#include <linux/hrtimer_types.h>

#include <crypto/hash.h>
+#include <crypto/public_key.h>
#include <linux/acpi.h>
#include <linux/gpu_buddy.h>
#include <drm/drm_device.h>
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index f7db5975e7621..e8b652faa3b49 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -122,6 +122,8 @@
pub mod print;
pub mod processor;
pub mod ptr;
+#[cfg(CONFIG_CRYPTO)]
+pub mod public_key;
#[cfg(CONFIG_RUST_PWM_ABSTRACTIONS)]
pub mod pwm;
pub mod ratelimit;
diff --git a/rust/kernel/public_key.rs b/rust/kernel/public_key.rs
new file mode 100644
index 0000000000000..e1d51333c1179
--- /dev/null
+++ b/rust/kernel/public_key.rs
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0
+
+// Copyright (C) 2026 Western Digital
+
+//! Wrappers around the Linux kernel crypto public key APIs.
+//!
+//! C headers: [`include/crypto/public_key.h`](srctree/include/crypto/public_key.h).
+//!
+//! Reference: <https://www.kernel.org/doc/html/latest/crypto/asymmetric-keys.html>
+
+use core::ptr::NonNull;
+use kernel::prelude::*;
+use kernel::{
+ bindings,
+ error::to_result,
+ str::CStr, //
+};
+
+/// Owned `struct public_key` wrapper.
+pub struct PublicKey {
+ key: NonNull<bindings::public_key>,
+}
+
+impl PublicKey {
+ /// Create a Rust `PublicKey` from a valid C `struct public_key` pointer.
+ pub fn from_raw(key: NonNull<bindings::public_key>) -> Self {
+ Self { key }
+ }
+
+ /// Verify a signature using this public key.
+ pub fn verify_signature(
+ &self,
+ signature: &[u8],
+ encoding: &'static CStr,
+ hash_algo: &'static CStr,
+ message: &[u8],
+ ) -> Result {
+ let sig = bindings::public_key_signature {
+ s: signature.as_ptr().cast_mut(),
+ s_size: signature.len() as u32,
+ encoding: encoding.as_char_ptr().cast::<u8>(),
+ hash_algo: hash_algo.as_char_ptr().cast::<u8>(),
+ m: message.as_ptr().cast_mut(),
+ m_size: message.len() as u32,
+ ..Default::default()
+ };
+
+ // SAFETY: `self.key` is a valid public key handle, and `sig` points to
+ // valid signature/message data owned by the caller for the duration of
+ // this call.
+ unsafe {
+ to_result(bindings::public_key_verify_signature(
+ self.key.as_ptr(),
+ &sig,
+ ))
+ }
+ }
+}
+
+impl Drop for PublicKey {
+ fn drop(&mut self) {
+ // SAFETY: `self.key` was either returned by `x509_cert_parse()` or
+ // manually transferred from an `x509_certificate` and has not been
+ // freed yet.
+ unsafe {
+ bindings::public_key_free(self.key.as_ptr());
+ }
+ }
+}
--
2.56.0