* [dpdk-dev v1] cryptodev: introduce constant-time memory comparison
@ 2025-09-25 10:22 Kai Ji
2025-09-25 10:33 ` [EXTERNAL] " Akhil Goyal
2025-09-26 15:49 ` [dpdk-dev v2 1/2] eal: Add rte_consttime_memsq() to prevent timing attacks memcmp Kai Ji
0 siblings, 2 replies; 16+ messages in thread
From: Kai Ji @ 2025-09-25 10:22 UTC (permalink / raw)
To: dev; +Cc: Kai Ji, stable, Pablo de Lara, Akhil Goyal, Fan Zhang
Add rte_consttime_memcmp() to prevent timing attacks in cryptographic
digest verification operations.
Replace memcmp() with rte_consttime_memcmp() in cryptographic
authentication verification operations across multiple crypto drivers:
* ipsec_mb
* scheduler
Note: OpenSSL crypto driver already uses CRYPTO_memcmp() which
provides equivalent timing attack resistance and is left unchanged.
Bugzilla ID: 1773
Cc: stable@dpdk.org
[0] https://bugs.dpdk.org/show_bug.cgi?id=1773
Signed-off-by: Kai Ji <kai.ji@intel.com>
---
drivers/crypto/ipsec_mb/pmd_aesni_gcm.c | 4 ++--
drivers/crypto/ipsec_mb/pmd_aesni_mb.c | 6 ++---
drivers/crypto/ipsec_mb/pmd_snow3g.c | 2 +-
drivers/crypto/ipsec_mb/pmd_zuc.c | 2 +-
.../scheduler/rte_cryptodev_scheduler.c | 2 +-
lib/cryptodev/rte_cryptodev.h | 23 +++++++++++++++++++
6 files changed, 31 insertions(+), 8 deletions(-)
diff --git a/drivers/crypto/ipsec_mb/pmd_aesni_gcm.c b/drivers/crypto/ipsec_mb/pmd_aesni_gcm.c
index 8d40bd9169..ef8503d904 100644
--- a/drivers/crypto/ipsec_mb/pmd_aesni_gcm.c
+++ b/drivers/crypto/ipsec_mb/pmd_aesni_gcm.c
@@ -206,7 +206,7 @@ post_process_gcm_crypto_op(struct ipsec_mb_qp *qp,
tag, session->req_digest_length);
#endif
- if (memcmp(tag, digest, session->req_digest_length) != 0)
+ if (rte_consttime_memcmp(tag, digest, session->req_digest_length) != 0)
op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
} else {
if (session->req_digest_length != session->gen_digest_length) {
@@ -558,7 +558,7 @@ aesni_gcm_sgl_op_finalize_decryption(const struct aesni_gcm_session *s,
ops.finalize_dec(&s->gdata_key, gdata_ctx, tmpdigest,
s->gen_digest_length);
- return memcmp(digest, tmpdigest, s->req_digest_length) == 0 ? 0
+ return rte_consttime_memcmp(digest, tmpdigest, s->req_digest_length) == 0 ? 0
: EBADMSG;
}
diff --git a/drivers/crypto/ipsec_mb/pmd_aesni_mb.c b/drivers/crypto/ipsec_mb/pmd_aesni_mb.c
index a6c3f09b6f..78fc59c4bf 100644
--- a/drivers/crypto/ipsec_mb/pmd_aesni_mb.c
+++ b/drivers/crypto/ipsec_mb/pmd_aesni_mb.c
@@ -1902,7 +1902,7 @@ verify_docsis_sec_crc(IMB_JOB *job, uint8_t *status)
crc = job->dst + crc_offset;
/* Verify CRC (at the end of the message) */
- if (memcmp(job->auth_tag_output, crc, RTE_ETHER_CRC_LEN) != 0)
+ if (rte_consttime_memcmp(job->auth_tag_output, crc, RTE_ETHER_CRC_LEN) != 0)
*status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
}
@@ -1910,7 +1910,7 @@ static inline void
verify_digest(IMB_JOB *job, void *digest, uint16_t len, uint8_t *status)
{
/* Verify digest if required */
- if (memcmp(job->auth_tag_output, digest, len) != 0)
+ if (rte_consttime_memcmp(job->auth_tag_output, digest, len) != 0)
*status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
}
@@ -2305,7 +2305,7 @@ verify_sync_dgst(struct rte_crypto_sym_vec *vec,
for (i = 0, k = 0; i != vec->num; i++) {
if (vec->status[i] == 0) {
- if (memcmp(vec->digest[i].va, dgst[i], len) != 0)
+ if (rte_consttime_memcmp(vec->digest[i].va, dgst[i], len) != 0)
vec->status[i] = EBADMSG;
else
k++;
diff --git a/drivers/crypto/ipsec_mb/pmd_snow3g.c b/drivers/crypto/ipsec_mb/pmd_snow3g.c
index 65f0e5c568..7c900d11de 100644
--- a/drivers/crypto/ipsec_mb/pmd_snow3g.c
+++ b/drivers/crypto/ipsec_mb/pmd_snow3g.c
@@ -269,7 +269,7 @@ process_snow3g_hash_op(struct ipsec_mb_qp *qp, struct rte_crypto_op **ops,
&session->pKeySched_hash,
iv, src, length_in_bits, dst);
/* Verify digest. */
- if (memcmp(dst, ops[i]->sym->auth.digest.data,
+ if (rte_consttime_memcmp(dst, ops[i]->sym->auth.digest.data,
SNOW3G_DIGEST_LENGTH) != 0)
ops[i]->status =
RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
diff --git a/drivers/crypto/ipsec_mb/pmd_zuc.c b/drivers/crypto/ipsec_mb/pmd_zuc.c
index 44781be1d1..c3f109289b 100644
--- a/drivers/crypto/ipsec_mb/pmd_zuc.c
+++ b/drivers/crypto/ipsec_mb/pmd_zuc.c
@@ -185,7 +185,7 @@ process_zuc_hash_op(struct ipsec_mb_qp *qp, struct rte_crypto_op **ops,
*/
for (i = 0; i < processed_ops; i++)
if (sessions[i]->auth_op == RTE_CRYPTO_AUTH_OP_VERIFY)
- if (memcmp(dst[i], ops[i]->sym->auth.digest.data,
+ if (rte_consttime_memcmp(dst[i], ops[i]->sym->auth.digest.data,
ZUC_DIGEST_LENGTH) != 0)
ops[i]->status =
RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
diff --git a/drivers/crypto/scheduler/rte_cryptodev_scheduler.c b/drivers/crypto/scheduler/rte_cryptodev_scheduler.c
index 1ca8443431..158d6332b8 100644
--- a/drivers/crypto/scheduler/rte_cryptodev_scheduler.c
+++ b/drivers/crypto/scheduler/rte_cryptodev_scheduler.c
@@ -100,7 +100,7 @@ check_sec_cap_equal(const struct rte_security_capability *sec_cap1,
return 0;
if (sec_cap1->protocol == RTE_SECURITY_PROTOCOL_DOCSIS)
- return !memcmp(&sec_cap1->docsis, &sec_cap2->docsis,
+ return !rte_consttime_memcmp(&sec_cap1->docsis, &sec_cap2->docsis,
sizeof(sec_cap1->docsis));
else
return 0;
diff --git a/lib/cryptodev/rte_cryptodev.h b/lib/cryptodev/rte_cryptodev.h
index eaf0e50d37..77f10fbf88 100644
--- a/lib/cryptodev/rte_cryptodev.h
+++ b/lib/cryptodev/rte_cryptodev.h
@@ -78,6 +78,29 @@ extern int rte_cryptodev_logtype;
#define rte_crypto_op_ctophys_offset(c, o) \
(rte_iova_t)((c)->phys_addr + (o))
+/**
+ * Constant-time memory comparison for cryptographic use.
+ * Returns 0 if the memory regions are equal, nonzero otherwise.
+ * Runs in constant time with respect to the length to prevent timing attacks.
+ *
+ * @param a
+ * Pointer to the first memory region.
+ * @param b
+ * Pointer to the second memory region.
+ * @param n
+ * Number of bytes to compare.
+ * @return
+ * 0 if memory regions are equal, nonzero otherwise.
+ */
+#define rte_consttime_memcmp(a, b, n) __extension__ ({ \
+ const volatile uint8_t *__pa = (const volatile uint8_t *)(a); \
+ const volatile uint8_t *__pb = (const volatile uint8_t *)(b); \
+ uint8_t __result = 0; \
+ for (size_t __i = 0; __i < (n); __i++) \
+ __result |= __pa[__i] ^ __pb[__i]; \
+ __result; \
+})
+
/**
* Crypto parameters range description
*/
--
2.34.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* RE: [EXTERNAL] [dpdk-dev v1] cryptodev: introduce constant-time memory comparison
2025-09-25 10:22 [dpdk-dev v1] cryptodev: introduce constant-time memory comparison Kai Ji
@ 2025-09-25 10:33 ` Akhil Goyal
2025-09-25 20:47 ` Thomas Monjalon
2025-09-26 15:49 ` [dpdk-dev v2 1/2] eal: Add rte_consttime_memsq() to prevent timing attacks memcmp Kai Ji
1 sibling, 1 reply; 16+ messages in thread
From: Akhil Goyal @ 2025-09-25 10:33 UTC (permalink / raw)
To: Kai Ji, dev, Stephen Hemminger,
NBU-Contact-Thomas Monjalon (EXTERNAL),
Bruce Richardson, David Marchand
Cc: stable, Pablo de Lara, Fan Zhang
> Add rte_consttime_memcmp() to prevent timing attacks in cryptographic
> digest verification operations.
>
> Replace memcmp() with rte_consttime_memcmp() in cryptographic
> authentication verification operations across multiple crypto drivers:
>
> * ipsec_mb
> * scheduler
>
> Note: OpenSSL crypto driver already uses CRYPTO_memcmp() which
> provides equivalent timing attack resistance and is left unchanged.
>
> Bugzilla ID: 1773
> Cc: stable@dpdk.org
>
> [0] https://bugs.dpdk.org/show_bug.cgi?id=1773
>
> Signed-off-by: Kai Ji <kai.ji@intel.com>
> diff --git a/lib/cryptodev/rte_cryptodev.h b/lib/cryptodev/rte_cryptodev.h
> index eaf0e50d37..77f10fbf88 100644
> --- a/lib/cryptodev/rte_cryptodev.h
> +++ b/lib/cryptodev/rte_cryptodev.h
> @@ -78,6 +78,29 @@ extern int rte_cryptodev_logtype;
> #define rte_crypto_op_ctophys_offset(c, o) \
> (rte_iova_t)((c)->phys_addr + (o))
>
> +/**
> + * Constant-time memory comparison for cryptographic use.
> + * Returns 0 if the memory regions are equal, nonzero otherwise.
> + * Runs in constant time with respect to the length to prevent timing attacks.
> + *
> + * @param a
> + * Pointer to the first memory region.
> + * @param b
> + * Pointer to the second memory region.
> + * @param n
> + * Number of bytes to compare.
> + * @return
> + * 0 if memory regions are equal, nonzero otherwise.
> + */
> +#define rte_consttime_memcmp(a, b, n) __extension__ ({ \
> + const volatile uint8_t *__pa = (const volatile uint8_t *)(a); \
> + const volatile uint8_t *__pb = (const volatile uint8_t *)(b); \
> + uint8_t __result = 0; \
> + for (size_t __i = 0; __i < (n); __i++) \
> + __result |= __pa[__i] ^ __pb[__i]; \
> + __result; \
> +})
> +
> /**
> * Crypto parameters range description
> */
I believe this is not the right place to add this define. It should be somewhere in common eal if it is already not there.
++ Thomas, Stephen, Bruce, David.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [EXTERNAL] [dpdk-dev v1] cryptodev: introduce constant-time memory comparison
2025-09-25 10:33 ` [EXTERNAL] " Akhil Goyal
@ 2025-09-25 20:47 ` Thomas Monjalon
2025-09-26 7:55 ` Bruce Richardson
2025-09-26 8:13 ` Konstantin Ananyev
0 siblings, 2 replies; 16+ messages in thread
From: Thomas Monjalon @ 2025-09-25 20:47 UTC (permalink / raw)
To: Kai Ji
Cc: dev, Stephen Hemminger, Bruce Richardson, David Marchand, stable,
Pablo de Lara, Fan Zhang, Akhil Goyal
25/09/2025 12:33, Akhil Goyal:
> > +/**
> > + * Constant-time memory comparison for cryptographic use.
> > + * Returns 0 if the memory regions are equal, nonzero otherwise.
> > + * Runs in constant time with respect to the length to prevent timing attacks.
> > + *
> > + * @param a
> > + * Pointer to the first memory region.
> > + * @param b
> > + * Pointer to the second memory region.
> > + * @param n
> > + * Number of bytes to compare.
> > + * @return
> > + * 0 if memory regions are equal, nonzero otherwise.
> > + */
> > +#define rte_consttime_memcmp(a, b, n) __extension__ ({ \
> > + const volatile uint8_t *__pa = (const volatile uint8_t *)(a); \
> > + const volatile uint8_t *__pb = (const volatile uint8_t *)(b); \
> > + uint8_t __result = 0; \
> > + for (size_t __i = 0; __i < (n); __i++) \
> > + __result |= __pa[__i] ^ __pb[__i]; \
> > + __result; \
> > +})
>
> I believe this is not the right place to add this define.
> It should be somewhere in common eal if it is already not there.
Yes indeed.
cryptodev is the API for managing crypto devices.
A new memcmp function would be better hosted in libc,
and in EAL for compatibility with all supported libc.
I mean please add it in EAL, and propose it to glibc as well.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [EXTERNAL] [dpdk-dev v1] cryptodev: introduce constant-time memory comparison
2025-09-25 20:47 ` Thomas Monjalon
@ 2025-09-26 7:55 ` Bruce Richardson
2025-09-26 7:58 ` Bruce Richardson
2025-09-26 12:34 ` Morten Brørup
2025-09-26 8:13 ` Konstantin Ananyev
1 sibling, 2 replies; 16+ messages in thread
From: Bruce Richardson @ 2025-09-26 7:55 UTC (permalink / raw)
To: Thomas Monjalon
Cc: Kai Ji, dev, Stephen Hemminger, David Marchand, stable,
Pablo de Lara, Fan Zhang, Akhil Goyal
On Thu, Sep 25, 2025 at 10:47:42PM +0200, Thomas Monjalon wrote:
> 25/09/2025 12:33, Akhil Goyal:
> > > +/**
> > > + * Constant-time memory comparison for cryptographic use.
> > > + * Returns 0 if the memory regions are equal, nonzero otherwise.
> > > + * Runs in constant time with respect to the length to prevent timing attacks.
> > > + *
> > > + * @param a
> > > + * Pointer to the first memory region.
> > > + * @param b
> > > + * Pointer to the second memory region.
> > > + * @param n
> > > + * Number of bytes to compare.
> > > + * @return
> > > + * 0 if memory regions are equal, nonzero otherwise.
> > > + */
> > > +#define rte_consttime_memcmp(a, b, n) __extension__ ({ \
> > > + const volatile uint8_t *__pa = (const volatile uint8_t *)(a); \
> > > + const volatile uint8_t *__pb = (const volatile uint8_t *)(b); \
> > > + uint8_t __result = 0; \
> > > + for (size_t __i = 0; __i < (n); __i++) \
> > > + __result |= __pa[__i] ^ __pb[__i]; \
> > > + __result; \
> > > +})
> >
> > I believe this is not the right place to add this define.
> > It should be somewhere in common eal if it is already not there.
>
> Yes indeed.
> cryptodev is the API for managing crypto devices.
> A new memcmp function would be better hosted in libc,
> and in EAL for compatibility with all supported libc.
>
> I mean please add it in EAL, and propose it to glibc as well.
>
Just for reference, there is a good discussion of such functions and
reference code under MIT license at [1]. After reading that, I note that
the proposed macro above it not strictly a memcmp function because it just
returns a zero/non-zero value, rather than a value indicating which array
value is greater. Therefore some feedback on this code:
* Use an inline function returning bool rather than a macro
* A more accurate name might be rte_consttime_memneq, since the code
returns 0 (false) if equal.
Regars,
/Bruce
[1] https://github.com/chmike/cst_time_memcmp
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [EXTERNAL] [dpdk-dev v1] cryptodev: introduce constant-time memory comparison
2025-09-26 7:55 ` Bruce Richardson
@ 2025-09-26 7:58 ` Bruce Richardson
2025-09-26 12:34 ` Morten Brørup
1 sibling, 0 replies; 16+ messages in thread
From: Bruce Richardson @ 2025-09-26 7:58 UTC (permalink / raw)
To: Thomas Monjalon
Cc: Kai Ji, dev, Stephen Hemminger, David Marchand, stable,
Pablo de Lara, Fan Zhang, Akhil Goyal
On Fri, Sep 26, 2025 at 08:55:55AM +0100, Bruce Richardson wrote:
> On Thu, Sep 25, 2025 at 10:47:42PM +0200, Thomas Monjalon wrote:
> > 25/09/2025 12:33, Akhil Goyal:
> > > > +/**
> > > > + * Constant-time memory comparison for cryptographic use.
> > > > + * Returns 0 if the memory regions are equal, nonzero otherwise.
> > > > + * Runs in constant time with respect to the length to prevent timing attacks.
> > > > + *
> > > > + * @param a
> > > > + * Pointer to the first memory region.
> > > > + * @param b
> > > > + * Pointer to the second memory region.
> > > > + * @param n
> > > > + * Number of bytes to compare.
> > > > + * @return
> > > > + * 0 if memory regions are equal, nonzero otherwise.
> > > > + */
> > > > +#define rte_consttime_memcmp(a, b, n) __extension__ ({ \
> > > > + const volatile uint8_t *__pa = (const volatile uint8_t *)(a); \
> > > > + const volatile uint8_t *__pb = (const volatile uint8_t *)(b); \
> > > > + uint8_t __result = 0; \
> > > > + for (size_t __i = 0; __i < (n); __i++) \
> > > > + __result |= __pa[__i] ^ __pb[__i]; \
> > > > + __result; \
> > > > +})
> > >
> > > I believe this is not the right place to add this define.
> > > It should be somewhere in common eal if it is already not there.
> >
> > Yes indeed.
> > cryptodev is the API for managing crypto devices.
> > A new memcmp function would be better hosted in libc,
> > and in EAL for compatibility with all supported libc.
> >
> > I mean please add it in EAL, and propose it to glibc as well.
> >
>
> Just for reference, there is a good discussion of such functions and
> reference code under MIT license at [1]. After reading that, I note that
> the proposed macro above it not strictly a memcmp function because it just
> returns a zero/non-zero value, rather than a value indicating which array
> value is greater. Therefore some feedback on this code:
> * Use an inline function returning bool rather than a macro
> * A more accurate name might be rte_consttime_memneq, since the code
> returns 0 (false) if equal.
>
Or better, change the return value from result to !result to make it a
"memeq" function, which also has the benefit of clamping return values to
just 0 and 1.
> Regars,
> /Bruce
>
> [1] https://github.com/chmike/cst_time_memcmp
^ permalink raw reply [flat|nested] 16+ messages in thread
* RE: [EXTERNAL] [dpdk-dev v1] cryptodev: introduce constant-time memory comparison
2025-09-26 7:55 ` Bruce Richardson
2025-09-26 7:58 ` Bruce Richardson
@ 2025-09-26 12:34 ` Morten Brørup
1 sibling, 0 replies; 16+ messages in thread
From: Morten Brørup @ 2025-09-26 12:34 UTC (permalink / raw)
To: Bruce Richardson, Thomas Monjalon, Akhil Goyal
Cc: Kai Ji, dev, Stephen Hemminger, stable, David Marchand,
Pablo de Lara, Fan Zhang
> From: Bruce Richardson [mailto:bruce.richardson@intel.com]
> Sent: Friday, 26 September 2025 09.56
>
> On Thu, Sep 25, 2025 at 10:47:42PM +0200, Thomas Monjalon wrote:
> > 25/09/2025 12:33, Akhil Goyal:
> > > > +/**
> > > > + * Constant-time memory comparison for cryptographic use.
> > > > + * Returns 0 if the memory regions are equal, nonzero otherwise.
> > > > + * Runs in constant time with respect to the length to prevent
> timing attacks.
> > > > + *
> > > > + * @param a
> > > > + * Pointer to the first memory region.
> > > > + * @param b
> > > > + * Pointer to the second memory region.
> > > > + * @param n
> > > > + * Number of bytes to compare.
> > > > + * @return
> > > > + * 0 if memory regions are equal, nonzero otherwise.
> > > > + */
> > > > +#define rte_consttime_memcmp(a, b, n) __extension__ ({ \
> > > > + const volatile uint8_t *__pa = (const volatile uint8_t
> *)(a); \
> > > > + const volatile uint8_t *__pb = (const volatile uint8_t
> *)(b); \
> > > > + uint8_t __result = 0; \
> > > > + for (size_t __i = 0; __i < (n); __i++) \
> > > > + __result |= __pa[__i] ^ __pb[__i]; \
> > > > + __result; \
> > > > +})
> > >
> > > I believe this is not the right place to add this define.
> > > It should be somewhere in common eal if it is already not there.
> >
> > Yes indeed.
> > cryptodev is the API for managing crypto devices.
> > A new memcmp function would be better hosted in libc,
> > and in EAL for compatibility with all supported libc.
> >
> > I mean please add it in EAL, and propose it to glibc as well.
> >
>
> Just for reference, there is a good discussion of such functions and
> reference code under MIT license at [1]. After reading that, I note
> that
> the proposed macro above it not strictly a memcmp function because it
> just
> returns a zero/non-zero value, rather than a value indicating which
> array
> value is greater. Therefore some feedback on this code:
> * Use an inline function returning bool rather than a macro
> * A more accurate name might be rte_consttime_memneq, since the code
> returns 0 (false) if equal.
>
> Regars,
> /Bruce
>
> [1] https://github.com/chmike/cst_time_memcmp
When deciding on the function name and location:
Can we foresee other consttime or crypto-purpose functions that should reside in the EAL?
There's already rte_memzero_explicit() in rte_memory.h:
https://elixir.bootlin.com/dpdk/v25.07/source/lib/eal/include/rte_memory.h#L747
Please use the same naming convention, i.e. put the function purpose first, and append the special behavior as postfix:
rte_memneq_consttime(), e.g.:
bool rte_memneq_consttime(const void *s1, const void *s2, size_t n);
IMHO, eal/include/rte_memory.h is a good location for this too.
Should it be an inline or normal function?
If it's primarily for fast path, inline is preferable.
You could also add the inverse function, i.e. add both memneq and memeq.
^ permalink raw reply [flat|nested] 16+ messages in thread
* RE: [EXTERNAL] [dpdk-dev v1] cryptodev: introduce constant-time memory comparison
2025-09-25 20:47 ` Thomas Monjalon
2025-09-26 7:55 ` Bruce Richardson
@ 2025-09-26 8:13 ` Konstantin Ananyev
2025-09-26 8:16 ` Konstantin Ananyev
1 sibling, 1 reply; 16+ messages in thread
From: Konstantin Ananyev @ 2025-09-26 8:13 UTC (permalink / raw)
To: Thomas Monjalon, Kai Ji
Cc: dev, Stephen Hemminger, Bruce Richardson, David Marchand, stable,
Pablo de Lara, Fan Zhang, Akhil Goyal
> 25/09/2025 12:33, Akhil Goyal:
> > > +/**
> > > + * Constant-time memory comparison for cryptographic use.
> > > + * Returns 0 if the memory regions are equal, nonzero otherwise.
> > > + * Runs in constant time with respect to the length to prevent timing attacks.
> > > + *
> > > + * @param a
> > > + * Pointer to the first memory region.
> > > + * @param b
> > > + * Pointer to the second memory region.
> > > + * @param n
> > > + * Number of bytes to compare.
> > > + * @return
> > > + * 0 if memory regions are equal, nonzero otherwise.
> > > + */
> > > +#define rte_consttime_memcmp(a, b, n) __extension__ ({ \
> > > + const volatile uint8_t *__pa = (const volatile uint8_t *)(a); \
> > > + const volatile uint8_t *__pb = (const volatile uint8_t *)(b); \
> > > + uint8_t __result = 0; \
> > > + for (size_t __i = 0; __i < (n); __i++) \
> > > + __result |= __pa[__i] ^ __pb[__i]; \
> > > + __result; \
> > > +})
> >
> > I believe this is not the right place to add this define.
> > It should be somewhere in common eal if it is already not there.
>
> Yes indeed.
> cryptodev is the API for managing crypto devices.
> A new memcmp function would be better hosted in libc,
> and in EAL for compatibility with all supported libc.
>
> I mean please add it in EAL, and propose it to glibc as well.
Stupid q: what's wrong with standard C memcmp() function?
^ permalink raw reply [flat|nested] 16+ messages in thread
* RE: [EXTERNAL] [dpdk-dev v1] cryptodev: introduce constant-time memory comparison
2025-09-26 8:13 ` Konstantin Ananyev
@ 2025-09-26 8:16 ` Konstantin Ananyev
0 siblings, 0 replies; 16+ messages in thread
From: Konstantin Ananyev @ 2025-09-26 8:16 UTC (permalink / raw)
To: Konstantin Ananyev, Thomas Monjalon, Kai Ji
Cc: dev, Stephen Hemminger, Bruce Richardson, David Marchand, stable,
Pablo de Lara, Fan Zhang, Akhil Goyal
>
>
> > 25/09/2025 12:33, Akhil Goyal:
> > > > +/**
> > > > + * Constant-time memory comparison for cryptographic use.
> > > > + * Returns 0 if the memory regions are equal, nonzero otherwise.
> > > > + * Runs in constant time with respect to the length to prevent timing
> attacks.
> > > > + *
> > > > + * @param a
> > > > + * Pointer to the first memory region.
> > > > + * @param b
> > > > + * Pointer to the second memory region.
> > > > + * @param n
> > > > + * Number of bytes to compare.
> > > > + * @return
> > > > + * 0 if memory regions are equal, nonzero otherwise.
> > > > + */
> > > > +#define rte_consttime_memcmp(a, b, n) __extension__ ({ \
> > > > + const volatile uint8_t *__pa = (const volatile uint8_t *)(a); \
> > > > + const volatile uint8_t *__pb = (const volatile uint8_t *)(b); \
> > > > + uint8_t __result = 0; \
> > > > + for (size_t __i = 0; __i < (n); __i++) \
> > > > + __result |= __pa[__i] ^ __pb[__i]; \
> > > > + __result; \
> > > > +})
> > >
> > > I believe this is not the right place to add this define.
> > > It should be somewhere in common eal if it is already not there.
> >
> > Yes indeed.
> > cryptodev is the API for managing crypto devices.
> > A new memcmp function would be better hosted in libc,
> > and in EAL for compatibility with all supported libc.
> >
> > I mean please add it in EAL, and propose it to glibc as well.
>
> Stupid q: what's wrong with standard C memcmp() function?
Ah, sorry, didn't read properly.
Please disregard, and yes - might be EAL is the right place for it.
^ permalink raw reply [flat|nested] 16+ messages in thread
* [dpdk-dev v2 1/2] eal: Add rte_consttime_memsq() to prevent timing attacks memcmp.
2025-09-25 10:22 [dpdk-dev v1] cryptodev: introduce constant-time memory comparison Kai Ji
2025-09-25 10:33 ` [EXTERNAL] " Akhil Goyal
@ 2025-09-26 15:49 ` Kai Ji
2025-09-26 15:49 ` [dpdk-dev v2 2/2] crypto/ipsec-mb: use constant-time memory comparison Kai Ji
` (2 more replies)
1 sibling, 3 replies; 16+ messages in thread
From: Kai Ji @ 2025-09-26 15:49 UTC (permalink / raw)
To: dev
Cc: gakhil, konstantin.ananyev, bruce.richardson, thomas, stephen,
Kai Ji, stable
Bugzilla ID: 1773
Cc: stable@dpdk.org
[0] https://bugs.dpdk.org/show_bug.cgi?id=1773
Signed-off-by: Kai Ji <kai.ji@intel.com>
---
lib/eal/include/rte_common.h | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/lib/eal/include/rte_common.h b/lib/eal/include/rte_common.h
index 9e7d84f929..ddbba083be 100644
--- a/lib/eal/include/rte_common.h
+++ b/lib/eal/include/rte_common.h
@@ -700,6 +700,40 @@ rte_is_aligned(const void * const __rte_restrict ptr, const unsigned int align)
return ((uintptr_t)ptr & (align - 1)) == 0;
}
+/**
+ * Constant-time memory inequality comparison.
+ *
+ * This function compares two memory regions in constant time, making it
+ * resistant to timing side-channel attacks. The execution time depends only
+ * on the length parameter, not on the actual data values being compared.
+ *
+ * This is particularly important for cryptographic operations where timing
+ * differences could leak information about secret keys, passwords, or other
+ * sensitive data.
+ *
+ * @param a
+ * Pointer to the first memory region to compare
+ * @param b
+ * Pointer to the second memory region to compare
+ * @param n
+ * Number of bytes to compare
+ * @return
+ * false if the memory regions are identical, true if they differ
+ */
+static inline bool
+rte_consttime_memneq(const void *a, const void *b, size_t n)
+{
+ const volatile uint8_t *pa = (const volatile uint8_t *)a;
+ const volatile uint8_t *pb = (const volatile uint8_t *)b;
+ uint8_t result = 0;
+ size_t i;
+
+ for (i = 0; i < n; i++)
+ result |= pa[i] ^ pb[i];
+
+ return result != 0;
+}
+
/*********** Macros for compile type checks ********/
/* Workaround for toolchain issues with missing C11 macro in FreeBSD */
--
2.34.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [dpdk-dev v2 2/2] crypto/ipsec-mb: use constant-time memory comparison
2025-09-26 15:49 ` [dpdk-dev v2 1/2] eal: Add rte_consttime_memsq() to prevent timing attacks memcmp Kai Ji
@ 2025-09-26 15:49 ` Kai Ji
2025-09-26 16:02 ` [dpdk-dev v3 1/2] eal: Add rte_consttime_memneq() to prevent timing attacks memcmp Kai Ji
2025-09-26 18:07 ` [dpdk-dev v2 1/2] eal: Add rte_consttime_memsq() " Stephen Hemminger
2 siblings, 0 replies; 16+ messages in thread
From: Kai Ji @ 2025-09-26 15:49 UTC (permalink / raw)
To: dev
Cc: gakhil, konstantin.ananyev, bruce.richardson, thomas, stephen,
Kai Ji, stable
Replace memcmp() with rte_consttime_memsq() in cryptographic
authentication verification operations across multiple crypto drivers:
* ipsec_mb
Note: OpenSSL crypto driver already uses CRYPTO_memcmp() which
provides equivalent timing attack resistance and is left unchanged.
Note: scheduler driver memcmp stays unchanged as its not secret data
comparison and actually faster with no timing attack risk.
Bugzilla ID: 1773
Cc: stable@dpdk.org
[0] https://bugs.dpdk.org/show_bug.cgi?id=1773
Signed-off-by: Kai Ji <kai.ji@intel.com>
---
drivers/crypto/ipsec_mb/pmd_aesni_gcm.c | 5 ++---
drivers/crypto/ipsec_mb/pmd_aesni_mb.c | 6 +++---
drivers/crypto/ipsec_mb/pmd_snow3g.c | 4 ++--
drivers/crypto/ipsec_mb/pmd_zuc.c | 4 ++--
4 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/drivers/crypto/ipsec_mb/pmd_aesni_gcm.c b/drivers/crypto/ipsec_mb/pmd_aesni_gcm.c
index 8d40bd9169..bfe119bf77 100644
--- a/drivers/crypto/ipsec_mb/pmd_aesni_gcm.c
+++ b/drivers/crypto/ipsec_mb/pmd_aesni_gcm.c
@@ -206,7 +206,7 @@ post_process_gcm_crypto_op(struct ipsec_mb_qp *qp,
tag, session->req_digest_length);
#endif
- if (memcmp(tag, digest, session->req_digest_length) != 0)
+ if (rte_consttime_memneq(tag, digest, session->req_digest_length))
op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
} else {
if (session->req_digest_length != session->gen_digest_length) {
@@ -558,8 +558,7 @@ aesni_gcm_sgl_op_finalize_decryption(const struct aesni_gcm_session *s,
ops.finalize_dec(&s->gdata_key, gdata_ctx, tmpdigest,
s->gen_digest_length);
- return memcmp(digest, tmpdigest, s->req_digest_length) == 0 ? 0
- : EBADMSG;
+ return rte_consttime_memneq(digest, tmpdigest, s->req_digest_length) ? EBADMSG : 0;
}
static inline void
diff --git a/drivers/crypto/ipsec_mb/pmd_aesni_mb.c b/drivers/crypto/ipsec_mb/pmd_aesni_mb.c
index a6c3f09b6f..f23a09376e 100644
--- a/drivers/crypto/ipsec_mb/pmd_aesni_mb.c
+++ b/drivers/crypto/ipsec_mb/pmd_aesni_mb.c
@@ -1902,7 +1902,7 @@ verify_docsis_sec_crc(IMB_JOB *job, uint8_t *status)
crc = job->dst + crc_offset;
/* Verify CRC (at the end of the message) */
- if (memcmp(job->auth_tag_output, crc, RTE_ETHER_CRC_LEN) != 0)
+ if (rte_consttime_memneq(job->auth_tag_output, crc, RTE_ETHER_CRC_LEN))
*status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
}
@@ -1910,7 +1910,7 @@ static inline void
verify_digest(IMB_JOB *job, void *digest, uint16_t len, uint8_t *status)
{
/* Verify digest if required */
- if (memcmp(job->auth_tag_output, digest, len) != 0)
+ if (rte_consttime_memneq(job->auth_tag_output, digest, len))
*status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
}
@@ -2305,7 +2305,7 @@ verify_sync_dgst(struct rte_crypto_sym_vec *vec,
for (i = 0, k = 0; i != vec->num; i++) {
if (vec->status[i] == 0) {
- if (memcmp(vec->digest[i].va, dgst[i], len) != 0)
+ if (rte_consttime_memneq(vec->digest[i].va, dgst[i], len))
vec->status[i] = EBADMSG;
else
k++;
diff --git a/drivers/crypto/ipsec_mb/pmd_snow3g.c b/drivers/crypto/ipsec_mb/pmd_snow3g.c
index 65f0e5c568..befb60e473 100644
--- a/drivers/crypto/ipsec_mb/pmd_snow3g.c
+++ b/drivers/crypto/ipsec_mb/pmd_snow3g.c
@@ -269,8 +269,8 @@ process_snow3g_hash_op(struct ipsec_mb_qp *qp, struct rte_crypto_op **ops,
&session->pKeySched_hash,
iv, src, length_in_bits, dst);
/* Verify digest. */
- if (memcmp(dst, ops[i]->sym->auth.digest.data,
- SNOW3G_DIGEST_LENGTH) != 0)
+ if (rte_consttime_memneq(dst, ops[i]->sym->auth.digest.data,
+ SNOW3G_DIGEST_LENGTH))
ops[i]->status =
RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
} else {
diff --git a/drivers/crypto/ipsec_mb/pmd_zuc.c b/drivers/crypto/ipsec_mb/pmd_zuc.c
index 44781be1d1..8f0be0465a 100644
--- a/drivers/crypto/ipsec_mb/pmd_zuc.c
+++ b/drivers/crypto/ipsec_mb/pmd_zuc.c
@@ -185,8 +185,8 @@ process_zuc_hash_op(struct ipsec_mb_qp *qp, struct rte_crypto_op **ops,
*/
for (i = 0; i < processed_ops; i++)
if (sessions[i]->auth_op == RTE_CRYPTO_AUTH_OP_VERIFY)
- if (memcmp(dst[i], ops[i]->sym->auth.digest.data,
- ZUC_DIGEST_LENGTH) != 0)
+ if (rte_consttime_memneq(dst[i], ops[i]->sym->auth.digest.data,
+ ZUC_DIGEST_LENGTH))
ops[i]->status =
RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
--
2.34.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [dpdk-dev v3 1/2] eal: Add rte_consttime_memneq() to prevent timing attacks memcmp.
2025-09-26 15:49 ` [dpdk-dev v2 1/2] eal: Add rte_consttime_memsq() to prevent timing attacks memcmp Kai Ji
2025-09-26 15:49 ` [dpdk-dev v2 2/2] crypto/ipsec-mb: use constant-time memory comparison Kai Ji
@ 2025-09-26 16:02 ` Kai Ji
2025-09-26 16:02 ` [dpdk-dev v3 2/2] crypto/ipsec-mb: use constant-time memory comparison Kai Ji
` (2 more replies)
2025-09-26 18:07 ` [dpdk-dev v2 1/2] eal: Add rte_consttime_memsq() " Stephen Hemminger
2 siblings, 3 replies; 16+ messages in thread
From: Kai Ji @ 2025-09-26 16:02 UTC (permalink / raw)
To: dev; +Cc: gakhil, konstantin.ananyev, bruce.richardson, thomas, stephen, Kai Ji
Bugzilla ID: 1773
https://bugs.dpdk.org/show_bug.cgi?id=1773
Signed-off-by: Kai Ji <kai.ji@intel.com>
---
lib/eal/include/rte_common.h | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/lib/eal/include/rte_common.h b/lib/eal/include/rte_common.h
index 9e7d84f929..ddbba083be 100644
--- a/lib/eal/include/rte_common.h
+++ b/lib/eal/include/rte_common.h
@@ -700,6 +700,40 @@ rte_is_aligned(const void * const __rte_restrict ptr, const unsigned int align)
return ((uintptr_t)ptr & (align - 1)) == 0;
}
+/**
+ * Constant-time memory inequality comparison.
+ *
+ * This function compares two memory regions in constant time, making it
+ * resistant to timing side-channel attacks. The execution time depends only
+ * on the length parameter, not on the actual data values being compared.
+ *
+ * This is particularly important for cryptographic operations where timing
+ * differences could leak information about secret keys, passwords, or other
+ * sensitive data.
+ *
+ * @param a
+ * Pointer to the first memory region to compare
+ * @param b
+ * Pointer to the second memory region to compare
+ * @param n
+ * Number of bytes to compare
+ * @return
+ * false if the memory regions are identical, true if they differ
+ */
+static inline bool
+rte_consttime_memneq(const void *a, const void *b, size_t n)
+{
+ const volatile uint8_t *pa = (const volatile uint8_t *)a;
+ const volatile uint8_t *pb = (const volatile uint8_t *)b;
+ uint8_t result = 0;
+ size_t i;
+
+ for (i = 0; i < n; i++)
+ result |= pa[i] ^ pb[i];
+
+ return result != 0;
+}
+
/*********** Macros for compile type checks ********/
/* Workaround for toolchain issues with missing C11 macro in FreeBSD */
--
2.34.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [dpdk-dev v3 2/2] crypto/ipsec-mb: use constant-time memory comparison
2025-09-26 16:02 ` [dpdk-dev v3 1/2] eal: Add rte_consttime_memneq() to prevent timing attacks memcmp Kai Ji
@ 2025-09-26 16:02 ` Kai Ji
2025-09-26 18:12 ` [dpdk-dev v3 1/2] eal: Add rte_consttime_memneq() to prevent timing attacks memcmp Stephen Hemminger
2025-09-26 19:17 ` Morten Brørup
2 siblings, 0 replies; 16+ messages in thread
From: Kai Ji @ 2025-09-26 16:02 UTC (permalink / raw)
To: dev; +Cc: gakhil, konstantin.ananyev, bruce.richardson, thomas, stephen, Kai Ji
Replace memcmp() with rte_consttime_memneq() in cryptographic
authentication verification operations in ipsec_mb crypto driver.
Note: OpenSSL crypto driver already uses CRYPTO_memcmp() which
provides equivalent timing attack resistance and is left unchanged.
Note: scheduler driver memcmp stays unchanged as its not secret data
comparison and actually faster with no timing attack risk.
Bugzilla ID: 1773
https://bugs.dpdk.org/show_bug.cgi?id=1773
Signed-off-by: Kai Ji <kai.ji@intel.com>
---
drivers/crypto/ipsec_mb/pmd_aesni_gcm.c | 5 ++---
drivers/crypto/ipsec_mb/pmd_aesni_mb.c | 6 +++---
drivers/crypto/ipsec_mb/pmd_snow3g.c | 4 ++--
drivers/crypto/ipsec_mb/pmd_zuc.c | 4 ++--
4 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/drivers/crypto/ipsec_mb/pmd_aesni_gcm.c b/drivers/crypto/ipsec_mb/pmd_aesni_gcm.c
index 8d40bd9169..bfe119bf77 100644
--- a/drivers/crypto/ipsec_mb/pmd_aesni_gcm.c
+++ b/drivers/crypto/ipsec_mb/pmd_aesni_gcm.c
@@ -206,7 +206,7 @@ post_process_gcm_crypto_op(struct ipsec_mb_qp *qp,
tag, session->req_digest_length);
#endif
- if (memcmp(tag, digest, session->req_digest_length) != 0)
+ if (rte_consttime_memneq(tag, digest, session->req_digest_length))
op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
} else {
if (session->req_digest_length != session->gen_digest_length) {
@@ -558,8 +558,7 @@ aesni_gcm_sgl_op_finalize_decryption(const struct aesni_gcm_session *s,
ops.finalize_dec(&s->gdata_key, gdata_ctx, tmpdigest,
s->gen_digest_length);
- return memcmp(digest, tmpdigest, s->req_digest_length) == 0 ? 0
- : EBADMSG;
+ return rte_consttime_memneq(digest, tmpdigest, s->req_digest_length) ? EBADMSG : 0;
}
static inline void
diff --git a/drivers/crypto/ipsec_mb/pmd_aesni_mb.c b/drivers/crypto/ipsec_mb/pmd_aesni_mb.c
index a6c3f09b6f..f23a09376e 100644
--- a/drivers/crypto/ipsec_mb/pmd_aesni_mb.c
+++ b/drivers/crypto/ipsec_mb/pmd_aesni_mb.c
@@ -1902,7 +1902,7 @@ verify_docsis_sec_crc(IMB_JOB *job, uint8_t *status)
crc = job->dst + crc_offset;
/* Verify CRC (at the end of the message) */
- if (memcmp(job->auth_tag_output, crc, RTE_ETHER_CRC_LEN) != 0)
+ if (rte_consttime_memneq(job->auth_tag_output, crc, RTE_ETHER_CRC_LEN))
*status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
}
@@ -1910,7 +1910,7 @@ static inline void
verify_digest(IMB_JOB *job, void *digest, uint16_t len, uint8_t *status)
{
/* Verify digest if required */
- if (memcmp(job->auth_tag_output, digest, len) != 0)
+ if (rte_consttime_memneq(job->auth_tag_output, digest, len))
*status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
}
@@ -2305,7 +2305,7 @@ verify_sync_dgst(struct rte_crypto_sym_vec *vec,
for (i = 0, k = 0; i != vec->num; i++) {
if (vec->status[i] == 0) {
- if (memcmp(vec->digest[i].va, dgst[i], len) != 0)
+ if (rte_consttime_memneq(vec->digest[i].va, dgst[i], len))
vec->status[i] = EBADMSG;
else
k++;
diff --git a/drivers/crypto/ipsec_mb/pmd_snow3g.c b/drivers/crypto/ipsec_mb/pmd_snow3g.c
index 65f0e5c568..befb60e473 100644
--- a/drivers/crypto/ipsec_mb/pmd_snow3g.c
+++ b/drivers/crypto/ipsec_mb/pmd_snow3g.c
@@ -269,8 +269,8 @@ process_snow3g_hash_op(struct ipsec_mb_qp *qp, struct rte_crypto_op **ops,
&session->pKeySched_hash,
iv, src, length_in_bits, dst);
/* Verify digest. */
- if (memcmp(dst, ops[i]->sym->auth.digest.data,
- SNOW3G_DIGEST_LENGTH) != 0)
+ if (rte_consttime_memneq(dst, ops[i]->sym->auth.digest.data,
+ SNOW3G_DIGEST_LENGTH))
ops[i]->status =
RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
} else {
diff --git a/drivers/crypto/ipsec_mb/pmd_zuc.c b/drivers/crypto/ipsec_mb/pmd_zuc.c
index 44781be1d1..8f0be0465a 100644
--- a/drivers/crypto/ipsec_mb/pmd_zuc.c
+++ b/drivers/crypto/ipsec_mb/pmd_zuc.c
@@ -185,8 +185,8 @@ process_zuc_hash_op(struct ipsec_mb_qp *qp, struct rte_crypto_op **ops,
*/
for (i = 0; i < processed_ops; i++)
if (sessions[i]->auth_op == RTE_CRYPTO_AUTH_OP_VERIFY)
- if (memcmp(dst[i], ops[i]->sym->auth.digest.data,
- ZUC_DIGEST_LENGTH) != 0)
+ if (rte_consttime_memneq(dst[i], ops[i]->sym->auth.digest.data,
+ ZUC_DIGEST_LENGTH))
ops[i]->status =
RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
--
2.34.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [dpdk-dev v3 1/2] eal: Add rte_consttime_memneq() to prevent timing attacks memcmp.
2025-09-26 16:02 ` [dpdk-dev v3 1/2] eal: Add rte_consttime_memneq() to prevent timing attacks memcmp Kai Ji
2025-09-26 16:02 ` [dpdk-dev v3 2/2] crypto/ipsec-mb: use constant-time memory comparison Kai Ji
@ 2025-09-26 18:12 ` Stephen Hemminger
2025-09-26 19:17 ` Morten Brørup
2 siblings, 0 replies; 16+ messages in thread
From: Stephen Hemminger @ 2025-09-26 18:12 UTC (permalink / raw)
To: Kai Ji; +Cc: dev, gakhil, konstantin.ananyev, bruce.richardson, thomas
On Fri, 26 Sep 2025 16:02:08 +0000
Kai Ji <kai.ji@intel.com> wrote:
> +/**
> + * Constant-time memory inequality comparison.
> + *
> + * This function compares two memory regions in constant time, making it
> + * resistant to timing side-channel attacks. The execution time depends only
> + * on the length parameter, not on the actual data values being compared.
> + *
> + * This is particularly important for cryptographic operations where timing
> + * differences could leak information about secret keys, passwords, or other
> + * sensitive data.
> + *
> + * @param a
> + * Pointer to the first memory region to compare
> + * @param b
> + * Pointer to the second memory region to compare
> + * @param n
> + * Number of bytes to compare
> + * @return
> + * false if the memory regions are identical, true if they differ
> + */
> +static inline bool
> +rte_consttime_memneq(const void *a, const void *b, size_t n)
prefer FreeBSD naming i.e memeq instead of memneq
^ permalink raw reply [flat|nested] 16+ messages in thread
* RE: [dpdk-dev v3 1/2] eal: Add rte_consttime_memneq() to prevent timing attacks memcmp.
2025-09-26 16:02 ` [dpdk-dev v3 1/2] eal: Add rte_consttime_memneq() to prevent timing attacks memcmp Kai Ji
2025-09-26 16:02 ` [dpdk-dev v3 2/2] crypto/ipsec-mb: use constant-time memory comparison Kai Ji
2025-09-26 18:12 ` [dpdk-dev v3 1/2] eal: Add rte_consttime_memneq() to prevent timing attacks memcmp Stephen Hemminger
@ 2025-09-26 19:17 ` Morten Brørup
2025-09-26 20:15 ` Stephen Hemminger
2 siblings, 1 reply; 16+ messages in thread
From: Morten Brørup @ 2025-09-26 19:17 UTC (permalink / raw)
To: Kai Ji, dev; +Cc: gakhil, konstantin.ananyev, bruce.richardson, thomas, stephen
> From: Kai Ji [mailto:kai.ji@intel.com]
> Sent: Friday, 26 September 2025 18.02
>
> Bugzilla ID: 1773
> https://bugs.dpdk.org/show_bug.cgi?id=1773
>
> Signed-off-by: Kai Ji <kai.ji@intel.com>
> ---
> lib/eal/include/rte_common.h | 34 ++++++++++++++++++++++++++++++++++
> 1 file changed, 34 insertions(+)
>
> diff --git a/lib/eal/include/rte_common.h
> b/lib/eal/include/rte_common.h
> index 9e7d84f929..ddbba083be 100644
> --- a/lib/eal/include/rte_common.h
> +++ b/lib/eal/include/rte_common.h
> @@ -700,6 +700,40 @@ rte_is_aligned(const void * const __rte_restrict
> ptr, const unsigned int align)
> return ((uintptr_t)ptr & (align - 1)) == 0;
> }
>
> +/**
> + * Constant-time memory inequality comparison.
> + *
> + * This function compares two memory regions in constant time, making
> it
> + * resistant to timing side-channel attacks. The execution time
> depends only
> + * on the length parameter, not on the actual data values being
> compared.
> + *
> + * This is particularly important for cryptographic operations where
> timing
> + * differences could leak information about secret keys, passwords, or
> other
> + * sensitive data.
> + *
> + * @param a
> + * Pointer to the first memory region to compare
> + * @param b
> + * Pointer to the second memory region to compare
> + * @param n
> + * Number of bytes to compare
> + * @return
> + * false if the memory regions are identical, true if they differ
> + */
> +static inline bool
> +rte_consttime_memneq(const void *a, const void *b, size_t n)
> +{
> + const volatile uint8_t *pa = (const volatile uint8_t *)a;
> + const volatile uint8_t *pb = (const volatile uint8_t *)b;
> + uint8_t result = 0;
> + size_t i;
> +
> + for (i = 0; i < n; i++)
> + result |= pa[i] ^ pb[i];
> +
> + return result != 0;
> +}
> +
> /*********** Macros for compile type checks ********/
>
> /* Workaround for toolchain issues with missing C11 macro in FreeBSD
> */
> --
> 2.34.1
My comments here still apply:
https://inbox.dpdk.org/dev/98CBD80474FA8B44BF855DF32C47DC35F6547A@smartserver.smartshare.dk/
Also, this is certainly not a common function, so don't put it in rte_commo.h. Put it in rte_memory.h as suggested.
-Morten
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [dpdk-dev v3 1/2] eal: Add rte_consttime_memneq() to prevent timing attacks memcmp.
2025-09-26 19:17 ` Morten Brørup
@ 2025-09-26 20:15 ` Stephen Hemminger
0 siblings, 0 replies; 16+ messages in thread
From: Stephen Hemminger @ 2025-09-26 20:15 UTC (permalink / raw)
To: Morten Brørup
Cc: Kai Ji, dev, gakhil, konstantin.ananyev, bruce.richardson, thomas
On Fri, 26 Sep 2025 21:17:08 +0200
Morten Brørup <mb@smartsharesystems.com> wrote:
> > From: Kai Ji [mailto:kai.ji@intel.com]
> > Sent: Friday, 26 September 2025 18.02
> >
> > Bugzilla ID: 1773
> > https://bugs.dpdk.org/show_bug.cgi?id=1773
> >
> > Signed-off-by: Kai Ji <kai.ji@intel.com>
> > ---
> > lib/eal/include/rte_common.h | 34 ++++++++++++++++++++++++++++++++++
> > 1 file changed, 34 insertions(+)
> >
> > diff --git a/lib/eal/include/rte_common.h
> > b/lib/eal/include/rte_common.h
> > index 9e7d84f929..ddbba083be 100644
> > --- a/lib/eal/include/rte_common.h
> > +++ b/lib/eal/include/rte_common.h
> > @@ -700,6 +700,40 @@ rte_is_aligned(const void * const __rte_restrict
> > ptr, const unsigned int align)
> > return ((uintptr_t)ptr & (align - 1)) == 0;
> > }
> >
> > +/**
> > + * Constant-time memory inequality comparison.
> > + *
> > + * This function compares two memory regions in constant time, making
> > it
> > + * resistant to timing side-channel attacks. The execution time
> > depends only
> > + * on the length parameter, not on the actual data values being
> > compared.
> > + *
> > + * This is particularly important for cryptographic operations where
> > timing
> > + * differences could leak information about secret keys, passwords, or
> > other
> > + * sensitive data.
> > + *
> > + * @param a
> > + * Pointer to the first memory region to compare
> > + * @param b
> > + * Pointer to the second memory region to compare
> > + * @param n
> > + * Number of bytes to compare
> > + * @return
> > + * false if the memory regions are identical, true if they differ
> > + */
> > +static inline bool
> > +rte_consttime_memneq(const void *a, const void *b, size_t n)
> > +{
> > + const volatile uint8_t *pa = (const volatile uint8_t *)a;
> > + const volatile uint8_t *pb = (const volatile uint8_t *)b;
> > + uint8_t result = 0;
> > + size_t i;
> > +
> > + for (i = 0; i < n; i++)
> > + result |= pa[i] ^ pb[i];
> > +
> > + return result != 0;
> > +}
> > +
> > /*********** Macros for compile type checks ********/
> >
> > /* Workaround for toolchain issues with missing C11 macro in FreeBSD
> > */
> > --
> > 2.34.1
>
> My comments here still apply:
> https://inbox.dpdk.org/dev/98CBD80474FA8B44BF855DF32C47DC35F6547A@smartserver.smartshare.dk/
>
> Also, this is certainly not a common function, so don't put it in rte_commo.h. Put it in rte_memory.h as suggested.
Yes, Should be next to existing rte_memzero_explicit in rte_memory.h
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [dpdk-dev v2 1/2] eal: Add rte_consttime_memsq() to prevent timing attacks memcmp.
2025-09-26 15:49 ` [dpdk-dev v2 1/2] eal: Add rte_consttime_memsq() to prevent timing attacks memcmp Kai Ji
2025-09-26 15:49 ` [dpdk-dev v2 2/2] crypto/ipsec-mb: use constant-time memory comparison Kai Ji
2025-09-26 16:02 ` [dpdk-dev v3 1/2] eal: Add rte_consttime_memneq() to prevent timing attacks memcmp Kai Ji
@ 2025-09-26 18:07 ` Stephen Hemminger
2 siblings, 0 replies; 16+ messages in thread
From: Stephen Hemminger @ 2025-09-26 18:07 UTC (permalink / raw)
To: Kai Ji; +Cc: dev, gakhil, konstantin.ananyev, bruce.richardson, thomas, stable
On Fri, 26 Sep 2025 15:49:04 +0000
Kai Ji <kai.ji@intel.com> wrote:
> Bugzilla ID: 1773
> Cc: stable@dpdk.org
>
> [0] https://bugs.dpdk.org/show_bug.cgi?id=1773
>
> Signed-off-by: Kai Ji <kai.ji@intel.com>
> ---
> lib/eal/include/rte_common.h | 34 ++++++++++++++++++++++++++++++++++
> 1 file changed, 34 insertions(+)
>
> diff --git a/lib/eal/include/rte_common.h b/lib/eal/include/rte_common.h
> index 9e7d84f929..ddbba083be 100644
> --- a/lib/eal/include/rte_common.h
> +++ b/lib/eal/include/rte_common.h
> @@ -700,6 +700,40 @@ rte_is_aligned(const void * const __rte_restrict ptr, const unsigned int align)
> return ((uintptr_t)ptr & (align - 1)) == 0;
> }
>
> +/**
> + * Constant-time memory inequality comparison.
> + *
> + * This function compares two memory regions in constant time, making it
> + * resistant to timing side-channel attacks. The execution time depends only
> + * on the length parameter, not on the actual data values being compared.
> + *
> + * This is particularly important for cryptographic operations where timing
> + * differences could leak information about secret keys, passwords, or other
> + * sensitive data.
> + *
> + * @param a
> + * Pointer to the first memory region to compare
> + * @param b
> + * Pointer to the second memory region to compare
> + * @param n
> + * Number of bytes to compare
> + * @return
> + * false if the memory regions are identical, true if they differ
> + */
> +static inline bool
> +rte_consttime_memneq(const void *a, const void *b, size_t n)
> +{
> + const volatile uint8_t *pa = (const volatile uint8_t *)a;
> + const volatile uint8_t *pb = (const volatile uint8_t *)b;
> + uint8_t result = 0;
> + size_t i;
> +
> + for (i = 0; i < n; i++)
> + result |= pa[i] ^ pb[i];
> +
> + return result != 0;
> +}
New functions usually have to be marked experimental.
Since DPDK adopts many things from FreeBSD, perhaps the function
should use the same naming conventions. That would mean
int rte_consttime_memequal(void *, void *, size_t len);
And will also need to update release notes.
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2025-09-26 20:15 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-09-25 10:22 [dpdk-dev v1] cryptodev: introduce constant-time memory comparison Kai Ji
2025-09-25 10:33 ` [EXTERNAL] " Akhil Goyal
2025-09-25 20:47 ` Thomas Monjalon
2025-09-26 7:55 ` Bruce Richardson
2025-09-26 7:58 ` Bruce Richardson
2025-09-26 12:34 ` Morten Brørup
2025-09-26 8:13 ` Konstantin Ananyev
2025-09-26 8:16 ` Konstantin Ananyev
2025-09-26 15:49 ` [dpdk-dev v2 1/2] eal: Add rte_consttime_memsq() to prevent timing attacks memcmp Kai Ji
2025-09-26 15:49 ` [dpdk-dev v2 2/2] crypto/ipsec-mb: use constant-time memory comparison Kai Ji
2025-09-26 16:02 ` [dpdk-dev v3 1/2] eal: Add rte_consttime_memneq() to prevent timing attacks memcmp Kai Ji
2025-09-26 16:02 ` [dpdk-dev v3 2/2] crypto/ipsec-mb: use constant-time memory comparison Kai Ji
2025-09-26 18:12 ` [dpdk-dev v3 1/2] eal: Add rte_consttime_memneq() to prevent timing attacks memcmp Stephen Hemminger
2025-09-26 19:17 ` Morten Brørup
2025-09-26 20:15 ` Stephen Hemminger
2025-09-26 18:07 ` [dpdk-dev v2 1/2] eal: Add rte_consttime_memsq() " Stephen Hemminger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).