Re: [PATCH net-next 1/3] psp: add crypt-offset and spi-threshold get/set attributes

From: Akhilesh Samineni

Date: Fri Apr 10 2026 - 15:35:35 EST


On Wed, Apr 8, 2026 at 3:07 AM Willem de Bruijn
<willemdebruijn.kernel@xxxxxxxxx> wrote:
>
> Akhilesh Samineni wrote:
> > crypt-offset (Crypt Offset)
> > ----------------------------------
> > The crypt-offset attribute specifies the byte offset within a packet
> > from which encryption begins. This is a per-device attribute that
> > allows a portion of the packet header to remain in plaintext while
> > the rest of the payload is encrypted. This is useful in scenarios
> > where intermediate nodes need to inspect or process a fixed-size
> > header before the encrypted payload.
> >
> > The default value is 0, meaning encryption starts from the beginning
> > of the payload following the PSP header.
> >
> > spi-threshold (SPI Threshold)
> > ------------------------------
> > The SPI (Security Parameter Index) is a 32-bit per-device identifier
> > used to distinguish security associations. As SPI values are allocated
> > monotonically, a threshold is needed to trigger timely SPI rotation
> > before the space is exhausted.
> >
> > The spi-threshold attribute allows userspace to configure the value at
> > which an SPI rotation should be initiated. The default is set to
> > PSP_SPI_THRESHOLD_DEFAULT (~90% of 0x7FFFFFFF), providing a comfortable
> > margin to perform rotation without racing to exhaustion.
> >
> > NOTE: A follow-up series will add notification support to alert
> > subscribed users when the configured spi-threshold is reached, enabling
> > timely SPI rotation.
> >
> > Signed-off-by: Akhilesh Samineni <akhilesh.samineni@xxxxxxxxxxxx>
> > Reviewed-by: Kiran Kella <kiran.kella@xxxxxxxxxxxx>
> > Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@xxxxxxxxxxxx>
> > ---
> > Documentation/netlink/specs/psp.yaml | 13 +++++++++++++
> > include/net/psp/types.h | 7 +++++++
> > include/uapi/linux/psp.h | 2 ++
> > net/psp/psp-nl-gen.c | 6 ++++--
> > net/psp/psp_main.c | 3 +++
> > net/psp/psp_nl.c | 27 +++++++++++++++++++++++----
> > 6 files changed, 52 insertions(+), 6 deletions(-)
> >
> > diff --git a/Documentation/netlink/specs/psp.yaml b/Documentation/netlink/specs/psp.yaml
> > index f3a57782d2cf..b22869be91cf 100644
> > --- a/Documentation/netlink/specs/psp.yaml
> > +++ b/Documentation/netlink/specs/psp.yaml
> > @@ -38,6 +38,15 @@ attribute-sets:
> > type: u32
> > enum: version
> > enum-as-flags: true
> > + -
> > + name: crypt-offset
> > + doc: The offset from the end of the PSP header to the start of the encrypted payload.
>
> In 4 octet units?
>

Yes. crypt-offset is in 4 octet units only. I will update the
description accordingly in the next v2 patch.

> > + type: u8
> > + -
> > + name: spi-threshold
> > + doc: Threshold for the SPI to trigger notification to the user for appropriate rotate action.
> > + type: u32
> > +
> > -
> > name: assoc
> > attributes:
> > @@ -170,6 +179,8 @@ operations:
> > - ifindex
> > - psp-versions-cap
> > - psp-versions-ena
> > + - crypt-offset
> > + - spi-threshold
> > pre: psp-device-get-locked
> > post: psp-device-unlock
> > dump:
> > @@ -193,6 +204,8 @@ operations:
> > attributes:
> > - id
> > - psp-versions-ena
> > + - crypt-offset
> > + - spi-threshold
> > reply:
> > attributes: []
> > pre: psp-device-get-locked
> > diff --git a/include/net/psp/types.h b/include/net/psp/types.h
> > index 25a9096d4e7d..875f7822557f 100644
> > --- a/include/net/psp/types.h
> > +++ b/include/net/psp/types.h
> > @@ -25,6 +25,9 @@ struct psphdr {
> > #define PSP_SPI_KEY_ID GENMASK(30, 0)
> > #define PSP_SPI_KEY_PHASE BIT(31)
> >
> > +/* Default SPI threshold: ~90% of max SPI (0x7FFFFFFF) to allow rotation before exhaustion */
> > +#define PSP_SPI_THRESHOLD_DEFAULT 0x73333333
>
> Do you want to choose a more round number, in either hex or dec?
>

I think we can use 0x70000000; it's approximately 87.5% of the maximum SPI.

> > +
> > #define PSPHDR_CRYPT_OFFSET GENMASK(5, 0)
> >
> > #define PSPHDR_VERFL_SAMPLE BIT(7)
> > @@ -38,9 +41,13 @@ struct psphdr {
> > /**
> > * struct psp_dev_config - PSP device configuration
> > * @versions: PSP versions enabled on the device
> > + * @crypt_offset: crypto offset configured on the device
> > + * @spi_threshold: SPI threshold value on the device
> > */
> > struct psp_dev_config {
> > u32 versions;
> > + u8 crypt_offset;
> > + u32 spi_threshold;
> > };
> >
> > /**
> > diff --git a/include/uapi/linux/psp.h b/include/uapi/linux/psp.h
> > index a3a336488dc3..bb390159dc72 100644
> > --- a/include/uapi/linux/psp.h
> > +++ b/include/uapi/linux/psp.h
> > @@ -22,6 +22,8 @@ enum {
> > PSP_A_DEV_IFINDEX,
> > PSP_A_DEV_PSP_VERSIONS_CAP,
> > PSP_A_DEV_PSP_VERSIONS_ENA,
> > + PSP_A_DEV_CRYPT_OFFSET,
> > + PSP_A_DEV_SPI_THRESHOLD,
> >
> > __PSP_A_DEV_MAX,
> > PSP_A_DEV_MAX = (__PSP_A_DEV_MAX - 1)
> > diff --git a/net/psp/psp-nl-gen.c b/net/psp/psp-nl-gen.c
> > index 22a48d0fa378..e50b8b80955c 100644
> > --- a/net/psp/psp-nl-gen.c
> > +++ b/net/psp/psp-nl-gen.c
> > @@ -23,9 +23,11 @@ static const struct nla_policy psp_dev_get_nl_policy[PSP_A_DEV_ID + 1] = {
> > };
> >
> > /* PSP_CMD_DEV_SET - do */
> > -static const struct nla_policy psp_dev_set_nl_policy[PSP_A_DEV_PSP_VERSIONS_ENA + 1] = {
> > +static const struct nla_policy psp_dev_set_nl_policy[PSP_A_DEV_SPI_THRESHOLD + 1] = {
> > [PSP_A_DEV_ID] = NLA_POLICY_MIN(NLA_U32, 1),
> > [PSP_A_DEV_PSP_VERSIONS_ENA] = NLA_POLICY_MASK(NLA_U32, 0xf),
> > + [PSP_A_DEV_CRYPT_OFFSET] = { .type = NLA_U8, },
> > + [PSP_A_DEV_SPI_THRESHOLD] = { .type = NLA_U32, },
> > };
> >
> > /* PSP_CMD_KEY_ROTATE - do */
> > @@ -75,7 +77,7 @@ static const struct genl_split_ops psp_nl_ops[] = {
> > .doit = psp_nl_dev_set_doit,
> > .post_doit = psp_device_unlock,
> > .policy = psp_dev_set_nl_policy,
> > - .maxattr = PSP_A_DEV_PSP_VERSIONS_ENA,
> > + .maxattr = PSP_A_DEV_SPI_THRESHOLD,
> > .flags = GENL_CMD_CAP_DO,
> > },
> > {
> > diff --git a/net/psp/psp_main.c b/net/psp/psp_main.c
> > index 9508b6c38003..536ee44db09d 100644
> > --- a/net/psp/psp_main.c
> > +++ b/net/psp/psp_main.c
> > @@ -79,6 +79,9 @@ psp_dev_create(struct net_device *netdev,
> > INIT_LIST_HEAD(&psd->stale_assocs);
> > refcount_set(&psd->refcnt, 1);
> >
> > + /* ~90% of 0x7FFFFFFF; allows SPI rotation well before space is exhausted */
>
> Repeat comment. Not needed here.
>

Ack

> > + psd->config.spi_threshold = PSP_SPI_THRESHOLD_DEFAULT;
> > +
> > mutex_lock(&psp_devs_lock);
> > err = xa_alloc_cyclic(&psp_devs, &psd->id, psd, xa_limit_16b,
> > &last_id, GFP_KERNEL);
> > diff --git a/net/psp/psp_nl.c b/net/psp/psp_nl.c
> > index 6afd7707ec12..fbb77460a24b 100644
> > --- a/net/psp/psp_nl.c
> > +++ b/net/psp/psp_nl.c
> > @@ -101,7 +101,9 @@ psp_nl_dev_fill(struct psp_dev *psd, struct sk_buff *rsp,
> > if (nla_put_u32(rsp, PSP_A_DEV_ID, psd->id) ||
> > nla_put_u32(rsp, PSP_A_DEV_IFINDEX, psd->main_netdev->ifindex) ||
> > nla_put_u32(rsp, PSP_A_DEV_PSP_VERSIONS_CAP, psd->caps->versions) ||
> > - nla_put_u32(rsp, PSP_A_DEV_PSP_VERSIONS_ENA, psd->config.versions))
> > + nla_put_u32(rsp, PSP_A_DEV_PSP_VERSIONS_ENA, psd->config.versions) ||
> > + nla_put_u8(rsp, PSP_A_DEV_CRYPT_OFFSET, psd->config.crypt_offset) ||
> > + nla_put_u32(rsp, PSP_A_DEV_SPI_THRESHOLD, psd->config.spi_threshold))
> > goto err_cancel_msg;
> >
> > genlmsg_end(rsp, hdr);
> > @@ -193,6 +195,13 @@ int psp_nl_dev_set_doit(struct sk_buff *skb, struct genl_info *info)
> >
> > memcpy(&new_config, &psd->config, sizeof(new_config));
> >
> > + if (!info->attrs[PSP_A_DEV_PSP_VERSIONS_ENA] &&
> > + !info->attrs[PSP_A_DEV_CRYPT_OFFSET] &&
> > + !info->attrs[PSP_A_DEV_SPI_THRESHOLD]) {
> > + NL_SET_ERR_MSG(info->extack, "No settings present");
> > + return -EINVAL;
> > + }
> > +
> > if (info->attrs[PSP_A_DEV_PSP_VERSIONS_ENA]) {
> > new_config.versions =
> > nla_get_u32(info->attrs[PSP_A_DEV_PSP_VERSIONS_ENA]);
> > @@ -200,9 +209,19 @@ int psp_nl_dev_set_doit(struct sk_buff *skb, struct genl_info *info)
> > NL_SET_ERR_MSG(info->extack, "Requested PSP versions not supported by the device");
> > return -EINVAL;
> > }
> > - } else {
> > - NL_SET_ERR_MSG(info->extack, "No settings present");
> > - return -EINVAL;
> > + }
> > +
> > + if (info->attrs[PSP_A_DEV_CRYPT_OFFSET])
> > + new_config.crypt_offset =
> > + nla_get_u8(info->attrs[PSP_A_DEV_CRYPT_OFFSET]);
>
> PSP defines a 6-bit field in 4 octet units. Does this need bounds checking?
>

Yes, I will add the bound checks in the next v2 patch.
> > +
> > + if (info->attrs[PSP_A_DEV_SPI_THRESHOLD]) {
> > + new_config.spi_threshold =
> > + nla_get_u32(info->attrs[PSP_A_DEV_SPI_THRESHOLD]);
> > + if (new_config.spi_threshold & PSP_SPI_KEY_PHASE) {
> > + NL_SET_ERR_MSG(info->extack, "SPI threshold must not have bit 31 set");
> > + return -EINVAL;
> > + }
> > }
> >
> > rsp = psp_nl_reply_new(info);
> > --
> > 2.45.4
> >
>
>

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature