Skip to content

Commit 03af18e

Browse files
committed
CVE fixes 01.07.26
1 parent 966c7f2 commit 03af18e

19 files changed

Lines changed: 2297 additions & 1 deletion

prepare_source

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
git_src -b debian/openssl-3.5.5-1 https://salsa.debian.org/debian/openssl.git
22
import_upstream_patches
33

4-
version_suffix="gl50"
4+
version_suffix="gl51"
55
fips_version_suffix="${version_suffix}"
66
sed "s/SED_MARKER_FOR_FIPS_VERSION/$fips_version_suffix/" <patches-debian/rules.patch.tpl > patches-debian/rules.patch
77
apply_patches patches-debian
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
From: Pranavjeet-Naidu <pranavjeetnaidu@gmail.com>
2+
Date: Wed, 25 Mar 2026 05:15:30 +0530
3+
Subject: Add negative length validation in EVP_EncryptUpdate and
4+
EVP_DecryptUpdate
5+
6+
Added input length validation checks to prevent potential security issues
7+
when negative values are passed to EVP_EncryptUpdate and EVP_DecryptUpdate.
8+
These functions cast inl (int) to size_t without validation, which could lead
9+
to unexpectedly large buffer allocation attempts or unintended behavior with
10+
negative inputs.
11+
12+
Validation is performed early in both functions to ensure only valid,
13+
non-negative lengths are processed. Error is reported via EVP_R_INVALID_LENGTH.
14+
15+
Fixes: https://github.com/openssl/openssl/issues/30486
16+
17+
Reviewed-by: Paul Dale <paul.dale@oracle.com>
18+
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
19+
Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org>
20+
MergeDate: Tue Mar 31 02:10:52 2026
21+
(Merged from https://github.com/openssl/openssl/pull/30560)
22+
23+
(cherry picked from commit d29c165122bd480ca736a3eeb21d88a6b433ead3)
24+
---
25+
crypto/evp/evp_enc.c | 10 ++++++++++
26+
test/evp_extra_test.c | 41 +++++++++++++++++++++++++++++++++++++++++
27+
2 files changed, 51 insertions(+)
28+
29+
diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c
30+
index 5584e06d7e..97ea6fd153 100644
31+
--- a/crypto/evp/evp_enc.c
32+
+++ b/crypto/evp/evp_enc.c
33+
@@ -979,6 +979,11 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
34+
size_t soutl, inl_ = (size_t)inl;
35+
int blocksize;
36+
37+
+ if (inl < 0) {
38+
+ ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_LENGTH);
39+
+ return 0;
40+
+ }
41+
+
42+
if (ossl_likely(outl != NULL)) {
43+
*outl = 0;
44+
} else {
45+
@@ -1128,6 +1133,11 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
46+
size_t soutl, inl_ = (size_t)inl;
47+
int blocksize;
48+
49+
+ if (inl < 0) {
50+
+ ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_LENGTH);
51+
+ return 0;
52+
+ }
53+
+
54+
if (ossl_likely(outl != NULL)) {
55+
*outl = 0;
56+
} else {
57+
diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c
58+
index d45f497f03..573732bfec 100644
59+
--- a/test/evp_extra_test.c
60+
+++ b/test/evp_extra_test.c
61+
@@ -6547,6 +6547,45 @@ static int test_invalid_ctx_for_digest(void)
62+
return ret;
63+
}
64+
65+
+static int test_evp_cipher_negative_length(void)
66+
+{
67+
+ EVP_CIPHER_CTX *ctx = NULL;
68+
+ EVP_CIPHER *cipher = NULL;
69+
+ unsigned char key[16] = { 0 };
70+
+ unsigned char iv[16] = { 0 };
71+
+ unsigned char buffer[32] = { 0 };
72+
+ int outl = 0;
73+
+ int ret = 0;
74+
+
75+
+ if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new()))
76+
+ goto end;
77+
+
78+
+ if (!TEST_ptr(cipher = EVP_CIPHER_fetch(testctx, "AES-128-CBC", testpropq)))
79+
+ goto end;
80+
+
81+
+ /* Initialize encryption context */
82+
+ if (!TEST_int_eq(EVP_EncryptInit_ex2(ctx, cipher, key, iv, NULL), 1))
83+
+ goto end;
84+
+
85+
+ /* Test EVP_EncryptUpdate with negative length - should fail */
86+
+ if (!TEST_int_eq(EVP_EncryptUpdate(ctx, buffer, &outl, (unsigned char *)"test", -1), 0))
87+
+ goto end;
88+
+
89+
+ /* Reinitialize for decryption */
90+
+ if (!TEST_int_eq(EVP_DecryptInit_ex2(ctx, cipher, key, iv, NULL), 1))
91+
+ goto end;
92+
+
93+
+ /* Test EVP_DecryptUpdate with negative length - should fail */
94+
+ if (!TEST_int_eq(EVP_DecryptUpdate(ctx, buffer, &outl, (unsigned char *)"test", -1), 0))
95+
+ goto end;
96+
+
97+
+ ret = 1;
98+
+end:
99+
+ EVP_CIPHER_free(cipher);
100+
+ EVP_CIPHER_CTX_free(ctx);
101+
+ return ret;
102+
+}
103+
+
104+
static int test_evp_cipher_pipeline(void)
105+
{
106+
OSSL_PROVIDER *fake_pipeline = NULL;
107+
@@ -6950,6 +6989,8 @@ int setup_tests(void)
108+
109+
ADD_TEST(test_invalid_ctx_for_digest);
110+
111+
+ ADD_TEST(test_evp_cipher_negative_length);
112+
+
113+
ADD_TEST(test_evp_cipher_pipeline);
114+
115+
return 1;
116+
--
117+
2.53.0
118+
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
From: Viktor Dukhovni <openssl-users@dukhovni.org>
2+
Date: Tue, 7 Apr 2026 22:40:55 +1000
3+
Subject: Avoid length truncation in ASN1_STRING_set
4+
5+
The ASN1_STRING_set() function takes an `int` length, make sure the
6+
argument is not inadvertently truncated when it is called from
7+
asn1_ex_c2i().
8+
9+
Fixes CVE-2026-34180
10+
11+
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
12+
Reviewed-by: Norbert Pocs <norbertp@openssl.org>
13+
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
14+
MergeDate: Mon Jun 8 14:13:56 2026
15+
(cherry picked from commit 5f525cace61a53311ee533374919356c700847d9)
16+
---
17+
crypto/asn1/tasn_dec.c | 24 +++++++++++++++++-------
18+
1 file changed, 17 insertions(+), 7 deletions(-)
19+
20+
diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c
21+
index 91c2e524f55b9..e9532b9f48f74 100644
22+
--- a/crypto/asn1/tasn_dec.c
23+
+++ b/crypto/asn1/tasn_dec.c
24+
@@ -54,7 +54,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
25+
const ASN1_ITEM *it,
26+
int tag, int aclass, char opt,
27+
ASN1_TLC *ctx);
28+
-static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
29+
+static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, long len,
30+
int utype, char *free_cont, const ASN1_ITEM *it);
31+
32+
/* Table to convert tags to bit values, used for MSTRING type */
33+
@@ -855,19 +855,24 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
34+
35+
/* Translate ASN1 content octets into a structure */
36+
37+
-static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
38+
+static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, long len,
39+
int utype, char *free_cont, const ASN1_ITEM *it)
40+
{
41+
ASN1_VALUE **opval = NULL;
42+
ASN1_STRING *stmp;
43+
ASN1_TYPE *typ = NULL;
44+
int ret = 0;
45+
+ int ilen = (int)len;
46+
const ASN1_PRIMITIVE_FUNCS *pf;
47+
ASN1_INTEGER **tint;
48+
pf = it->funcs;
49+
50+
- if (pf && pf->prim_c2i)
51+
- return pf->prim_c2i(pval, cont, len, utype, free_cont, it);
52+
+ if (pf && pf->prim_c2i) {
53+
+ if (len == (long)ilen)
54+
+ return pf->prim_c2i(pval, cont, ilen, utype, free_cont, it);
55+
+ ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LONG);
56+
+ return 0;
57+
+ }
58+
/* If ANY type clear type and set pointer to internal value */
59+
if (it->utype == V_ASN1_ANY) {
60+
if (*pval == NULL) {
61+
@@ -885,7 +890,8 @@ static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
62+
}
63+
switch (utype) {
64+
case V_ASN1_OBJECT:
65+
- if (!ossl_c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len))
66+
+ if (len != (long)ilen
67+
+ || !ossl_c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, ilen))
68+
goto err;
69+
break;
70+
71+
@@ -940,6 +946,10 @@ static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
72+
case V_ASN1_SET:
73+
case V_ASN1_SEQUENCE:
74+
default:
75+
+ if (len != (long)ilen) {
76+
+ ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LONG);
77+
+ goto err;
78+
+ }
79+
if (utype == V_ASN1_BMPSTRING && (len & 1)) {
80+
ERR_raise(ERR_LIB_ASN1, ASN1_R_BMPSTRING_IS_WRONG_LENGTH);
81+
goto err;
82+
@@ -970,10 +980,10 @@ static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
83+
}
84+
/* If we've already allocated a buffer use it */
85+
if (*free_cont) {
86+
- ASN1_STRING_set0(stmp, (unsigned char *)cont /* UGLY CAST! */, len);
87+
+ ASN1_STRING_set0(stmp, (unsigned char *)cont /* UGLY CAST! */, ilen);
88+
*free_cont = 0;
89+
} else {
90+
- if (!ASN1_STRING_set(stmp, cont, len)) {
91+
+ if (!ASN1_STRING_set(stmp, cont, ilen)) {
92+
ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
93+
ASN1_STRING_free(stmp);
94+
*pval = NULL;
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
From: Alicja Kario <hkario@redhat.com>
2+
Date: Wed, 29 Apr 2026 16:29:35 +0200
3+
Subject: pkcs12: verify that the pbmac1 key length is safe
4+
5+
Short mac keys (as short as 1 byte) can be used to probe the
6+
system under attack to accept a PKCS#12 file created by an attacker
7+
even if the attacker doesn't know the password used for MAC protection.
8+
9+
Fixes CVE-2026-34181
10+
11+
(also update the reference to the PBMAC1 PKCS#12 RFC)
12+
13+
Signed-off-by: Alicja Kario <hkario@redhat.com>
14+
---
15+
crypto/pkcs12/p12_mutl.c | 8 +++++---
16+
test/recipes/80-test_pkcs12.t | 13 ++++++++-----
17+
2 files changed, 13 insertions(+), 8 deletions(-)
18+
19+
diff --git a/crypto/pkcs12/p12_mutl.c b/crypto/pkcs12/p12_mutl.c
20+
index 01956252df76..15072e12f26b 100644
21+
--- a/crypto/pkcs12/p12_mutl.c
22+
+++ b/crypto/pkcs12/p12_mutl.c
23+
@@ -144,11 +144,13 @@ static int PBMAC1_PBKDF2_HMAC(OSSL_LIB_CTX *ctx, const char *propq,
24+
}
25+
pbkdf2_salt = pbkdf2_param->salt->value.octet_string;
26+
27+
- /* RFC 9579 specifies missing key length as invalid */
28+
+ /* RFC 9879 specifies missing key length as invalid */
29+
if (pbkdf2_param->keylength != NULL)
30+
keylen = ASN1_INTEGER_get(pbkdf2_param->keylength);
31+
- if (keylen <= 0 || keylen > EVP_MAX_MD_SIZE) {
32+
- ERR_raise(ERR_LIB_PKCS12, PKCS12_R_PARSE_ERROR);
33+
+ /* RFC 9879 specifies too short key length as untrustworthy too */
34+
+ if (keylen < 20 || keylen > EVP_MAX_MD_SIZE) {
35+
+ ERR_raise_data(ERR_LIB_PKCS12, PKCS12_R_PARSE_ERROR,
36+
+ "Invalid Key length (%d is not in the range 20..64)", keylen);
37+
goto err;
38+
}
39+
40+
diff --git a/test/recipes/80-test_pkcs12.t b/test/recipes/80-test_pkcs12.t
41+
index d258b7eb0e47..56ab93803e7a 100644
42+
--- a/test/recipes/80-test_pkcs12.t
43+
+++ b/test/recipes/80-test_pkcs12.t
44+
@@ -56,7 +56,7 @@ $ENV{OPENSSL_WIN32_UTF8}=1;
45+
46+
my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
47+
48+
-plan tests => $no_fips ? 53 : 59;
49+
+plan tests => $no_fips ? 55 : 61;
50+
51+
# Test different PKCS#12 formats
52+
ok(run(test(["pkcs12_format_test"])), "test pkcs12 formats");
53+
@@ -205,8 +205,11 @@ for my $instance (sort keys %pbmac1_tests) {
54+
}
55+
}
56+
57+
-# Test pbmac1 pkcs12 good files, RFC 9579
58+
-for my $file ("pbmac1_256_256.good.p12", "pbmac1_512_256.good.p12", "pbmac1_512_512.good.p12")
59+
+# Test pbmac1 pkcs12 good files, RFC 9579, and one extra with shorter key
60+
+# length
61+
+for my $file ("pbmac1_256_256.good.p12", "pbmac1_512_256.good.p12",
62+
+ "pbmac1_512_512.good.p12",
63+
+ "pbmac1_256_256.good-shorter-key-len.p12")
64+
{
65+
my $path = srctop_file("test", "recipes", "80-test_pkcs12_data", $file);
66+
ok(run(app(["openssl", "pkcs12", "-in", $path, "-password", "pass:1234", "-noenc"])),
67+
@@ -235,12 +238,12 @@ unless ($no_fips) {
68+
}
69+
}
70+
71+
-# Test pbmac1 pkcs12 bad files, RFC 9579 and CVE-2025-11187
72+
+# Test pbmac1 pkcs12 bad files, RFC 9579, CVE-2025-11187 and CVE-2026-34181
73+
for my $file ("pbmac1_256_256.bad-iter.p12", "pbmac1_256_256.bad-salt.p12",
74+
"pbmac1_256_256.no-len.p12", "pbmac1_256_256.bad-len.p12",
75+
"pbmac1_256_256.bad-salt-type.p12", "pbmac1_256_256.negative-len.p12",
76+
"pbmac1_256_256.no-salt.p12", "pbmac1_256_256.very-big-len.p12",
77+
- "pbmac1_256_256.zero-len.p12")
78+
+ "pbmac1_256_256.zero-len.p12", "pbmac1_256_256.bad-key-len.p12")
79+
{
80+
my $path = srctop_file("test", "recipes", "80-test_pkcs12_data", $file);
81+
with({ exit_checker => sub { return shift == 1; } },
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
From: Neil Horman <nhorman@openssl.org>
2+
Date: Fri, 17 Apr 2026 13:21:50 -0400
3+
Subject: Reject potentially forged encrypted CMS AuthEnvelopedData messages
4+
5+
1. Adjust ossl_cms_EncryptedContent_init_bio to not accept non-AEAD
6+
ciphers.
7+
8+
If a forged CMS message with AuthEnvelopedData is received with
9+
a non-AEAD cipher specified, we silently accept that and decrypt
10+
the message, skipping any authentication, which violates RFC 5083.
11+
12+
We also add checks to ensure we fail if we try to encrypt
13+
AuthEnvelopedData without using an AEAD cipher.
14+
15+
2. Ensure that tag lengths on cms AEAD data is the recommended size.
16+
17+
RFC 5084 recommends that mac tags be at least 12 bytes for AES-GCM
18+
and 4 bytes for AES-CCM on AuthEnvelopedData. As this code is not
19+
algorith-specific we add a check for a minimal size and just use the
20+
lower limit which is sufficient to prevent this attack.
21+
22+
Without this check, its possible to set the tag length to 1 and within
23+
256 guesses, forge a CMS message.
24+
25+
Fixes CVE-2026-34182
26+
---
27+
diff --git a/crypto/cms/cms_enc.c b/crypto/cms/cms_enc.c
28+
index 08afb5ab11..ba7082cebd 100644
29+
--- a/crypto/cms/cms_enc.c
30+
+++ b/crypto/cms/cms_enc.c
31+
@@ -109,13 +109,15 @@ BIO *ossl_cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec,
32+
goto err;
33+
}
34+
piv = aparams.iv;
35+
- if (ec->taglen > 0
36+
- && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
37+
- ec->taglen, ec->tag)
38+
- <= 0) {
39+
+
40+
+ if (ec->taglen < 4 || ec->taglen > 16
41+
+ || EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, (int)ec->taglen, ec->tag) <= 0) {
42+
ERR_raise(ERR_LIB_CMS, CMS_R_CIPHER_AEAD_SET_TAG_ERROR);
43+
goto err;
44+
}
45+
+ } else if (auth) {
46+
+ ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM);
47+
+ goto err;
48+
}
49+
}
50+
len = EVP_CIPHER_CTX_get_key_length(ctx);

0 commit comments

Comments
 (0)