From: sashiko-bot@kernel.org
To: alistair23@gmail.com, linux-pci@vger.kernel.org,
linux-cxl@vger.kernel.org
Cc: ojeda@kernel.org, gary@garyguo.net
Subject: Re: [PATCH v5 21/23] rust: x509: Add X509 certificate bindings
Date: Tue, 27 Oct 2026 05:45:37 +0000 [thread overview]
Message-ID: <sashiko-outbox-186140@kernel.org> (raw)
In-Reply-To: <20261027052536.1722081-22-alistair.francis@wdc.com>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [Medium] rust: x509: build and link failure when CONFIG_X509_CERTIFICATE_PARSER != y
- [Medium] rust: bindings: build failure in bindings_helper.h when CONFIG_KEYS=n
- [Low] rust: x509: missing inline attributes, import style, and log typo
--
commit bd0a2a1272842d031d7bfad2c6e145a2a0b663dc
Author: Alistair Francis <alistair.francis@wdc.com>
rust: x509: Add X509 certificate bindings
This commit adds initial Rust bindings and a Certificate wrapper around
the kernel X.509 certificate parser APIs for use by the Rust SPDM
implementation.
> diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
> index da8855899c530..66e18819d52b0 100644
> --- a/rust/bindings/bindings_helper.h
> +++ b/rust/bindings/bindings_helper.h
> @@ -39,6 +39,8 @@
> #include <drm/drm_gem_shmem_helper.h>
> #include <drm/drm_gpuvm.h>
> #include <drm/drm_ioctl.h>
> +#include <keys/asymmetric-type.h>
> +#include <keys/x509-parser.h>
[Severity: Medium]
Does including keys/asymmetric-type.h and keys/x509-parser.h
unconditionally break bindgen when CONFIG_KEYS is disabled?
In include/linux/key.h, struct key is only defined under #ifdef CONFIG_KEYS
and is otherwise only forward-declared:
include/linux/key.h:
struct key;
struct net;
#ifdef CONFIG_KEYS
However, include/keys/asymmetric-type.h defines inline functions outside
any #ifdef CONFIG_KEYS guard that dereference const struct key *:
include/keys/asymmetric-type.h:
static inline
const struct asymmetric_key_ids *asymmetric_key_ids(const struct key *key)
{
return key->payload.data[asym_key_ids];
}
When building with CONFIG_RUST=y and CONFIG_KEYS=n, clang fails during
bindgen generation with an incomplete type error on struct key. Should
these headers be guarded or should struct key handling in
include/keys/asymmetric-type.h account for !CONFIG_KEYS?
> diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
> index e8b652faa3b49..aa95aafff8c49 100644
> --- a/rust/kernel/lib.rs
> +++ b/rust/kernel/lib.rs
> @@ -153,6 +153,8 @@
> pub mod usb;
> pub mod validate;
> pub mod workqueue;
> +#[cfg(CONFIG_CRYPTO)]
> +pub mod x509;
[Severity: Medium]
Should the x509 module be gated on
#[cfg(CONFIG_X509_CERTIFICATE_PARSER = "y")] instead of
#[cfg(CONFIG_CRYPTO)]?
Because rust/kernel.o is always built-in when CONFIG_RUST=y, non-generic
methods in rust/kernel/x509.rs such as Certificate::parse(),
Certificate::verify_signed(), and Certificate::drop() are compiled directly
into vmlinux whenever CONFIG_CRYPTO is enabled.
In Certificate::parse() and Certificate::drop(), the code calls
bindings::x509_get_certificate_length(), bindings::x509_cert_parse(), and
bindings::x509_free_certificate(), which are only built under
CONFIG_X509_CERTIFICATE_PARSER in crypto/asymmetric_keys/Makefile:
obj-$(CONFIG_X509_CERTIFICATE_PARSER) += x509_key_parser.o
x509_key_parser-y := \
x509.asn1.o \
x509_akid.asn1.o \
x509_cert_parser.o \
x509_loader.o \
x509_public_key.o
Similarly, Certificate::verify_signed() calls
bindings::public_key_verify_signature(), which is built under
CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE (selected by
CONFIG_X509_CERTIFICATE_PARSER) and falls back to a static inline stub in
include/crypto/public_key.h when disabled, which bindgen does not expose
without a rust_helper_* wrapper.
If CONFIG_CRYPTO is enabled while CONFIG_X509_CERTIFICATE_PARSER is n or m,
won't this fail to compile or fail to link vmlinux with undefined references
from rust/kernel.o?
> diff --git a/rust/kernel/x509.rs b/rust/kernel/x509.rs
> new file mode 100644
> index 0000000000000..1b5bc2a99c91c
> --- /dev/null
> +++ b/rust/kernel/x509.rs
> @@ -0,0 +1,118 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +// Copyright (C) 2026 Western Digital
> +
> +//! Wrappers around the Linux kernel X509 parser APIs.
> +//!
> +//! C headers: [`include/keys/x509-parser.h`](srctree/include/keys/x509-parser.h).
> +
> +use core::ffi::c_void;
> +use core::ptr::{self, NonNull};
> +use kernel::prelude::*;
> +use kernel::{
> + bindings,
> + error::{
> + from_err_ptr,
> + to_result, //
> + },
> + public_key::PublicKey,
> +};
> +
> +/// Owned `struct x509_certificate` wrapper.
> +pub struct Certificate {
> + cert: NonNull<bindings::x509_certificate>,
> +}
> +
> +impl Certificate {
> + /// Parses a DER certificate from `data` and returns it with the length
> + /// of the certificate in bytes.
> + pub fn parse(data: &[u8]) -> Result<(Self, usize)> {
> + // SAFETY: `data.as_ptr()` points to at least `data.len()` valid bytes.
> + let len = unsafe { bindings::x509_get_certificate_length(data.as_ptr(), data.len()) };
> + let len = usize::try_from(len).map_err(|_| {
> + pr_err!("Invalid certificate length\n");
> + EPROTO
> + })?;
> +
> + if len > data.len() {
> + pr_err!("Certificate length is larger then the buffer\n");
> + return Err(EPROTO);
> + }
> +
> + // SAFETY: `data.as_ptr()` points to `data.len()` valid bytes and the
> + // caller has already checked that the DER certificate length fits in
> + // that buffer.
> + let cert = from_err_ptr(unsafe {
> + bindings::x509_cert_parse(data.as_ptr().cast::<c_void>(), len)
> + })?;
> + let cert = NonNull::new(cert).ok_or(EINVAL)?;
> +
> + Ok((Self { cert }, len))
> + }
> +
> + /// Returns the raw pointer for the X.509 certificate.
> + /// This is what is returned from the C function x509_cert_parse()
> + pub fn raw(&self) -> *mut bindings::x509_certificate {
> + self.cert.as_ptr()
> + }
> +
> + /// Check that the certificate is not unsupported or blacklisted.
> + pub fn check_accepted(&self) -> Result {
> + // SAFETY: `self.cert` was returned by `x509_cert_parse()` and remains
> + // valid until dropped.
> + let cert = unsafe { &*self.cert.as_ptr() };
> + if cert.unsupported_sig || cert.blacklisted {
> + pr_err!("Certificate was rejected\n");
> + return Err(EKEYREJECTED);
> + }
> +
> + Ok(())
> + }
> +
> + /// Verify that `child`'s signature is signed by this cert's public/private key.
> + pub fn verify_signed(&self, child: &Self) -> Result {
> + // SAFETY: both certificate pointers were produced by `x509_cert_parse()`
> + // and remain valid until dropped.
> + let (prev, child) = unsafe { (&*self.cert.as_ptr(), &*child.cert.as_ptr()) };
> +
> + let prev_pub = NonNull::new(prev.pub_).ok_or(EINVAL)?;
> + let child_sig = NonNull::new(child.sig).ok_or(EINVAL)?;
> +
> + // SAFETY: `prev_pub` and `child_sig` are valid for at least the duration
> + // of this call.
> + unsafe {
> + to_result(bindings::public_key_verify_signature(
> + prev_pub.as_ptr(),
> + child_sig.as_ptr(),
> + ))
> + }
> + }
> +
> + /// Transfers the public key out of the certificate so the certificate can be
> + /// dropped without freeing the public key.
> + pub fn take_public_key(&mut self) -> Option<PublicKey> {
> + // SAFETY: `self.cert` is a valid certificate pointer.
> + let raw = unsafe { (*self.cert.as_ptr()).pub_ };
> + let key = NonNull::new(raw)?;
> +
> + // SAFETY: `self.cert` is a valid certificate pointer. Clearing `pub_`
> + // transfers ownership of the public key to the returned `PublicKey`.
> + // The `pub_` field will not be freed by `x509_free_certificate()` in
> + // Drop
> + unsafe {
> + (*self.cert.as_ptr()).pub_ = ptr::null_mut();
> + }
> +
> + Some(PublicKey::from_raw(key))
> + }
> +}
[Severity: Low]
This isn't a bug, but there are a few minor style and coding guideline items
in rust/kernel/x509.rs:
1. At the top of rust/kernel/x509.rs, core::ptr::{self, NonNull} should use
vertical import formatting, and core::ffi::c_void is already provided by
kernel::prelude::*.
2. In Certificate::parse(), the error message has a typo ("larger then"
instead of "larger than").
3. Small abstraction methods in the kernel crate such as Certificate::raw(),
Certificate::check_accepted(), Certificate::verify_signed(), and
Certificate::take_public_key() should be annotated with #[inline].
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261027052536.1722081-1-alistair.francis@wdc.com?part=21
next prev parent reply other threads:[~2026-10-27 5:45 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-27 5:25 [PATCH v5 00/23] lib: Rust implementation of SPDM alistair23
2026-10-27 5:25 ` [PATCH v5 01/23] virt: coco: change tsm_register() to use a const struct alistair23
2026-10-27 5:32 ` sashiko-bot
2026-10-27 5:25 ` [PATCH v5 02/23] rust: create basic untrusted data API alistair23
2026-10-27 5:34 ` sashiko-bot
2026-10-27 13:17 ` Benno Lossin
2026-10-27 5:25 ` [PATCH v5 03/23] rust: validate: add `Validate` trait alistair23
2026-10-27 5:33 ` sashiko-bot
2026-10-27 5:25 ` [PATCH v5 04/23] X.509: Make certificate parser public alistair23
2026-10-27 5:33 ` sashiko-bot
2026-10-27 5:25 ` [PATCH v5 05/23] X.509: Parse Subject Alternative Name in certificates alistair23
2026-10-27 5:32 ` sashiko-bot
2026-10-27 5:25 ` [PATCH v5 06/23] X.509: Move certificate length retrieval into new helper alistair23
2026-10-27 5:32 ` sashiko-bot
2026-10-27 5:25 ` [PATCH v5 07/23] rust: add bindings for hash.h alistair23
2026-10-27 5:34 ` sashiko-bot
2026-10-27 5:25 ` [PATCH v5 08/23] rust: device: Expose Device from_raw() publically alistair23
2026-10-27 5:34 ` sashiko-bot
2026-10-27 5:25 ` [PATCH v5 09/23] lib: rspdm: Initial commit of Rust SPDM alistair23
2026-10-27 5:42 ` sashiko-bot
2026-10-27 5:25 ` [PATCH v5 10/23] PCI/TSM: Rename pf0 to host alistair23
2026-10-27 5:33 ` sashiko-bot
2026-10-27 5:25 ` [PATCH v5 11/23] PCI/TSM: Support connecting to PCIe CMA devices alistair23
2026-10-27 5:50 ` sashiko-bot
2026-10-27 5:25 ` [PATCH v5 12/23] PCI/CMA: Add a PCI TSM CMA driver using SPDM alistair23
2026-10-27 5:46 ` sashiko-bot
2026-10-27 5:25 ` [PATCH v5 13/23] PCI/CMA: Validate Subject Alternative Name in certificates alistair23
2026-10-27 5:37 ` sashiko-bot
2026-10-27 5:25 ` [PATCH v5 14/23] lib: rspdm: Support SPDM get_version alistair23
2026-10-27 5:41 ` sashiko-bot
2026-10-27 5:25 ` [PATCH v5 15/23] lib: rspdm: Support SPDM get_capabilities alistair23
2026-10-27 5:36 ` sashiko-bot
2026-10-27 5:25 ` [PATCH v5 16/23] rust: kernel: Add crypto hash bindings alistair23
2026-10-27 5:41 ` sashiko-bot
2026-10-27 5:25 ` [PATCH v5 17/23] lib: rspdm: Support SPDM negotiate_algorithms alistair23
2026-10-27 5:43 ` sashiko-bot
2026-10-27 5:25 ` [PATCH v5 18/23] lib: rspdm: Support SPDM get_digests alistair23
2026-10-27 5:38 ` sashiko-bot
2026-10-27 5:25 ` [PATCH v5 19/23] lib: rspdm: Support SPDM get_certificate alistair23
2026-10-27 5:35 ` sashiko-bot
2026-10-27 5:25 ` [PATCH v5 20/23] rust: public_key: Add crypto public key bindings alistair23
2026-10-27 5:41 ` sashiko-bot
2026-10-27 5:25 ` [PATCH v5 21/23] rust: x509: Add X509 certificate bindings alistair23
2026-10-27 5:45 ` sashiko-bot [this message]
2026-10-27 5:25 ` [PATCH v5 22/23] lib: rspdm: Support SPDM certificate validation alistair23
2026-10-27 5:38 ` sashiko-bot
2026-10-27 5:25 ` [PATCH v5 23/23] lib: rspdm: Support SPDM challenge alistair23
2026-10-27 5:43 ` sashiko-bot
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=sashiko-outbox-186140@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=alistair23@gmail.com \
--cc=gary@garyguo.net \
--cc=linux-cxl@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=ojeda@kernel.org \
--cc=sashiko-reviews@lists.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.