diff mbox series

[meta-oe,kirkstone] opensc: fix CVE-2023-5992

Message ID 20251031091445.2662463-1-peng.zhang1.cn@windriver.com
State New
Headers show
Series [meta-oe,kirkstone] opensc: fix CVE-2023-5992 | expand

Commit Message

Peng Zhang Oct. 31, 2025, 9:14 a.m. UTC
From: Zhang Peng <peng.zhang1.cn@windriver.com>

CVE-2023-5992:
A vulnerability was found in OpenSC where PKCS#1 encryption padding removal is not
implemented as side-channel resistant. This issue may result in the potential leak
of private data.

Reference:
[https://nvd.nist.gov/vuln/detail/CVE-2023-5992]
[https://github.com/OpenSC/OpenSC/wiki/CVE-2023-5992]

Upstream patches:
[https://github.com/OpenSC/OpenSC/pull/2948]
[https://github.com/OpenSC/OpenSC/pull/3016]

Signed-off-by: Zhang Peng <peng.zhang1.cn@windriver.com>
---
 .../opensc/files/CVE-2023-5992-0001.patch     | 359 ++++++++++++++++++
 .../opensc/files/CVE-2023-5992-0002.patch     | 269 +++++++++++++
 .../opensc/files/CVE-2023-5992-0003.patch     |  41 ++
 .../opensc/files/CVE-2023-5992-0004.patch     | 109 ++++++
 .../opensc/files/CVE-2023-5992-0005.patch     |  63 +++
 .../opensc/files/CVE-2023-5992-0006.patch     | 118 ++++++
 .../opensc/files/CVE-2023-5992-0007.patch     |  50 +++
 .../opensc/files/CVE-2023-5992-0008.patch     |  37 ++
 .../opensc/files/CVE-2023-5992-0009.patch     | 123 ++++++
 .../opensc/files/CVE-2023-5992-0010.patch     |  75 ++++
 .../recipes-support/opensc/opensc_0.22.0.bb   |  10 +
 11 files changed, 1254 insertions(+)
 create mode 100644 meta-oe/recipes-support/opensc/files/CVE-2023-5992-0001.patch
 create mode 100644 meta-oe/recipes-support/opensc/files/CVE-2023-5992-0002.patch
 create mode 100644 meta-oe/recipes-support/opensc/files/CVE-2023-5992-0003.patch
 create mode 100644 meta-oe/recipes-support/opensc/files/CVE-2023-5992-0004.patch
 create mode 100644 meta-oe/recipes-support/opensc/files/CVE-2023-5992-0005.patch
 create mode 100644 meta-oe/recipes-support/opensc/files/CVE-2023-5992-0006.patch
 create mode 100644 meta-oe/recipes-support/opensc/files/CVE-2023-5992-0007.patch
 create mode 100644 meta-oe/recipes-support/opensc/files/CVE-2023-5992-0008.patch
 create mode 100644 meta-oe/recipes-support/opensc/files/CVE-2023-5992-0009.patch
 create mode 100644 meta-oe/recipes-support/opensc/files/CVE-2023-5992-0010.patch
diff mbox series

Patch

diff --git a/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0001.patch b/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0001.patch
new file mode 100644
index 0000000000..4798ab56ae
--- /dev/null
+++ b/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0001.patch
@@ -0,0 +1,359 @@ 
+From 9c14d6d996e526ebfda75de7b577255acf7ad86d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= <vhanulik@redhat.com>
+Date: Mon, 13 Nov 2023 13:54:54 +0100
+Subject: [PATCH 01/10] Reimplement removing of PKCS#1 v1.5 padding to be time
+ constant
+
+CVE: CVE-2023-5992
+Upstream-Status: Backport [https://github.com/OpenSC/OpenSC/pull/2948]
+
+Signed-off-by: Zhang Peng <peng.zhang1.cn@windriver.com>
+---
+ src/common/Makefile.am      |   5 +-
+ src/common/constant-time.h  | 128 ++++++++++++++++++++++++++++++++++++
+ src/libopensc/internal.h    |   4 +-
+ src/libopensc/padding.c     | 102 +++++++++++++++++++---------
+ src/libopensc/pkcs15-sec.c  |   5 +-
+ src/minidriver/minidriver.c |   4 +-
+ 6 files changed, 209 insertions(+), 39 deletions(-)
+ create mode 100644 src/common/constant-time.h
+
+diff --git a/src/common/Makefile.am b/src/common/Makefile.am
+index 83a40e1c2..c4cfff185 100644
+--- a/src/common/Makefile.am
++++ b/src/common/Makefile.am
+@@ -8,7 +8,7 @@ dist_noinst_DATA = \
+ 	LICENSE.compat_getopt compat_getopt.txt \
+ 	compat_getopt_main.c \
+ 	README.compat_strlcpy compat_strlcpy.3
+-noinst_HEADERS = compat_strlcat.h compat_strlcpy.h compat_strnlen.h compat_getpass.h compat_getopt.h simclist.h libpkcs11.h libscdl.h
++noinst_HEADERS = compat_strlcat.h compat_strlcpy.h compat_strnlen.h compat_getpass.h compat_getopt.h simclist.h libpkcs11.h libscdl.h constant-time.h
+ 
+ AM_CPPFLAGS = -I$(top_srcdir)/src
+ 
+@@ -40,7 +40,8 @@ TIDY_FILES = \
+ 	compat_report_rangecheckfailure.c \
+ 	compat___iob_func.c \
+ 	simclist.c simclist.h \
+-	libpkcs11.c libscdl.c
++	libpkcs11.c libscdl.c \
++	constant-time.h
+ 
+ check-local:
+ 	if [ -x "$(CLANGTIDY)" ]; then clang-tidy -config='' --checks='$(TIDY_CHECKS)' -header-filter=.* $(addprefix $(srcdir)/,$(TIDY_FILES)) -- $(TIDY_FLAGS); fi
+diff --git a/src/common/constant-time.h b/src/common/constant-time.h
+new file mode 100644
+index 000000000..40c3e500c
+--- /dev/null
++++ b/src/common/constant-time.h
+@@ -0,0 +1,128 @@
++/* Original source: https://github.com/openssl/openssl/blob/9890cc42daff5e2d0cad01ac4bf78c391f599a6e/include/internal/constant_time.h */
++
++#ifndef CONSTANT_TIME_H
++#define CONSTANT_TIME_H
++
++#include <stdlib.h>
++#include <string.h>
++
++#if !defined(inline)
++#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
++#define constant_inline inline
++#elif defined(__GNUC__) && __GNUC__ >= 2
++#elif defined(__GNUC__) && __GNUC__ >= 2
++#elif defined(_MSC_VER)
++#define constant_inline __inline
++#else
++#define constant_inline
++#endif
++#else			       /* use what caller wants as inline  may be from config.h */
++#define constant_inline inline /* inline */
++#endif
++
++/*-
++ * The boolean methods return a bitmask of all ones (0xff...f) for true
++ * and 0 for false. For example,
++ *      if (a < b) {
++ *        c = a;
++ *      } else {
++ *        c = b;
++ *      }
++ * can be written as
++ *      unsigned int lt = constant_time_lt(a, b);
++ *      c = constant_time_select(lt, a, b);
++ */
++
++static constant_inline unsigned int
++value_barrier(unsigned int a)
++{
++	volatile unsigned int r = a;
++	return r;
++}
++
++static constant_inline size_t
++value_barrier_s(size_t a)
++{
++	volatile size_t r = a;
++	return r;
++}
++
++/* MSB */
++static constant_inline size_t
++constant_time_msb_s(size_t a)
++{
++	return 0 - (a >> (sizeof(a) * 8 - 1));
++}
++
++static constant_inline unsigned int
++constant_time_msb(unsigned int a)
++{
++	return 0 - (a >> (sizeof(a) * 8 - 1));
++}
++
++/* Select */
++static constant_inline unsigned int
++constant_time_select(unsigned int mask, unsigned int a, unsigned int b)
++{
++	return (value_barrier(mask) & a) | (value_barrier(~mask) & b);
++}
++
++static constant_inline unsigned char
++constant_time_select_8(unsigned char mask, unsigned char a, unsigned char b)
++{
++	return (unsigned char)constant_time_select(mask, a, b);
++}
++
++static constant_inline size_t
++constant_time_select_s(size_t mask, size_t a, size_t b)
++{
++	return (value_barrier_s(mask) & a) | (value_barrier_s(~mask) & b);
++}
++
++/* Zero */
++static constant_inline unsigned int
++constant_time_is_zero(unsigned int a)
++{
++	return constant_time_msb(~a & (a - 1));
++}
++
++static constant_inline size_t
++constant_time_is_zero_s(size_t a)
++{
++	return constant_time_msb_s(~a & (a - 1));
++}
++
++/* Comparison*/
++static constant_inline size_t
++constant_time_lt_s(size_t a, size_t b)
++{
++	return constant_time_msb_s(a ^ ((a ^ b) | ((a - b) ^ b)));
++}
++
++static constant_inline unsigned int
++constant_time_lt(unsigned int a, unsigned int b)
++{
++	return constant_time_msb(a ^ ((a ^ b) | ((a - b) ^ b)));
++}
++
++static constant_inline unsigned int
++constant_time_ge(unsigned int a, unsigned int b)
++{
++	return ~constant_time_lt(a, b);
++}
++
++/* Equality*/
++
++static constant_inline unsigned int
++constant_time_eq(unsigned int a, unsigned int b)
++{
++	return constant_time_is_zero(a ^ b);
++}
++
++static constant_inline size_t
++constant_time_eq_s(size_t a, size_t b)
++{
++	return constant_time_is_zero_s(a ^ b);
++}
++
++#endif /* CONSTANT_TIME_H */
+diff --git a/src/libopensc/internal.h b/src/libopensc/internal.h
+index e7ac63ccf..57568d311 100644
+--- a/src/libopensc/internal.h
++++ b/src/libopensc/internal.h
+@@ -166,8 +166,8 @@ int _sc_card_add_xeddsa_alg(struct sc_card *card, unsigned int key_length,
+ 
+ int sc_pkcs1_strip_01_padding(struct sc_context *ctx, const u8 *in_dat, size_t in_len,
+ 		u8 *out_dat, size_t *out_len);
+-int sc_pkcs1_strip_02_padding(struct sc_context *ctx, const u8 *data, size_t len,
+-		u8 *out_dat, size_t *out_len);
++int sc_pkcs1_strip_02_padding_constant_time(sc_context_t *ctx, unsigned int n, const u8 *data,
++		unsigned int data_len, u8 *out, unsigned int *out_len);
+ int sc_pkcs1_strip_digest_info_prefix(unsigned int *algorithm,
+ 		const u8 *in_dat, size_t in_len, u8 *out_dat, size_t *out_len);
+ 
+diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c
+index e4940ea2b..3a8b81c3f 100644
+--- a/src/libopensc/padding.c
++++ b/src/libopensc/padding.c
+@@ -32,10 +32,13 @@
+ #include <string.h>
+ #include <stdlib.h>
+ 
++#include "common/constant-time.h"
+ #include "internal.h"
+ 
+ /* TODO doxygen comments */
+ 
++#define SC_PKCS1_PADDING_MIN_SIZE 11
++
+ /*
+  * Prefixes for pkcs-v1 signatures
+  */
+@@ -143,45 +146,82 @@ sc_pkcs1_strip_01_padding(struct sc_context *ctx, const u8 *in_dat, size_t in_le
+ 	return SC_SUCCESS;
+ }
+ 
+-
+-/* remove pkcs1 BT02 padding (adding BT02 padding is currently not
+- * needed/implemented) */
++/* Remove pkcs1 BT02 padding (adding BT02 padding is currently not
++ * needed/implemented) in constant-time.
++ * Original source: https://github.com/openssl/openssl/blob/9890cc42daff5e2d0cad01ac4bf78c391f599a6e/crypto/rsa/rsa_pk1.c#L171 */
+ int
+-sc_pkcs1_strip_02_padding(sc_context_t *ctx, const u8 *data, size_t len, u8 *out, size_t *out_len)
++sc_pkcs1_strip_02_padding_constant_time(sc_context_t *ctx, unsigned int n, const u8 *data, unsigned int data_len, u8 *out, unsigned int *out_len)
+ {
+-	unsigned int	n = 0;
+-
++	unsigned int i = 0;
++	u8 *msg, *msg_orig = NULL;
++	unsigned int good, found_zero_byte, mask;
++	unsigned int zero_index = 0, msg_index, mlen = -1, len = 0;
+ 	LOG_FUNC_CALLED(ctx);
+-	if (data == NULL || len < 3)
++
++	if (data == NULL || data_len <= 0 || data_len > n || n < SC_PKCS1_PADDING_MIN_SIZE)
+ 		LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
+ 
+-	/* skip leading zero byte */
+-	if (*data == 0) {
+-		data++;
+-		len--;
++	msg = msg_orig = calloc(n, sizeof(u8));
++	if (msg == NULL)
++		LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
++
++	/*
++	 * We can not check length of input data straight away and still we need to read
++	 * from input even when the input is not as long as needed to keep the time constant.
++	 * If data has wrong size, it is padded by zeroes from left and the following checks
++	 * do not pass.
++	 */
++	len = data_len;
++	for (data += len, msg += n, i = 0; i < n; i++) {
++		mask = ~constant_time_is_zero(len);
++		len -= 1 & mask;
++		data -= 1 & mask;
++		*--msg = *data & mask;
++	}
++	// check first byte to be 0x00
++	good = constant_time_is_zero(msg[0]);
++	// check second byte to be 0x02
++	good &= constant_time_eq(msg[1], 2);
++
++	// find zero byte after random data in padding
++	found_zero_byte = 0;
++	for (i = 2; i < n; i++) {
++		unsigned int equals0 = constant_time_is_zero(msg[i]);
++		zero_index = constant_time_select(~found_zero_byte & equals0, i, zero_index);
++		found_zero_byte |= equals0;
+ 	}
+-	if (data[0] != 0x02)
+-		LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_PADDING);
+-	/* skip over padding bytes */
+-	for (n = 1; n < len && data[n]; n++)
+-		;
+-	/* Must be at least 8 pad bytes */
+-	if (n >= len || n < 9)
+-		LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_PADDING);
+-	n++;
+-	if (out == NULL)
+-		/* just check the padding */
+-		LOG_FUNC_RETURN(ctx, SC_SUCCESS);
+ 
+-	/* Now move decrypted contents to head of buffer */
+-	if (*out_len < len - n)
+-		LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
+-	*out_len = len - n;
+-	memmove(out, data + n, *out_len);
++	// zero_index stands for index of last found zero
++	good &= constant_time_ge(zero_index, 2 + 8);
++
++	// start of the actual message in data
++	msg_index = zero_index + 1;
++
++	// length of message
++	mlen = data_len - msg_index;
++
++	// check that message fits into out buffer
++	good &= constant_time_ge(*out_len, mlen);
++
++	// move the result in-place by |num|-SC_PKCS1_PADDING_MIN_SIZE-|mlen| bytes to the left.
++	*out_len = constant_time_select(constant_time_lt(n - SC_PKCS1_PADDING_MIN_SIZE, *out_len),
++			n - SC_PKCS1_PADDING_MIN_SIZE, *out_len);
++	for (msg_index = 1; msg_index < n - SC_PKCS1_PADDING_MIN_SIZE; msg_index <<= 1) {
++		mask = ~constant_time_eq(msg_index & (n - SC_PKCS1_PADDING_MIN_SIZE - mlen), 0);
++		for (i = SC_PKCS1_PADDING_MIN_SIZE; i < n - msg_index; i++)
++			msg[i] = constant_time_select_8(mask, msg[i + msg_index], msg[i]);
++	}
++	// move message into out buffer, if good
++	for (i = 0; i < *out_len; i++) {
++		unsigned int msg_index;
++		// when out is longer than message in data, use some bogus index in msg
++		mask = good & constant_time_lt(i, mlen);
++		msg_index = constant_time_select(mask, i + SC_PKCS1_PADDING_MIN_SIZE, 0); // to now overflow msg buffer
++		out[i] = constant_time_select_8(mask, msg[msg_index], out[i]);
++	}
+ 
+-	sc_log(ctx, "stripped output(%"SC_FORMAT_LEN_SIZE_T"u): %s", len - n,
+-	       sc_dump_hex(out, len - n));
+-	LOG_FUNC_RETURN(ctx, len - n);
++	free(msg_orig);
++	return constant_time_select(good, mlen, SC_ERROR_WRONG_PADDING);
+ }
+ 
+ /* add/remove DigestInfo prefix */
+diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c
+index b86cb77c3..cea46798a 100644
+--- a/src/libopensc/pkcs15-sec.c
++++ b/src/libopensc/pkcs15-sec.c
+@@ -308,8 +308,9 @@ int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card,
+ 
+ 	/* Strip any padding */
+ 	if (pad_flags & SC_ALGORITHM_RSA_PAD_PKCS1) {
+-		size_t s = r;
+-		r = sc_pkcs1_strip_02_padding(ctx, out, s, out, &s);
++		int s = r;
++		int key_size = alg_info->key_length;
++		r = sc_pkcs1_strip_02_padding_constant_time(ctx, key_size / 8, out, s, out, &s);
+ 		LOG_TEST_RET(ctx, r, "Invalid PKCS#1 padding");
+ 	}
+ 
+diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c
+index 0c089feab..e4d693a09 100644
+--- a/src/minidriver/minidriver.c
++++ b/src/minidriver/minidriver.c
+@@ -4582,9 +4582,9 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData,
+ 					  "sc_pkcs15_decipher: DECRYPT-INFO dwVersion=%lu\n",
+ 					  (unsigned long)pInfo->dwVersion);
+ 				if (pInfo->dwPaddingType == CARD_PADDING_PKCS1)   {
+-					size_t temp = pInfo->cbData;
++					unsigned int temp = pInfo->cbData;
+ 					logprintf(pCardData, 2, "sc_pkcs15_decipher: stripping PKCS1 padding\n");
+-					r = sc_pkcs1_strip_02_padding(vs->ctx, pbuf2, pInfo->cbData, pbuf2, &temp);
++					r = sc_pkcs1_strip_02_padding_constant_time(vs->ctx, prkey_info->modulus_length / 8, pbuf2, pInfo->cbData, pbuf2, &temp);
+ 					pInfo->cbData = (DWORD) temp;
+ 					if (r < 0)   {
+ 						logprintf(pCardData, 2, "Cannot strip PKCS1 padding: %i\n", r);
+-- 
+2.50.0
+
diff --git a/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0002.patch b/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0002.patch
new file mode 100644
index 0000000000..6f3ca502ee
--- /dev/null
+++ b/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0002.patch
@@ -0,0 +1,269 @@ 
+From c5ffd28572765a957ecadc8593c0bf0a596f535f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= <vhanulik@redhat.com>
+Date: Mon, 13 Nov 2023 14:31:08 +0100
+Subject: [PATCH 02/10] Add unit tests for PKCS#1 v1.5 de-padding
+
+CVE: CVE-2023-5992
+Upstream-Status: Backport [https://github.com/OpenSC/OpenSC/pull/2948]
+
+Signed-off-by: Zhang Peng <peng.zhang1.cn@windriver.com>
+---
+ src/tests/unittests/Makefile.am             |   5 +-
+ src/tests/unittests/Makefile.mak            |   5 +-
+ src/tests/unittests/strip_pkcs1_2_padding.c | 204 ++++++++++++++++++++
+ 3 files changed, 210 insertions(+), 4 deletions(-)
+ create mode 100644 src/tests/unittests/strip_pkcs1_2_padding.c
+
+diff --git a/src/tests/unittests/Makefile.am b/src/tests/unittests/Makefile.am
+index 03019c324..4ef1c7206 100644
+--- a/src/tests/unittests/Makefile.am
++++ b/src/tests/unittests/Makefile.am
+@@ -6,8 +6,8 @@ include $(top_srcdir)/aminclude_static.am
+ clean-local: code-coverage-clean
+ distclean-local: code-coverage-dist-clean
+ 
+-noinst_PROGRAMS = asn1 simpletlv cachedir
+-TESTS = asn1 simpletlv cachedir
++noinst_PROGRAMS = asn1 simpletlv cachedir strip_pkcs1_2_padding
++TESTS = asn1 simpletlv cachedir strip_pkcs1_2_padding
+ 
+ noinst_HEADERS = torture.h
+ 
+@@ -23,6 +23,7 @@ LDADD = $(top_builddir)/src/libopensc/libopensc.la \
+ asn1_SOURCES = asn1.c
+ simpletlv_SOURCES = simpletlv.c
+ cachedir_SOURCES = cachedir.c
++strip_pkcs1_2_padding = strip_pkcs1_2_padding.c
+ 
+ if ENABLE_ZLIB
+ noinst_PROGRAMS += compression
+diff --git a/src/tests/unittests/Makefile.mak b/src/tests/unittests/Makefile.mak
+index 41762fdbf..a04086a67 100644
+--- a/src/tests/unittests/Makefile.mak
++++ b/src/tests/unittests/Makefile.mak
+@@ -1,9 +1,10 @@
+ TOPDIR = ..\..\..
+ 
+-TARGETS = asn1 compression
++TARGETS = asn1 compression strip_pkcs1_2_padding
+ 
+ OBJECTS = asn1.obj \
+-	compression.obj
++	compression.obj \
++	strip_pkcs1_2_padding.obj \
+ 	$(TOPDIR)\win32\versioninfo.res
+ 
+ all: $(TARGETS)
+diff --git a/src/tests/unittests/strip_pkcs1_2_padding.c b/src/tests/unittests/strip_pkcs1_2_padding.c
+new file mode 100644
+index 000000000..f9561b936
+--- /dev/null
++++ b/src/tests/unittests/strip_pkcs1_2_padding.c
+@@ -0,0 +1,204 @@
++#include "common/compat_strlcpy.c"
++#include "libopensc/log.c"
++#include "libopensc/padding.c"
++#include "torture.h"
++#include <cmocka.h>
++
++static void
++torture_long_output_buffer(void **state)
++{
++	unsigned int n = 14;
++	unsigned int in_len = 14;
++	unsigned char in[] = {0x00, 0x02,
++			0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
++			0x00,
++			'm', 's', 'g'};
++	unsigned int out_len = 3;
++	unsigned char *out = malloc(out_len * sizeof(unsigned char));
++	unsigned char result_msg[] = {'m', 's', 'g'};
++	int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
++	assert_int_equal(r, 3);
++	assert_memory_equal(out, result_msg, r);
++	free(out);
++}
++
++static void
++torture_short_output_buffer(void **state)
++{
++	unsigned int n = 14;
++	unsigned int in_len = 14;
++	unsigned char in[] = {0x00, 0x02,
++			0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
++			0x00,
++			'm', 's', 'g'};
++	unsigned int out_len = 1;
++	unsigned char *out = malloc(out_len * sizeof(unsigned char));
++	int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
++	assert_int_equal(r, SC_ERROR_WRONG_PADDING);
++	free(out);
++}
++
++static void
++torture_short_message_correct_padding(void **state)
++{
++	unsigned int n = 14;
++	unsigned int in_len = 14;
++	unsigned char in[] = {0x00, 0x02,
++			0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
++			0x00,
++			'm', 's', 'g'};
++	unsigned int out_len = 3;
++	unsigned char *out = malloc(out_len * sizeof(unsigned char));
++	unsigned char result_msg[] = {'m', 's', 'g'};
++	int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
++	assert_int_equal(r, 3);
++	assert_memory_equal(out, result_msg, r);
++	free(out);
++}
++
++static void
++torture_missing_first_zero(void **state)
++{
++	unsigned int n = 13;
++	unsigned int in_len = 13;
++	unsigned char in[] = {0x02,
++			0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
++			0x00,
++			'm', 's', 'g'};
++	unsigned int out_len = 10;
++	unsigned char *out = malloc(out_len * sizeof(unsigned char));
++	int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
++	assert_int_equal(r, SC_ERROR_WRONG_PADDING);
++	free(out);
++}
++
++static void
++torture_missing_two(void **state)
++{
++	unsigned int n = 13;
++	unsigned int in_len = 13;
++	unsigned char in[] = {0x00,
++			0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
++			0x00,
++			'm', 's', 'g'};
++	unsigned int out_len = 10;
++	unsigned char *out = malloc(out_len * sizeof(unsigned char));
++	int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
++	assert_int_equal(r, SC_ERROR_WRONG_PADDING);
++	free(out);
++}
++
++static void
++torture_short_padding(void **state)
++{
++	unsigned int n = 13;
++	unsigned int in_len = 13;
++	unsigned char in[] = {0x00, 0x02,
++			0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++			0x00,
++			'm', 's', 'g'};
++	unsigned int out_len = 10;
++	unsigned char *out = malloc(out_len * sizeof(unsigned char));
++	int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
++	assert_int_equal(r, SC_ERROR_WRONG_PADDING);
++	free(out);
++}
++
++static void
++torture_missing_second_zero(void **state)
++{
++	unsigned int n = 13;
++	unsigned int in_len = 13;
++	unsigned char in[] = {0x00, 0x02,
++			0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
++			'm', 's', 'g'};
++	unsigned int out_len = 10;
++	unsigned char *out = malloc(out_len * sizeof(unsigned char));
++	int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
++	assert_int_equal(r, SC_ERROR_WRONG_PADDING);
++	free(out);
++}
++
++static void
++torture_missing_message(void **state)
++{
++	unsigned int n = 20;
++	unsigned int in_len = 11;
++	unsigned char in[] = {0x00, 0x02,
++			0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
++			0x00};
++	unsigned int out_len = 11;
++	unsigned char *out = malloc(out_len * sizeof(unsigned char));
++	int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
++	assert_int_equal(r, SC_ERROR_WRONG_PADDING);
++	free(out);
++}
++
++static void
++torture_one_byte_message(void **state)
++{
++	unsigned int n = 12;
++	unsigned int in_len = 12;
++	unsigned char in[] = {0x00, 0x02,
++			0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
++			0x00,
++			'm'};
++	unsigned int out_len = 1;
++	unsigned char *out = malloc(out_len * sizeof(unsigned char));
++	unsigned char result_msg[] = {'m'};
++	int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
++	assert_int_equal(r, 1);
++	assert_memory_equal(out, result_msg, r);
++	free(out);
++}
++
++static void
++torture_longer_padding(void **state)
++{
++	unsigned int n = 26;
++	unsigned int in_len = 26;
++	unsigned char in[] = {0x00, 0x02,
++			0x0e, 0x38, 0x97, 0x18, 0x16, 0x57, 0x9e, 0x30, 0xb6, 0xa5, 0x78, 0x13, 0x20, 0xca, 0x11,
++			0x00,
++			0x9d, 0x98, 0x3d, 0xca, 0xa9, 0xa7, 0x11, 0x0a};
++	unsigned int out_len = 8;
++	unsigned char *out = malloc(out_len * sizeof(unsigned char));
++	unsigned char result_msg[] = {0x9d, 0x98, 0x3d, 0xca, 0xa9, 0xa7, 0x11, 0x0a};
++	int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
++	assert_int_equal(r, 8);
++	assert_memory_equal(out, result_msg, r);
++	free(out);
++}
++
++static void
++torture_empty_message(void **state)
++{
++	unsigned int n = 18;
++	unsigned int in_len = 18;
++	unsigned char in[] = {0x00, 0x02,
++			0x0e, 0x38, 0x97, 0x18, 0x16, 0x57, 0x9e, 0x30, 0xb6, 0xa5, 0x78, 0x13, 0x20, 0xca, 0x11,
++			0x00};
++	unsigned int out_len = 8;
++	unsigned char *out = malloc(out_len * sizeof(unsigned char));
++	int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
++	assert_int_equal(r, 0);
++	free(out);
++}
++
++int
++main(void)
++{
++	const struct CMUnitTest tests[] = {
++			cmocka_unit_test(torture_long_output_buffer),
++			cmocka_unit_test(torture_short_output_buffer),
++			cmocka_unit_test(torture_short_message_correct_padding),
++			cmocka_unit_test(torture_missing_first_zero),
++			cmocka_unit_test(torture_missing_two),
++			cmocka_unit_test(torture_short_padding),
++			cmocka_unit_test(torture_missing_second_zero),
++			cmocka_unit_test(torture_missing_message),
++			cmocka_unit_test(torture_one_byte_message),
++			cmocka_unit_test(torture_longer_padding),
++			cmocka_unit_test(torture_empty_message)};
++	return cmocka_run_group_tests(tests, NULL, NULL);
++}
+-- 
+2.50.0
+
diff --git a/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0003.patch b/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0003.patch
new file mode 100644
index 0000000000..52a73064dc
--- /dev/null
+++ b/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0003.patch
@@ -0,0 +1,41 @@ 
+From 7266f151bb5896b9213d4cf0a298859a53cfb750 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= <vhanulik@redhat.com>
+Date: Thu, 16 Nov 2023 10:38:12 +0100
+Subject: [PATCH 03/10] pkcs15-sec: Remove logging after PKCS#1 v1.5 depadding
+
+To prevent Marvin attack on RSA PKCS#1 v1.5 padding
+when logging the return value, signaling the padding error.
+
+CVE: CVE-2023-5992
+Upstream-Status: Backport [https://github.com/OpenSC/OpenSC/pull/2948]
+
+Signed-off-by: Zhang Peng <peng.zhang1.cn@windriver.com>
+---
+ src/libopensc/pkcs15-sec.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c
+index cea46798a..b04856b4d 100644
+--- a/src/libopensc/pkcs15-sec.c
++++ b/src/libopensc/pkcs15-sec.c
+@@ -308,13 +308,13 @@ int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card,
+ 
+ 	/* Strip any padding */
+ 	if (pad_flags & SC_ALGORITHM_RSA_PAD_PKCS1) {
+-		int s = r;
+-		int key_size = alg_info->key_length;
++		unsigned int s = r;
++		unsigned int key_size = (unsigned int)alg_info->key_length;
+ 		r = sc_pkcs1_strip_02_padding_constant_time(ctx, key_size / 8, out, s, out, &s);
+-		LOG_TEST_RET(ctx, r, "Invalid PKCS#1 padding");
++		/* for keeping PKCS#1 v1.5 depadding constant-time, do not log error here */
+ 	}
+ 
+-	LOG_FUNC_RETURN(ctx, r);
++	return r;
+ }
+ 
+ /* derive one key from another. RSA can use decipher, so this is for only ECDH
+-- 
+2.50.0
+
diff --git a/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0004.patch b/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0004.patch
new file mode 100644
index 0000000000..459e1d2a61
--- /dev/null
+++ b/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0004.patch
@@ -0,0 +1,109 @@ 
+From 663dcbae0d92a05eba28ca56b80346b2fbe5a6d5 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= <vhanulik@redhat.com>
+Date: Thu, 16 Nov 2023 15:49:15 +0100
+Subject: [PATCH 04/10] framework-pkcs15.c: Handle PKCS#1 v1.5 depadding
+ constant-time
+
+In order to not disclose time side-channel when the depadding
+fails, do the same operations as for case when depadding ends
+with success.
+
+CVE: CVE-2023-5992
+Upstream-Status: Backport [https://github.com/OpenSC/OpenSC/pull/2948]
+
+Signed-off-by: Zhang Peng <peng.zhang1.cn@windriver.com>
+---
+ src/pkcs11/framework-pkcs15.c | 54 ++++++++++++++++++++++++++---------
+ 1 file changed, 41 insertions(+), 13 deletions(-)
+
+diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c
+index 4fc8f13ab..8376057ea 100644
+--- a/src/pkcs11/framework-pkcs15.c
++++ b/src/pkcs11/framework-pkcs15.c
+@@ -18,6 +18,7 @@
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+  */
+ 
++#include "common/constant-time.h"
+ #include "config.h"
+ #include <stdlib.h>
+ #include <string.h>
+@@ -4341,7 +4342,8 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *session, void *obj,
+ 	struct pkcs15_fw_data *fw_data = NULL;
+ 	struct pkcs15_prkey_object *prkey;
+ 	unsigned char decrypted[512]; /* FIXME: Will not work for keys above 4096 bits */
+-	int	buff_too_small, rv, flags = 0, prkey_has_path = 0;
++	int rv, flags = 0, prkey_has_path = 0;
++	CK_ULONG mask, good, rv_pkcs11;
+ 
+ 	sc_log(context, "Initiating decryption.");
+ 
+@@ -4415,27 +4417,53 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *session, void *obj,
+ 	rv = sc_pkcs15_decipher(fw_data->p15_card, prkey->prv_p15obj, flags,
+ 			pEncryptedData, ulEncryptedDataLen, decrypted, sizeof(decrypted));
+ 
+-	if (rv < 0 && !sc_pkcs11_conf.lock_login && !prkey_has_path)
++	/* skip for PKCS#1 v1.5 padding prevent side channel attack */
++	if (!(flags & SC_ALGORITHM_RSA_PAD_PKCS1) &&
++			rv < 0 && !sc_pkcs11_conf.lock_login && !prkey_has_path)
+ 		if (reselect_app_df(fw_data->p15_card) == SC_SUCCESS)
+ 			rv = sc_pkcs15_decipher(fw_data->p15_card, prkey->prv_p15obj, flags,
+ 					pEncryptedData, ulEncryptedDataLen, decrypted, sizeof(decrypted));
+ 
+ 	sc_unlock(p11card->card);
+ 
+-	sc_log(context, "Decryption complete. Result %d.", rv);
++	sc_log(context, "Decryption complete.");
+ 
+-	if (rv < 0)
+-		return sc_to_cryptoki_error(rv, "C_Decrypt");
++	/* Handle following code in constant-time
++	 * to prevent Marvin attack for PKCS#1 v1.5 padding. */
+ 
+-	buff_too_small = (*pulDataLen < (CK_ULONG)rv);
+-	*pulDataLen = rv;
+-	if (pData == NULL_PTR)
+-		return CKR_OK;
+-	if (buff_too_small)
+-		return CKR_BUFFER_TOO_SMALL;
+-	memcpy(pData, decrypted, *pulDataLen);
++	/* only padding error must be handled in constant-time way,
++	 * other error can be returned straight away */
++	if ((~constant_time_eq_s(rv, SC_ERROR_WRONG_PADDING) & constant_time_lt_s(sizeof(decrypted), rv)))
++		return sc_to_cryptoki_error(rv, "C_Decrypt");
+ 
+-	return CKR_OK;
++	/* check rv for padding error */
++	good = ~constant_time_eq_s(rv, SC_ERROR_WRONG_PADDING);
++	rv_pkcs11 = sc_to_cryptoki_error(SC_ERROR_WRONG_PADDING, "C_Decrypt");
++	rv_pkcs11 = constant_time_select_s(good, CKR_OK, rv_pkcs11);
++
++	if (pData == NULL_PTR) {
++		/* set length only if no error */
++		*pulDataLen = constant_time_select_s(good, rv, *pulDataLen);
++		/* return error only if original rv < 0 */
++		return rv_pkcs11;
++	}
++
++	/* check whether *pulDataLen < rv and set return value for small output buffer */
++	mask = good & constant_time_lt_s(*pulDataLen, rv);
++	rv_pkcs11 = constant_time_select_s(mask, CKR_BUFFER_TOO_SMALL, rv_pkcs11);
++	good &= ~mask;
++
++	/* move everything from decrypted into out buffer constant-time, if rv is ok */
++	for (CK_ULONG i = 0; i < *pulDataLen; i++) { /* iterate over whole pData to not disclose real depadded length */
++		CK_ULONG msg_index;
++		mask = good & constant_time_lt_s(i, sizeof(decrypted));		    /* i should be in the bounds of decrypted */
++		mask &= constant_time_lt_s(i, constant_time_select_s(good, rv, 0)); /* check that is in bounds of depadded message */
++		msg_index = constant_time_select_s(mask, i, 0);
++		pData[i] = constant_time_select_8(mask, decrypted[msg_index], pData[i]);
++	}
++	*pulDataLen = constant_time_select_s(good, rv, *pulDataLen);
++	/* do not log error code to prevent side channel attack */
++	return rv_pkcs11;
+ }
+ 
+ 
+-- 
+2.50.0
+
diff --git a/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0005.patch b/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0005.patch
new file mode 100644
index 0000000000..a52b964306
--- /dev/null
+++ b/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0005.patch
@@ -0,0 +1,63 @@ 
+From f7fc30b02090d657b9ba64cbb5168cb5a94592ef Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= <vhanulik@redhat.com>
+Date: Mon, 8 Jan 2024 14:59:22 +0100
+Subject: [PATCH 05/10] mechanism: Handle PKCS#1 v1.5 depadding constant-time
+
+CVE: CVE-2023-5992
+Upstream-Status: Backport [https://github.com/OpenSC/OpenSC/pull/2948]
+
+Signed-off-by: Zhang Peng <peng.zhang1.cn@windriver.com>
+---
+ src/pkcs11/mechanism.c | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c
+index c5959b36b..b3fce1714 100644
+--- a/src/pkcs11/mechanism.c
++++ b/src/pkcs11/mechanism.c
+@@ -23,6 +23,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ 
++#include "common/constant-time.h"
+ #include "sc-pkcs11.h"
+ 
+ /* Also used for verification data */
+@@ -844,7 +845,9 @@ sc_pkcs11_decr(struct sc_pkcs11_session *session,
+ 	rv = op->type->decrypt(op, pEncryptedData, ulEncryptedDataLen,
+ 	                       pData, pulDataLen);
+ 
+-	if (rv != CKR_BUFFER_TOO_SMALL && pData != NULL)
++	/* terminate session for any return value except CKR_BUFFER_TOO_SMALL,
++	 * perform check in time side-channel free way to prevent Marvin attack */
++	if (!constant_time_eq_s(rv, CKR_BUFFER_TOO_SMALL) && pData != NULL)
+ 		session_stop_operation(session, SC_PKCS11_OPERATION_DECRYPT);
+ 
+ 	return rv;
+@@ -1084,14 +1087,22 @@ sc_pkcs11_decrypt(sc_pkcs11_operation_t *operation,
+ {
+ 	struct signature_data *data;
+ 	struct sc_pkcs11_object *key;
++	CK_RV rv;
+ 
+ 	data = (struct signature_data*) operation->priv_data;
+ 
+ 	key = data->key;
+-	return key->ops->decrypt(operation->session,
++	rv = key->ops->decrypt(operation->session,
+ 				key, &operation->mechanism,
+ 				pEncryptedData, ulEncryptedDataLen,
+ 				pData, pulDataLen);
++
++	/* Skip DecryptFinalize for PKCS#1 v1.5 padding to prevent time side-channel leakage */
++	if (((CK_MECHANISM_PTR)&operation->mechanism)->mechanism == CKM_RSA_PKCS)
++		return rv;
++		
++	if (rv != CKR_OK)
++		return rv;
+ }
+ 
+ static CK_RV
+-- 
+2.50.0
+
diff --git a/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0006.patch b/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0006.patch
new file mode 100644
index 0000000000..b9c1f8ce3e
--- /dev/null
+++ b/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0006.patch
@@ -0,0 +1,118 @@ 
+From 224a5a9bb32a8eb575dc30f18004c069c62fc8b1 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= <vhanulik@redhat.com>
+Date: Wed, 22 Nov 2023 15:02:57 +0100
+Subject: [PATCH 06/10] minidriver: Make CardRSADecrypt constant-time
+
+CVE: CVE-2023-5992
+Upstream-Status: Backport [https://github.com/OpenSC/OpenSC/pull/2948]
+
+Signed-off-by: Zhang Peng <peng.zhang1.cn@windriver.com>
+---
+ src/minidriver/minidriver.c | 36 +++++++++++++++++++++++-------------
+ 1 file changed, 23 insertions(+), 13 deletions(-)
+
+diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c
+index e4d693a09..37e576ba2 100644
+--- a/src/minidriver/minidriver.c
++++ b/src/minidriver/minidriver.c
+@@ -41,6 +41,7 @@
+ #include "cardmod.h"
+ 
+ #include "common/compat_strlcpy.h"
++#include "common/constant-time.h"
+ #include "libopensc/asn1.h"
+ #include "libopensc/cardctl.h"
+ #include "libopensc/opensc.h"
+@@ -4463,13 +4464,15 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData,
+ 
+ {
+ 	DWORD dwret;
+-	int r, opt_crypt_flags = 0;
++	int r, opt_crypt_flags = 0, good = 0;
+ 	unsigned ui;
+ 	VENDOR_SPECIFIC *vs;
+ 	struct sc_pkcs15_prkey_info *prkey_info;
+ 	BYTE *pbuf = NULL, *pbuf2 = NULL;
+ 	struct sc_pkcs15_object *pkey = NULL;
+ 	struct sc_algorithm_info *alg_info = NULL;
++	unsigned int wrong_padding = 0;
++	unsigned int pbufLen = 0;
+ 
+ 	MD_FUNC_CALLED(pCardData, 1);
+ 
+@@ -4570,10 +4573,11 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData,
+ 		goto err;
+ 	}
+ 
++	pbufLen = pInfo->cbData;
+ 	if (alg_info->flags & SC_ALGORITHM_RSA_RAW)   {
+ 		logprintf(pCardData, 2, "sc_pkcs15_decipher: using RSA-RAW mechanism\n");
+ 		r = sc_pkcs15_decipher(vs->p15card, pkey, opt_crypt_flags, pbuf, pInfo->cbData, pbuf2, pInfo->cbData);
+-		logprintf(pCardData, 2, "sc_pkcs15_decipher returned %d\n", r);
++		/* do not log return value to not leak it */
+ 
+ 		if (r > 0) {
+ 			/* Need to handle padding */
+@@ -4586,13 +4590,9 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData,
+ 					logprintf(pCardData, 2, "sc_pkcs15_decipher: stripping PKCS1 padding\n");
+ 					r = sc_pkcs1_strip_02_padding_constant_time(vs->ctx, prkey_info->modulus_length / 8, pbuf2, pInfo->cbData, pbuf2, &temp);
+ 					pInfo->cbData = (DWORD) temp;
+-					if (r < 0)   {
+-						logprintf(pCardData, 2, "Cannot strip PKCS1 padding: %i\n", r);
+-						pCardData->pfnCspFree(pbuf);
+-						pCardData->pfnCspFree(pbuf2);
+-						dwret = SCARD_F_INTERNAL_ERROR;
+-						goto err;
+-					}
++					wrong_padding = constant_time_eq_s(r, SC_ERROR_WRONG_PADDING);
++					/* continue without returning error to not leak that padding is wrong
++					   to prevent time side-channel leak for Marvin attack*/
+ 				}
+ 				else if (pInfo->dwPaddingType == CARD_PADDING_OAEP)   {
+ 					/* TODO: Handle OAEP padding if present - can call PFN_CSP_UNPAD_DATA */
+@@ -4640,28 +4640,38 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData,
+ 		goto err;
+ 	}
+ 
+-	if ( r < 0)   {
++	good = constant_time_eq_s(r, 0);
++	/* if no error or padding error, do not return here to prevent Marvin attack */
++	if (!(good | wrong_padding) && r < 0)   {
+ 		logprintf(pCardData, 2, "sc_pkcs15_decipher error(%i): %s\n", r, sc_strerror(r));
+ 		pCardData->pfnCspFree(pbuf);
+ 		pCardData->pfnCspFree(pbuf2);
+ 		dwret = md_translate_OpenSC_to_Windows_error(r, SCARD_E_INVALID_VALUE);
+ 		goto err;
+ 	}
++	dwret = constant_time_select_s(good, SCARD_S_SUCCESS, SCARD_F_INTERNAL_ERROR);
+ 
+ 	logprintf(pCardData, 2, "decrypted data(%lu):\n",
+ 		  (unsigned long)pInfo->cbData);
+ 	loghex(pCardData, 7, pbuf2, pInfo->cbData);
+ 
+ 	/*inversion donnees */
+-	for(ui = 0; ui < pInfo->cbData; ui++)
+-		pInfo->pbData[ui] = pbuf2[pInfo->cbData-ui-1];
++	/* copy data in constant-time way to prevent leak */
++	for (ui = 0; ui < pbufLen; ui++) {
++		unsigned int mask, msg_index, inv_ui;
++		mask = good & constant_time_lt_s(ui, pInfo->cbData); /* ui should be in the bounds of pbuf2 */
++		inv_ui = pInfo->cbData - ui - 1;
++		msg_index = constant_time_select_s(mask, inv_ui, 0);
++		pInfo->pbData[ui] = constant_time_select_8(mask, pbuf2[msg_index], pInfo->pbData[ui]);
++	}
+ 
+ 	pCardData->pfnCspFree(pbuf);
+ 	pCardData->pfnCspFree(pbuf2);
+ 
+ err:
+ 	unlock(pCardData);
+-	MD_FUNC_RETURN(pCardData, 1, dwret);
++	/* do not log return value to not leak it */
++	return dwret;
+ }
+ 
+ 
+-- 
+2.50.0
+
diff --git a/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0007.patch b/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0007.patch
new file mode 100644
index 0000000000..ccd44833fa
--- /dev/null
+++ b/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0007.patch
@@ -0,0 +1,50 @@ 
+From 65f81aa8cdb8fa7e3c54165c9c800e6dae5591c7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= <vhanulik@redhat.com>
+Date: Fri, 24 Nov 2023 20:59:07 +0100
+Subject: [PATCH 07/10] pkcs11-object: Remove return value logging
+
+To prevent Marvin attack on RSA PKCS#1 v1.5 padding
+when logging the return value, signaling the padding error.
+
+CVE: CVE-2023-5992
+Upstream-Status: Backport [https://github.com/OpenSC/OpenSC/pull/2948]
+
+Signed-off-by: Zhang Peng <peng.zhang1.cn@windriver.com>
+---
+ src/pkcs11/pkcs11-object.c | 3 ++-
+ src/pkcs11/sc-pkcs11.h     | 5 +++++
+ 2 files changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/src/pkcs11/pkcs11-object.c b/src/pkcs11/pkcs11-object.c
+index c5cf78a2b..aae149b86 100644
+--- a/src/pkcs11/pkcs11-object.c
++++ b/src/pkcs11/pkcs11-object.c
+@@ -930,7 +930,8 @@ CK_RV C_Decrypt(CK_SESSION_HANDLE hSession,	/* the session's handle */
+ 		rv = reset_login_state(session->slot, rv);
+ 	}
+ 
+-	sc_log(context, "C_Decrypt() = %s", lookup_enum ( RV_T, rv ));
++	/* do not log error code to prevent side channel attack */
++	SC_LOG("C_Decrypt()");
+ 	sc_pkcs11_unlock();
+ 	return rv;
+ }
+diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h
+index 3c6b92ba4..35c8d5eb3 100644
+--- a/src/pkcs11/sc-pkcs11.h
++++ b/src/pkcs11/sc-pkcs11.h
+@@ -226,6 +226,11 @@ struct sc_pkcs11_slot {
+ };
+ typedef struct sc_pkcs11_slot sc_pkcs11_slot_t;
+ 
++#define SC_LOG(fmt) \
++	do { \
++		sc_log(context, (fmt)); \
++	} while (0)
++
+ /* Debug virtual slots. S is slot to be highlighted or NULL
+  * C is a comment format string and args It will be preceded by "VSS " */
+ #define DEBUG_VSS(S, ...) do { sc_log(context,"VSS " __VA_ARGS__); _debug_virtual_slots(S); } while (0)
+-- 
+2.50.0
+
diff --git a/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0008.patch b/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0008.patch
new file mode 100644
index 0000000000..d50337902d
--- /dev/null
+++ b/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0008.patch
@@ -0,0 +1,37 @@ 
+From 60f1966c06ed5fbe9e9e1edeefa2d280f5341484 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= <vhanulik@redhat.com>
+Date: Fri, 24 Nov 2023 21:00:23 +0100
+Subject: [PATCH 08/10] misc: Compare return value constant-time
+
+CVE: CVE-2023-5992
+Upstream-Status: Backport [https://github.com/OpenSC/OpenSC/pull/2948]
+
+Signed-off-by: Zhang Peng <peng.zhang1.cn@windriver.com>
+---
+ src/pkcs11/misc.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/pkcs11/misc.c b/src/pkcs11/misc.c
+index c3f5bb4e1..c0fd07240 100644
+--- a/src/pkcs11/misc.c
++++ b/src/pkcs11/misc.c
+@@ -23,6 +23,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ 
++#include "common/constant-time.h"
+ #include "sc-pkcs11.h"
+ 
+ #define DUMP_TEMPLATE_MAX	32
+@@ -172,7 +173,7 @@ CK_RV reset_login_state(struct sc_pkcs11_slot *slot, CK_RV rv)
+ 			slot->p11card->framework->logout(slot);
+ 		}
+ 
+-		if (rv == CKR_USER_NOT_LOGGED_IN) {
++		if (constant_time_eq_s(rv, CKR_USER_NOT_LOGGED_IN)) {
+ 			slot->login_user = -1;
+ 			pop_all_login_states(slot);
+ 		}
+-- 
+2.50.0
+
diff --git a/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0009.patch b/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0009.patch
new file mode 100644
index 0000000000..d65555bca9
--- /dev/null
+++ b/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0009.patch
@@ -0,0 +1,123 @@ 
+From e5f77a60bf22d76f695e360cc5c13c5c9ea8ba0c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= <vhanulik@redhat.com>
+Date: Mon, 5 Feb 2024 11:30:11 +0100
+Subject: [PATCH 09/10] unittests: Do not use uninitialized memory
+
+Thanks Coverity CID 414676, 414677, 414678,
+414679, 414680, 414681, 414682, 414683, 414684,
+414685, 414686
+
+CVE: CVE-2023-5992
+Upstream-Status: Backport [https://github.com/OpenSC/OpenSC/pull/3016]
+
+Signed-off-by: Zhang Peng <peng.zhang1.cn@windriver.com>
+---
+ src/tests/unittests/strip_pkcs1_2_padding.c | 22 ++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/src/tests/unittests/strip_pkcs1_2_padding.c b/src/tests/unittests/strip_pkcs1_2_padding.c
+index f9561b936..990e94a38 100644
+--- a/src/tests/unittests/strip_pkcs1_2_padding.c
++++ b/src/tests/unittests/strip_pkcs1_2_padding.c
+@@ -14,7 +14,7 @@ torture_long_output_buffer(void **state)
+ 			0x00,
+ 			'm', 's', 'g'};
+ 	unsigned int out_len = 3;
+-	unsigned char *out = malloc(out_len * sizeof(unsigned char));
++	unsigned char *out = calloc(out_len, sizeof(unsigned char));
+ 	unsigned char result_msg[] = {'m', 's', 'g'};
+ 	int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
+ 	assert_int_equal(r, 3);
+@@ -32,7 +32,7 @@ torture_short_output_buffer(void **state)
+ 			0x00,
+ 			'm', 's', 'g'};
+ 	unsigned int out_len = 1;
+-	unsigned char *out = malloc(out_len * sizeof(unsigned char));
++	unsigned char *out = calloc(out_len, sizeof(unsigned char));
+ 	int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
+ 	assert_int_equal(r, SC_ERROR_WRONG_PADDING);
+ 	free(out);
+@@ -48,7 +48,7 @@ torture_short_message_correct_padding(void **state)
+ 			0x00,
+ 			'm', 's', 'g'};
+ 	unsigned int out_len = 3;
+-	unsigned char *out = malloc(out_len * sizeof(unsigned char));
++	unsigned char *out = calloc(out_len, sizeof(unsigned char));
+ 	unsigned char result_msg[] = {'m', 's', 'g'};
+ 	int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
+ 	assert_int_equal(r, 3);
+@@ -66,7 +66,7 @@ torture_missing_first_zero(void **state)
+ 			0x00,
+ 			'm', 's', 'g'};
+ 	unsigned int out_len = 10;
+-	unsigned char *out = malloc(out_len * sizeof(unsigned char));
++	unsigned char *out = calloc(out_len, sizeof(unsigned char));
+ 	int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
+ 	assert_int_equal(r, SC_ERROR_WRONG_PADDING);
+ 	free(out);
+@@ -82,7 +82,7 @@ torture_missing_two(void **state)
+ 			0x00,
+ 			'm', 's', 'g'};
+ 	unsigned int out_len = 10;
+-	unsigned char *out = malloc(out_len * sizeof(unsigned char));
++	unsigned char *out = calloc(out_len, sizeof(unsigned char));
+ 	int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
+ 	assert_int_equal(r, SC_ERROR_WRONG_PADDING);
+ 	free(out);
+@@ -98,7 +98,7 @@ torture_short_padding(void **state)
+ 			0x00,
+ 			'm', 's', 'g'};
+ 	unsigned int out_len = 10;
+-	unsigned char *out = malloc(out_len * sizeof(unsigned char));
++	unsigned char *out = calloc(out_len, sizeof(unsigned char));
+ 	int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
+ 	assert_int_equal(r, SC_ERROR_WRONG_PADDING);
+ 	free(out);
+@@ -113,7 +113,7 @@ torture_missing_second_zero(void **state)
+ 			0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 			'm', 's', 'g'};
+ 	unsigned int out_len = 10;
+-	unsigned char *out = malloc(out_len * sizeof(unsigned char));
++	unsigned char *out = calloc(out_len, sizeof(unsigned char));
+ 	int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
+ 	assert_int_equal(r, SC_ERROR_WRONG_PADDING);
+ 	free(out);
+@@ -128,7 +128,7 @@ torture_missing_message(void **state)
+ 			0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 			0x00};
+ 	unsigned int out_len = 11;
+-	unsigned char *out = malloc(out_len * sizeof(unsigned char));
++	unsigned char *out = calloc(out_len, sizeof(unsigned char));
+ 	int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
+ 	assert_int_equal(r, SC_ERROR_WRONG_PADDING);
+ 	free(out);
+@@ -144,7 +144,7 @@ torture_one_byte_message(void **state)
+ 			0x00,
+ 			'm'};
+ 	unsigned int out_len = 1;
+-	unsigned char *out = malloc(out_len * sizeof(unsigned char));
++	unsigned char *out = calloc(out_len, sizeof(unsigned char));
+ 	unsigned char result_msg[] = {'m'};
+ 	int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
+ 	assert_int_equal(r, 1);
+@@ -162,7 +162,7 @@ torture_longer_padding(void **state)
+ 			0x00,
+ 			0x9d, 0x98, 0x3d, 0xca, 0xa9, 0xa7, 0x11, 0x0a};
+ 	unsigned int out_len = 8;
+-	unsigned char *out = malloc(out_len * sizeof(unsigned char));
++	unsigned char *out = calloc(out_len, sizeof(unsigned char));
+ 	unsigned char result_msg[] = {0x9d, 0x98, 0x3d, 0xca, 0xa9, 0xa7, 0x11, 0x0a};
+ 	int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
+ 	assert_int_equal(r, 8);
+@@ -179,7 +179,7 @@ torture_empty_message(void **state)
+ 			0x0e, 0x38, 0x97, 0x18, 0x16, 0x57, 0x9e, 0x30, 0xb6, 0xa5, 0x78, 0x13, 0x20, 0xca, 0x11,
+ 			0x00};
+ 	unsigned int out_len = 8;
+-	unsigned char *out = malloc(out_len * sizeof(unsigned char));
++	unsigned char *out = calloc(out_len, sizeof(unsigned char));
+ 	int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
+ 	assert_int_equal(r, 0);
+ 	free(out);
+-- 
+2.50.0
+
diff --git a/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0010.patch b/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0010.patch
new file mode 100644
index 0000000000..2585406b56
--- /dev/null
+++ b/meta-oe/recipes-support/opensc/files/CVE-2023-5992-0010.patch
@@ -0,0 +1,75 @@ 
+From 0039fe386c996faffaa2cf2d728c176cc239468b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= <vhanulik@redhat.com>
+Date: Mon, 5 Feb 2024 13:33:05 +0100
+Subject: [PATCH 10/10] Fix constant-time comparison of negative values
+
+Thanks Coverity CID 414687
+
+CVE: CVE-2023-5992
+Upstream-Status: Backport [https://github.com/OpenSC/OpenSC/pull/3016]
+
+Signed-off-by: Zhang Peng <peng.zhang1.cn@windriver.com>
+---
+ src/common/constant-time.h    | 6 ++++++
+ src/minidriver/minidriver.c   | 4 ++--
+ src/pkcs11/framework-pkcs15.c | 4 ++--
+ 3 files changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/src/common/constant-time.h b/src/common/constant-time.h
+index 40c3e500c..3f4446d4d 100644
+--- a/src/common/constant-time.h
++++ b/src/common/constant-time.h
+@@ -125,4 +125,10 @@ constant_time_eq_s(size_t a, size_t b)
+ 	return constant_time_is_zero_s(a ^ b);
+ }
+ 
++static constant_inline unsigned int
++constant_time_eq_i(int a, int b)
++{
++	return constant_time_eq((unsigned int)a, (unsigned int)b);
++}
++
+ #endif /* CONSTANT_TIME_H */
+diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c
+index 37e576ba2..e2be9e53d 100644
+--- a/src/minidriver/minidriver.c
++++ b/src/minidriver/minidriver.c
+@@ -4590,7 +4590,7 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData,
+ 					logprintf(pCardData, 2, "sc_pkcs15_decipher: stripping PKCS1 padding\n");
+ 					r = sc_pkcs1_strip_02_padding_constant_time(vs->ctx, prkey_info->modulus_length / 8, pbuf2, pInfo->cbData, pbuf2, &temp);
+ 					pInfo->cbData = (DWORD) temp;
+-					wrong_padding = constant_time_eq_s(r, SC_ERROR_WRONG_PADDING);
++					wrong_padding = constant_time_eq_i(r, SC_ERROR_WRONG_PADDING);
+ 					/* continue without returning error to not leak that padding is wrong
+ 					   to prevent time side-channel leak for Marvin attack*/
+ 				}
+@@ -4640,7 +4640,7 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData,
+ 		goto err;
+ 	}
+ 
+-	good = constant_time_eq_s(r, 0);
++	good = constant_time_eq_i(r, 0);
+ 	/* if no error or padding error, do not return here to prevent Marvin attack */
+ 	if (!(good | wrong_padding) && r < 0)   {
+ 		logprintf(pCardData, 2, "sc_pkcs15_decipher error(%i): %s\n", r, sc_strerror(r));
+diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c
+index 8376057ea..8b0a63b10 100644
+--- a/src/pkcs11/framework-pkcs15.c
++++ b/src/pkcs11/framework-pkcs15.c
+@@ -4433,11 +4433,11 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *session, void *obj,
+ 
+ 	/* only padding error must be handled in constant-time way,
+ 	 * other error can be returned straight away */
+-	if ((~constant_time_eq_s(rv, SC_ERROR_WRONG_PADDING) & constant_time_lt_s(sizeof(decrypted), rv)))
++	if ((~constant_time_eq_i(rv, SC_ERROR_WRONG_PADDING) & constant_time_lt_s(sizeof(decrypted), (size_t)rv)))
+ 		return sc_to_cryptoki_error(rv, "C_Decrypt");
+ 
+ 	/* check rv for padding error */
+-	good = ~constant_time_eq_s(rv, SC_ERROR_WRONG_PADDING);
++	good = ~constant_time_eq_i(rv, SC_ERROR_WRONG_PADDING);
+ 	rv_pkcs11 = sc_to_cryptoki_error(SC_ERROR_WRONG_PADDING, "C_Decrypt");
+ 	rv_pkcs11 = constant_time_select_s(good, CKR_OK, rv_pkcs11);
+ 
+-- 
+2.50.0
+
diff --git a/meta-oe/recipes-support/opensc/opensc_0.22.0.bb b/meta-oe/recipes-support/opensc/opensc_0.22.0.bb
index 52e29a5d92..30a9ae5468 100644
--- a/meta-oe/recipes-support/opensc/opensc_0.22.0.bb
+++ b/meta-oe/recipes-support/opensc/opensc_0.22.0.bb
@@ -55,6 +55,16 @@  SRC_URI = "git://github.com/OpenSC/OpenSC;branch=master;protocol=https \
            file://CVE-2024-45620-0001.patch \
            file://CVE-2024-45620-0002.patch \
            file://CVE-2024-45620-0003.patch \
+           file://CVE-2023-5992-0001.patch \
+           file://CVE-2023-5992-0002.patch \
+           file://CVE-2023-5992-0003.patch \
+           file://CVE-2023-5992-0004.patch \
+           file://CVE-2023-5992-0005.patch \
+           file://CVE-2023-5992-0006.patch \
+           file://CVE-2023-5992-0007.patch \
+           file://CVE-2023-5992-0008.patch \
+           file://CVE-2023-5992-0009.patch \
+           file://CVE-2023-5992-0010.patch \
           "
 
 # CVE-2021-34193 is a duplicate CVE covering the 5 individual