Zhang Peng 4cbf9d8d2c opensc: fix CVE-2023-5992
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>
Signed-off-by: Gyorgy Sarvari <skandigraun@gmail.com>
2025-11-02 15:09:01 +01:00

270 lines
8.3 KiB
Diff

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