* [PATCH 4/6] crypto/openssl: fix 3DES-CTR with big endian CPUs [not found] <20241024120535.2722316-1-david.marchand@redhat.com> @ 2024-10-24 12:05 ` David Marchand 2024-10-24 12:54 ` Morten Brørup [not found] ` <20241025070424.3916007-1-david.marchand@redhat.com> 1 sibling, 1 reply; 7+ messages in thread From: David Marchand @ 2024-10-24 12:05 UTC (permalink / raw) To: dev Cc: thomas, ferruh.yigit, stephen, mattias.ronnblom, stable, Kai Ji, Slawomir Mrozowicz, Tomasz Kulasek, Daniel Mrzyglod, Pablo de Lara, Michal Kobylinski Caught by code review. Don't byte swap unconditionally (assuming that CPU is little endian is wrong). Instead, convert from big endian to cpu and vice versa. Fixes: d61f70b4c918 ("crypto/libcrypto: add driver for OpenSSL library") Cc: stable@dpdk.org Signed-off-by: David Marchand <david.marchand@redhat.com> --- drivers/crypto/openssl/rte_openssl_pmd.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c index 9657b70c7a..9f5f3cda7d 100644 --- a/drivers/crypto/openssl/rte_openssl_pmd.c +++ b/drivers/crypto/openssl/rte_openssl_pmd.c @@ -2,6 +2,7 @@ * Copyright(c) 2016-2017 Intel Corporation */ +#include <rte_byteorder.h> #include <rte_common.h> #include <rte_hexdump.h> #include <rte_cryptodev.h> @@ -110,9 +111,9 @@ ctr_inc(uint8_t *ctr) { uint64_t *ctr64 = (uint64_t *)ctr; - *ctr64 = __builtin_bswap64(*ctr64); + *ctr64 = rte_be_to_cpu_64(*ctr64); (*ctr64)++; - *ctr64 = __builtin_bswap64(*ctr64); + *ctr64 = rte_cpu_to_be_64(*ctr64); } /* -- 2.46.2 ^ permalink raw reply [flat|nested] 7+ messages in thread
* RE: [PATCH 4/6] crypto/openssl: fix 3DES-CTR with big endian CPUs 2024-10-24 12:05 ` [PATCH 4/6] crypto/openssl: fix 3DES-CTR with big endian CPUs David Marchand @ 2024-10-24 12:54 ` Morten Brørup 2024-10-24 13:10 ` David Marchand 0 siblings, 1 reply; 7+ messages in thread From: Morten Brørup @ 2024-10-24 12:54 UTC (permalink / raw) To: David Marchand, dev Cc: thomas, ferruh.yigit, stephen, mattias.ronnblom, stable, Kai Ji, Slawomir Mrozowicz, Tomasz Kulasek, Daniel Mrzyglod, Pablo de Lara, Michal Kobylinski > From: David Marchand [mailto:david.marchand@redhat.com] > Sent: Thursday, 24 October 2024 14.06 > > Caught by code review. > > Don't byte swap unconditionally (assuming that CPU is little endian is > wrong). Instead, convert from big endian to cpu and vice versa. Yes looks like a bug. I wonder if this PMD has more similar bugs... grep bswap drivers/crypto/openssl/* says no. > @@ -110,9 +111,9 @@ ctr_inc(uint8_t *ctr) > { > uint64_t *ctr64 = (uint64_t *)ctr; > > - *ctr64 = __builtin_bswap64(*ctr64); > + *ctr64 = rte_be_to_cpu_64(*ctr64); > (*ctr64)++; > - *ctr64 = __builtin_bswap64(*ctr64); > + *ctr64 = rte_cpu_to_be_64(*ctr64); > } But that's not all. There may be an alignment bug too; the way it is used in process_openssl_cipher_des3ctr(), "ctr" is not guaranteed to be uint64_t aligned. How about this instead: ctr_inc(void *ctr) { uint64_t ctr64 = rte_be_to_cpu_64(*(unaligned_uint64_t *)ctr); ctr64++; *(unaligned_uint64_t *)ctr = rte_cpu_to_be_64(ctr64); } Or this: ctr_inc(void *ctr) { uint64_t ctr64; memcpy(&ctr64, ctr, sizeof(uint64_t)); ctr64 = rte_be_to_cpu_64(ctr64); ctr64++; ctr64 = rte_cpu_to_be_64(ctr64); memcpy(ctr, &ctr64, sizeof(uint64_t)); } Or use a union in process_openssl_cipher_des3ctr() to ensure it's uint64_t aligned. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 4/6] crypto/openssl: fix 3DES-CTR with big endian CPUs 2024-10-24 12:54 ` Morten Brørup @ 2024-10-24 13:10 ` David Marchand 2024-10-24 13:17 ` David Marchand 0 siblings, 1 reply; 7+ messages in thread From: David Marchand @ 2024-10-24 13:10 UTC (permalink / raw) To: Morten Brørup Cc: dev, thomas, ferruh.yigit, stephen, mattias.ronnblom, stable, Kai Ji, Slawomir Mrozowicz, Tomasz Kulasek, Daniel Mrzyglod, Pablo de Lara, Michal Kobylinski On Thu, Oct 24, 2024 at 2:55 PM Morten Brørup <mb@smartsharesystems.com> wrote: > > > From: David Marchand [mailto:david.marchand@redhat.com] > > Sent: Thursday, 24 October 2024 14.06 > > > > Caught by code review. > > > > Don't byte swap unconditionally (assuming that CPU is little endian is > > wrong). Instead, convert from big endian to cpu and vice versa. > > Yes looks like a bug. > I wonder if this PMD has more similar bugs... > grep bswap drivers/crypto/openssl/* says no. > > > @@ -110,9 +111,9 @@ ctr_inc(uint8_t *ctr) > > { > > uint64_t *ctr64 = (uint64_t *)ctr; > > > > - *ctr64 = __builtin_bswap64(*ctr64); > > + *ctr64 = rte_be_to_cpu_64(*ctr64); > > (*ctr64)++; > > - *ctr64 = __builtin_bswap64(*ctr64); > > + *ctr64 = rte_cpu_to_be_64(*ctr64); > > } > > But that's not all. > > There may be an alignment bug too; the way it is used in process_openssl_cipher_des3ctr(), "ctr" is not guaranteed to be uint64_t aligned. > > How about this instead: > > ctr_inc(void *ctr) > { > uint64_t ctr64 = rte_be_to_cpu_64(*(unaligned_uint64_t *)ctr); > ctr64++; > *(unaligned_uint64_t *)ctr = rte_cpu_to_be_64(ctr64); > } > > Or this: > > ctr_inc(void *ctr) > { > uint64_t ctr64; > > memcpy(&ctr64, ctr, sizeof(uint64_t)); > ctr64 = rte_be_to_cpu_64(ctr64); > ctr64++; > ctr64 = rte_cpu_to_be_64(ctr64); > memcpy(ctr, &ctr64, sizeof(uint64_t)); > } > > Or use a union in process_openssl_cipher_des3ctr() to ensure it's uint64_t aligned. Or declare ctr as a uint64_t in process_openssl_cipher_des3ctr directly, and remove this casting. -- David Marchand ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 4/6] crypto/openssl: fix 3DES-CTR with big endian CPUs 2024-10-24 13:10 ` David Marchand @ 2024-10-24 13:17 ` David Marchand 2024-10-24 13:30 ` David Marchand 0 siblings, 1 reply; 7+ messages in thread From: David Marchand @ 2024-10-24 13:17 UTC (permalink / raw) To: Morten Brørup Cc: dev, thomas, ferruh.yigit, stephen, mattias.ronnblom, stable, Kai Ji, Slawomir Mrozowicz, Tomasz Kulasek, Daniel Mrzyglod, Pablo de Lara, Michal Kobylinski On Thu, Oct 24, 2024 at 3:10 PM David Marchand <david.marchand@redhat.com> wrote: > > There may be an alignment bug too; the way it is used in process_openssl_cipher_des3ctr(), "ctr" is not guaranteed to be uint64_t aligned. > > > > How about this instead: > > > > ctr_inc(void *ctr) > > { > > uint64_t ctr64 = rte_be_to_cpu_64(*(unaligned_uint64_t *)ctr); > > ctr64++; > > *(unaligned_uint64_t *)ctr = rte_cpu_to_be_64(ctr64); > > } > > > > Or this: > > > > ctr_inc(void *ctr) > > { > > uint64_t ctr64; > > > > memcpy(&ctr64, ctr, sizeof(uint64_t)); > > ctr64 = rte_be_to_cpu_64(ctr64); > > ctr64++; > > ctr64 = rte_cpu_to_be_64(ctr64); > > memcpy(ctr, &ctr64, sizeof(uint64_t)); > > } > > > > Or use a union in process_openssl_cipher_des3ctr() to ensure it's uint64_t aligned. > > Or declare ctr as a uint64_t in process_openssl_cipher_des3ctr > directly, and remove this casting. Like: diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c index 9657b70c7a..8e193759b7 100644 --- a/drivers/crypto/openssl/rte_openssl_pmd.c +++ b/drivers/crypto/openssl/rte_openssl_pmd.c @@ -99,22 +99,6 @@ digest_name_get(enum rte_crypto_auth_algorithm algo) static int cryptodev_openssl_remove(struct rte_vdev_device *vdev); -/*----------------------------------------------------------------------------*/ - -/** - * Increment counter by 1 - * Counter is 64 bit array, big-endian - */ -static void -ctr_inc(uint8_t *ctr) -{ - uint64_t *ctr64 = (uint64_t *)ctr; - - *ctr64 = __builtin_bswap64(*ctr64); - (*ctr64)++; - *ctr64 = __builtin_bswap64(*ctr64); -} - /* *------------------------------------------------------------------------------ * Session Prepare @@ -1192,7 +1176,9 @@ static int process_openssl_cipher_des3ctr(struct rte_mbuf *mbuf_src, uint8_t *dst, int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx) { - uint8_t ebuf[8], ctr[8]; + uint8_t ebuf[8]; + uint64_t host_ctr; + uint64_t ctr; int unused, n; struct rte_mbuf *m; uint8_t *src; @@ -1209,14 +1195,16 @@ process_openssl_cipher_des3ctr(struct rte_mbuf *mbuf_src, uint8_t *dst, l = rte_pktmbuf_data_len(m) - offset; memcpy(ctr, iv, 8); + host_ctr = rte_be_64_to_cpu(ctr); for (n = 0; n < srclen; n++) { if (n % 8 == 0) { + ctr = rte_cpu_to_be_64(host_ctr); if (EVP_EncryptUpdate(ctx, (unsigned char *)&ebuf, &unused, (const unsigned char *)&ctr, 8) <= 0) goto process_cipher_des3ctr_err; - ctr_inc(ctr); + host_ctr++; } dst[n] = *(src++) ^ ebuf[n % 8]; -- David Marchand ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 4/6] crypto/openssl: fix 3DES-CTR with big endian CPUs 2024-10-24 13:17 ` David Marchand @ 2024-10-24 13:30 ` David Marchand 2024-10-24 14:21 ` Morten Brørup 0 siblings, 1 reply; 7+ messages in thread From: David Marchand @ 2024-10-24 13:30 UTC (permalink / raw) To: Morten Brørup Cc: dev, thomas, ferruh.yigit, stephen, mattias.ronnblom, stable, Kai Ji, Slawomir Mrozowicz, Tomasz Kulasek, Daniel Mrzyglod, Pablo de Lara, Michal Kobylinski On Thu, Oct 24, 2024 at 3:17 PM David Marchand <david.marchand@redhat.com> wrote: > @@ -1209,14 +1195,16 @@ process_openssl_cipher_des3ctr(struct rte_mbuf > *mbuf_src, uint8_t *dst, > l = rte_pktmbuf_data_len(m) - offset; > > memcpy(ctr, iv, 8); > + host_ctr = rte_be_64_to_cpu(ctr); > > for (n = 0; n < srclen; n++) { > if (n % 8 == 0) { > + ctr = rte_cpu_to_be_64(host_ctr); Moving this here adds one uneeded extra conversion on the first iteration. So I would keep the conversion around the host_ctr variable increment, if you get the idea. > if (EVP_EncryptUpdate(ctx, > (unsigned char *)&ebuf, &unused, > (const unsigned char *)&ctr, 8) <= 0) > goto process_cipher_des3ctr_err; > - ctr_inc(ctr); > + host_ctr++; > } > dst[n] = *(src++) ^ ebuf[n % 8]; -- David Marchand ^ permalink raw reply [flat|nested] 7+ messages in thread
* RE: [PATCH 4/6] crypto/openssl: fix 3DES-CTR with big endian CPUs 2024-10-24 13:30 ` David Marchand @ 2024-10-24 14:21 ` Morten Brørup 0 siblings, 0 replies; 7+ messages in thread From: Morten Brørup @ 2024-10-24 14:21 UTC (permalink / raw) To: David Marchand Cc: dev, thomas, ferruh.yigit, stephen, mattias.ronnblom, stable, Kai Ji, Slawomir Mrozowicz, Tomasz Kulasek, Daniel Mrzyglod, Pablo de Lara, Michal Kobylinski > From: David Marchand [mailto:david.marchand@redhat.com] > Sent: Thursday, 24 October 2024 15.30 > > On Thu, Oct 24, 2024 at 3:17 PM David Marchand > <david.marchand@redhat.com> wrote: > > @@ -1209,14 +1195,16 @@ process_openssl_cipher_des3ctr(struct > rte_mbuf > > *mbuf_src, uint8_t *dst, > > l = rte_pktmbuf_data_len(m) - offset; > > > > memcpy(ctr, iv, 8); > > + host_ctr = rte_be_64_to_cpu(ctr); > > > > for (n = 0; n < srclen; n++) { > > if (n % 8 == 0) { > > + ctr = rte_cpu_to_be_64(host_ctr); > > Moving this here adds one uneeded extra conversion on the first > iteration. > So I would keep the conversion around the host_ctr variable increment, > if you get the idea. > > > > if (EVP_EncryptUpdate(ctx, > > (unsigned char *)&ebuf, > &unused, > > (const unsigned char *)&ctr, > 8) <= 0) > > goto process_cipher_des3ctr_err; > > - ctr_inc(ctr); > > + host_ctr++; > > } > > dst[n] = *(src++) ^ ebuf[n % 8]; > > -- > David Marchand LGTM. For the next version, Acked-by: Morten Brørup <mb@smartsharesystems.com> ^ permalink raw reply [flat|nested] 7+ messages in thread
[parent not found: <20241025070424.3916007-1-david.marchand@redhat.com>]
* [PATCH v2 4/6] crypto/openssl: fix 3DES-CTR with big endian CPUs [not found] ` <20241025070424.3916007-1-david.marchand@redhat.com> @ 2024-10-25 7:04 ` David Marchand 0 siblings, 0 replies; 7+ messages in thread From: David Marchand @ 2024-10-25 7:04 UTC (permalink / raw) To: dev Cc: thomas, ferruh.yigit, stephen, mattias.ronnblom, stable, Morten Brørup, Kai Ji, Michal Kobylinski, Slawomir Mrozowicz, Tomasz Kulasek, Daniel Mrzyglod, Pablo de Lara Caught by code review. Don't byte swap unconditionally (assuming that CPU is little endian is wrong). Instead, convert from big endian to cpu and vice versa. Besides, avoid unaligned accesses and remove the ctr_inc helper that is not used anywhere else. Fixes: d61f70b4c918 ("crypto/libcrypto: add driver for OpenSSL library") Cc: stable@dpdk.org Signed-off-by: David Marchand <david.marchand@redhat.com> Acked-by: Morten Brørup <mb@smartsharesystems.com> --- Changes since v1: - fixed unaligned access, - removed unneeded helper, --- drivers/crypto/openssl/rte_openssl_pmd.c | 28 ++++++++---------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c index 9657b70c7a..0616383921 100644 --- a/drivers/crypto/openssl/rte_openssl_pmd.c +++ b/drivers/crypto/openssl/rte_openssl_pmd.c @@ -2,6 +2,7 @@ * Copyright(c) 2016-2017 Intel Corporation */ +#include <rte_byteorder.h> #include <rte_common.h> #include <rte_hexdump.h> #include <rte_cryptodev.h> @@ -99,22 +100,6 @@ digest_name_get(enum rte_crypto_auth_algorithm algo) static int cryptodev_openssl_remove(struct rte_vdev_device *vdev); -/*----------------------------------------------------------------------------*/ - -/** - * Increment counter by 1 - * Counter is 64 bit array, big-endian - */ -static void -ctr_inc(uint8_t *ctr) -{ - uint64_t *ctr64 = (uint64_t *)ctr; - - *ctr64 = __builtin_bswap64(*ctr64); - (*ctr64)++; - *ctr64 = __builtin_bswap64(*ctr64); -} - /* *------------------------------------------------------------------------------ * Session Prepare @@ -1192,7 +1177,8 @@ static int process_openssl_cipher_des3ctr(struct rte_mbuf *mbuf_src, uint8_t *dst, int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx) { - uint8_t ebuf[8], ctr[8]; + uint8_t ebuf[8]; + uint64_t ctr; int unused, n; struct rte_mbuf *m; uint8_t *src; @@ -1208,15 +1194,19 @@ process_openssl_cipher_des3ctr(struct rte_mbuf *mbuf_src, uint8_t *dst, src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset); l = rte_pktmbuf_data_len(m) - offset; - memcpy(ctr, iv, 8); + memcpy(&ctr, iv, 8); for (n = 0; n < srclen; n++) { if (n % 8 == 0) { + uint64_t cpu_ctr; + if (EVP_EncryptUpdate(ctx, (unsigned char *)&ebuf, &unused, (const unsigned char *)&ctr, 8) <= 0) goto process_cipher_des3ctr_err; - ctr_inc(ctr); + cpu_ctr = rte_be_to_cpu_64(ctr); + cpu_ctr++; + ctr = rte_cpu_to_be_64(cpu_ctr); } dst[n] = *(src++) ^ ebuf[n % 8]; -- 2.46.2 ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2024-10-25 7:05 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- [not found] <20241024120535.2722316-1-david.marchand@redhat.com> 2024-10-24 12:05 ` [PATCH 4/6] crypto/openssl: fix 3DES-CTR with big endian CPUs David Marchand 2024-10-24 12:54 ` Morten Brørup 2024-10-24 13:10 ` David Marchand 2024-10-24 13:17 ` David Marchand 2024-10-24 13:30 ` David Marchand 2024-10-24 14:21 ` Morten Brørup [not found] ` <20241025070424.3916007-1-david.marchand@redhat.com> 2024-10-25 7:04 ` [PATCH v2 " David Marchand
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).