Compare commits
No commits in common. "c8" and "imports/c8/openssl-1.1.1k-6.el8_5" have entirely different histories.
c8
...
imports/c8
@ -1,13 +1,11 @@
|
||||
diff -up openssl-1.1.1k/ssl/statem/extensions.c.cleanup-reneg openssl-1.1.1k/ssl/statem/extensions.c
|
||||
--- openssl-1.1.1k/ssl/statem/extensions.c.cleanup-reneg 2021-03-25 14:28:38.000000000 +0100
|
||||
+++ openssl-1.1.1k/ssl/statem/extensions.c 2021-06-24 16:16:19.526181743 +0200
|
||||
@@ -42,6 +42,9 @@ static int tls_parse_certificate_authori
|
||||
@@ -42,6 +42,7 @@ static int tls_parse_certificate_authori
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
static int init_srp(SSL *s, unsigned int context);
|
||||
#endif
|
||||
+#ifndef OPENSSL_NO_EC
|
||||
+static int init_ec_point_formats(SSL *s, unsigned int context);
|
||||
+#endif
|
||||
static int init_etm(SSL *s, unsigned int context);
|
||||
static int init_ems(SSL *s, unsigned int context);
|
||||
static int final_ems(SSL *s, unsigned int context, int sent);
|
||||
@ -20,11 +18,10 @@ diff -up openssl-1.1.1k/ssl/statem/extensions.c.cleanup-reneg openssl-1.1.1k/ssl
|
||||
tls_construct_stoc_ec_pt_formats, tls_construct_ctos_ec_pt_formats,
|
||||
final_ec_pt_formats
|
||||
},
|
||||
@@ -1164,6 +1165,17 @@ static int init_srp(SSL *s, unsigned int
|
||||
@@ -1164,6 +1165,15 @@ static int init_srp(SSL *s, unsigned int
|
||||
}
|
||||
#endif
|
||||
|
||||
+#ifndef OPENSSL_NO_EC
|
||||
+static int init_ec_point_formats(SSL *s, unsigned int context)
|
||||
+{
|
||||
+ OPENSSL_free(s->ext.peer_ecpointformats);
|
||||
@ -33,7 +30,6 @@ diff -up openssl-1.1.1k/ssl/statem/extensions.c.cleanup-reneg openssl-1.1.1k/ssl
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
static int init_etm(SSL *s, unsigned int context)
|
||||
{
|
||||
|
@ -1,74 +0,0 @@
|
||||
From e5fd1728ef4c7a5bf7c7a7163ca60370460a6e23 Mon Sep 17 00:00:00 2001
|
||||
From: Tomas Mraz <tomas@openssl.org>
|
||||
Date: Tue, 26 Apr 2022 12:40:24 +0200
|
||||
Subject: [PATCH] c_rehash: Do not use shell to invoke openssl
|
||||
|
||||
Except on VMS where it is safe.
|
||||
|
||||
This fixes CVE-2022-1292.
|
||||
|
||||
Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>
|
||||
Reviewed-by: Matt Caswell <matt@openssl.org>
|
||||
Upstream-Status: Backport [https://github.com/openssl/openssl/commit/e5fd1728ef4c7a5bf7c7a7163ca60370460a6e23]
|
||||
---
|
||||
tools/c_rehash.in | 29 +++++++++++++++++++++++++----
|
||||
1 file changed, 25 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/tools/c_rehash.in b/tools/c_rehash.in
|
||||
index fa7c6c9fef91..83c1cc80e08a 100644
|
||||
--- a/tools/c_rehash.in
|
||||
+++ b/tools/c_rehash.in
|
||||
@@ -152,6 +152,23 @@ sub check_file {
|
||||
return ($is_cert, $is_crl);
|
||||
}
|
||||
|
||||
+sub compute_hash {
|
||||
+ my $fh;
|
||||
+ if ( $^O eq "VMS" ) {
|
||||
+ # VMS uses the open through shell
|
||||
+ # The file names are safe there and list form is unsupported
|
||||
+ if (!open($fh, "-|", join(' ', @_))) {
|
||||
+ print STDERR "Cannot compute hash on '$fname'\n";
|
||||
+ return;
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (!open($fh, "-|", @_)) {
|
||||
+ print STDERR "Cannot compute hash on '$fname'\n";
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ return (<$fh>, <$fh>);
|
||||
+}
|
||||
|
||||
# Link a certificate to its subject name hash value, each hash is of
|
||||
# the form <hash>.<n> where n is an integer. If the hash value already exists
|
||||
@@ -161,10 +178,12 @@ sub check_file {
|
||||
|
||||
sub link_hash_cert {
|
||||
my $fname = $_[0];
|
||||
- $fname =~ s/\"/\\\"/g;
|
||||
- my ($hash, $fprint) = `"$openssl" x509 $x509hash -fingerprint -noout -in "$fname"`;
|
||||
+ my ($hash, $fprint) = compute_hash($openssl, "x509", $x509hash,
|
||||
+ "-fingerprint", "-noout",
|
||||
+ "-in", $fname);
|
||||
chomp $hash;
|
||||
chomp $fprint;
|
||||
+ return if !$hash;
|
||||
$fprint =~ s/^.*=//;
|
||||
$fprint =~ tr/://d;
|
||||
my $suffix = 0;
|
||||
@@ -202,10 +221,12 @@ sub link_hash_cert {
|
||||
|
||||
sub link_hash_crl {
|
||||
my $fname = $_[0];
|
||||
- $fname =~ s/'/'\\''/g;
|
||||
- my ($hash, $fprint) = `"$openssl" crl $crlhash -fingerprint -noout -in '$fname'`;
|
||||
+ my ($hash, $fprint) = compute_hash($openssl, "crl", $crlhash,
|
||||
+ "-fingerprint", "-noout",
|
||||
+ "-in", $fname);
|
||||
chomp $hash;
|
||||
chomp $fprint;
|
||||
+ return if !$hash;
|
||||
$fprint =~ s/^.*=//;
|
||||
$fprint =~ tr/://d;
|
||||
my $suffix = 0;
|
@ -1,255 +0,0 @@
|
||||
From 9639817dac8bbbaa64d09efad7464ccc405527c7 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Fiala <daniel@openssl.org>
|
||||
Date: Sun, 29 May 2022 20:11:24 +0200
|
||||
Subject: [PATCH] Fix file operations in c_rehash.
|
||||
|
||||
CVE-2022-2068
|
||||
|
||||
Reviewed-by: Matt Caswell <matt@openssl.org>
|
||||
Reviewed-by: Richard Levitte <levitte@openssl.org>
|
||||
Upstream-Status: Backport [https://github.com/openssl/openssl/commit/9639817dac8bbbaa64d09efad7464ccc405527c7]
|
||||
---
|
||||
tools/c_rehash.in | 216 +++++++++++++++++++++++-----------------------
|
||||
1 file changed, 107 insertions(+), 109 deletions(-)
|
||||
|
||||
diff --git a/tools/c_rehash.in b/tools/c_rehash.in
|
||||
index cfd18f5da110..9d2a6f6db73b 100644
|
||||
--- a/tools/c_rehash.in
|
||||
+++ b/tools/c_rehash.in
|
||||
@@ -104,52 +104,78 @@ foreach (@dirlist) {
|
||||
}
|
||||
exit($errorcount);
|
||||
|
||||
+sub copy_file {
|
||||
+ my ($src_fname, $dst_fname) = @_;
|
||||
+
|
||||
+ if (open(my $in, "<", $src_fname)) {
|
||||
+ if (open(my $out, ">", $dst_fname)) {
|
||||
+ print $out $_ while (<$in>);
|
||||
+ close $out;
|
||||
+ } else {
|
||||
+ warn "Cannot open $dst_fname for write, $!";
|
||||
+ }
|
||||
+ close $in;
|
||||
+ } else {
|
||||
+ warn "Cannot open $src_fname for read, $!";
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
sub hash_dir {
|
||||
- my %hashlist;
|
||||
- print "Doing $_[0]\n";
|
||||
- chdir $_[0];
|
||||
- opendir(DIR, ".");
|
||||
- my @flist = sort readdir(DIR);
|
||||
- closedir DIR;
|
||||
- if ( $removelinks ) {
|
||||
- # Delete any existing symbolic links
|
||||
- foreach (grep {/^[\da-f]+\.r{0,1}\d+$/} @flist) {
|
||||
- if (-l $_) {
|
||||
- print "unlink $_" if $verbose;
|
||||
- unlink $_ || warn "Can't unlink $_, $!\n";
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- FILE: foreach $fname (grep {/\.(pem)|(crt)|(cer)|(crl)$/} @flist) {
|
||||
- # Check to see if certificates and/or CRLs present.
|
||||
- my ($cert, $crl) = check_file($fname);
|
||||
- if (!$cert && !$crl) {
|
||||
- print STDERR "WARNING: $fname does not contain a certificate or CRL: skipping\n";
|
||||
- next;
|
||||
- }
|
||||
- link_hash_cert($fname) if ($cert);
|
||||
- link_hash_crl($fname) if ($crl);
|
||||
- }
|
||||
+ my $dir = shift;
|
||||
+ my %hashlist;
|
||||
+
|
||||
+ print "Doing $dir\n";
|
||||
+
|
||||
+ if (!chdir $dir) {
|
||||
+ print STDERR "WARNING: Cannot chdir to '$dir', $!\n";
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ opendir(DIR, ".") || print STDERR "WARNING: Cannot opendir '.', $!\n";
|
||||
+ my @flist = sort readdir(DIR);
|
||||
+ closedir DIR;
|
||||
+ if ( $removelinks ) {
|
||||
+ # Delete any existing symbolic links
|
||||
+ foreach (grep {/^[\da-f]+\.r{0,1}\d+$/} @flist) {
|
||||
+ if (-l $_) {
|
||||
+ print "unlink $_\n" if $verbose;
|
||||
+ unlink $_ || warn "Can't unlink $_, $!\n";
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ FILE: foreach $fname (grep {/\.(pem)|(crt)|(cer)|(crl)$/} @flist) {
|
||||
+ # Check to see if certificates and/or CRLs present.
|
||||
+ my ($cert, $crl) = check_file($fname);
|
||||
+ if (!$cert && !$crl) {
|
||||
+ print STDERR "WARNING: $fname does not contain a certificate or CRL: skipping\n";
|
||||
+ next;
|
||||
+ }
|
||||
+ link_hash_cert($fname) if ($cert);
|
||||
+ link_hash_crl($fname) if ($crl);
|
||||
+ }
|
||||
+
|
||||
+ chdir $pwd;
|
||||
}
|
||||
|
||||
sub check_file {
|
||||
- my ($is_cert, $is_crl) = (0,0);
|
||||
- my $fname = $_[0];
|
||||
- open IN, $fname;
|
||||
- while(<IN>) {
|
||||
- if (/^-----BEGIN (.*)-----/) {
|
||||
- my $hdr = $1;
|
||||
- if ($hdr =~ /^(X509 |TRUSTED |)CERTIFICATE$/) {
|
||||
- $is_cert = 1;
|
||||
- last if ($is_crl);
|
||||
- } elsif ($hdr eq "X509 CRL") {
|
||||
- $is_crl = 1;
|
||||
- last if ($is_cert);
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- close IN;
|
||||
- return ($is_cert, $is_crl);
|
||||
+ my ($is_cert, $is_crl) = (0,0);
|
||||
+ my $fname = $_[0];
|
||||
+
|
||||
+ open(my $in, "<", $fname);
|
||||
+ while(<$in>) {
|
||||
+ if (/^-----BEGIN (.*)-----/) {
|
||||
+ my $hdr = $1;
|
||||
+ if ($hdr =~ /^(X509 |TRUSTED |)CERTIFICATE$/) {
|
||||
+ $is_cert = 1;
|
||||
+ last if ($is_crl);
|
||||
+ } elsif ($hdr eq "X509 CRL") {
|
||||
+ $is_crl = 1;
|
||||
+ last if ($is_cert);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ close $in;
|
||||
+ return ($is_cert, $is_crl);
|
||||
}
|
||||
|
||||
sub compute_hash {
|
||||
@@ -177,76 +203,48 @@ sub compute_hash {
|
||||
# certificate fingerprints
|
||||
|
||||
sub link_hash_cert {
|
||||
- my $fname = $_[0];
|
||||
- my ($hash, $fprint) = compute_hash($openssl, "x509", $x509hash,
|
||||
- "-fingerprint", "-noout",
|
||||
- "-in", $fname);
|
||||
- chomp $hash;
|
||||
- chomp $fprint;
|
||||
- return if !$hash;
|
||||
- $fprint =~ s/^.*=//;
|
||||
- $fprint =~ tr/://d;
|
||||
- my $suffix = 0;
|
||||
- # Search for an unused hash filename
|
||||
- while(exists $hashlist{"$hash.$suffix"}) {
|
||||
- # Hash matches: if fingerprint matches its a duplicate cert
|
||||
- if ($hashlist{"$hash.$suffix"} eq $fprint) {
|
||||
- print STDERR "WARNING: Skipping duplicate certificate $fname\n";
|
||||
- return;
|
||||
- }
|
||||
- $suffix++;
|
||||
- }
|
||||
- $hash .= ".$suffix";
|
||||
- if ($symlink_exists) {
|
||||
- print "link $fname -> $hash\n" if $verbose;
|
||||
- symlink $fname, $hash || warn "Can't symlink, $!";
|
||||
- } else {
|
||||
- print "copy $fname -> $hash\n" if $verbose;
|
||||
- if (open($in, "<", $fname)) {
|
||||
- if (open($out,">", $hash)) {
|
||||
- print $out $_ while (<$in>);
|
||||
- close $out;
|
||||
- } else {
|
||||
- warn "can't open $hash for write, $!";
|
||||
- }
|
||||
- close $in;
|
||||
- } else {
|
||||
- warn "can't open $fname for read, $!";
|
||||
- }
|
||||
- }
|
||||
- $hashlist{$hash} = $fprint;
|
||||
+ link_hash($_[0], 'cert');
|
||||
}
|
||||
|
||||
# Same as above except for a CRL. CRL links are of the form <hash>.r<n>
|
||||
|
||||
sub link_hash_crl {
|
||||
- my $fname = $_[0];
|
||||
- my ($hash, $fprint) = compute_hash($openssl, "crl", $crlhash,
|
||||
- "-fingerprint", "-noout",
|
||||
- "-in", $fname);
|
||||
- chomp $hash;
|
||||
- chomp $fprint;
|
||||
- return if !$hash;
|
||||
- $fprint =~ s/^.*=//;
|
||||
- $fprint =~ tr/://d;
|
||||
- my $suffix = 0;
|
||||
- # Search for an unused hash filename
|
||||
- while(exists $hashlist{"$hash.r$suffix"}) {
|
||||
- # Hash matches: if fingerprint matches its a duplicate cert
|
||||
- if ($hashlist{"$hash.r$suffix"} eq $fprint) {
|
||||
- print STDERR "WARNING: Skipping duplicate CRL $fname\n";
|
||||
- return;
|
||||
- }
|
||||
- $suffix++;
|
||||
- }
|
||||
- $hash .= ".r$suffix";
|
||||
- if ($symlink_exists) {
|
||||
- print "link $fname -> $hash\n" if $verbose;
|
||||
- symlink $fname, $hash || warn "Can't symlink, $!";
|
||||
- } else {
|
||||
- print "cp $fname -> $hash\n" if $verbose;
|
||||
- system ("cp", $fname, $hash);
|
||||
- warn "Can't copy, $!" if ($? >> 8) != 0;
|
||||
- }
|
||||
- $hashlist{$hash} = $fprint;
|
||||
+ link_hash($_[0], 'crl');
|
||||
+}
|
||||
+
|
||||
+sub link_hash {
|
||||
+ my ($fname, $type) = @_;
|
||||
+ my $is_cert = $type eq 'cert';
|
||||
+
|
||||
+ my ($hash, $fprint) = compute_hash($openssl,
|
||||
+ $is_cert ? "x509" : "crl",
|
||||
+ $is_cert ? $x509hash : $crlhash,
|
||||
+ "-fingerprint", "-noout",
|
||||
+ "-in", $fname);
|
||||
+ chomp $hash;
|
||||
+ chomp $fprint;
|
||||
+ return if !$hash;
|
||||
+ $fprint =~ s/^.*=//;
|
||||
+ $fprint =~ tr/://d;
|
||||
+ my $suffix = 0;
|
||||
+ # Search for an unused hash filename
|
||||
+ my $crlmark = $is_cert ? "" : "r";
|
||||
+ while(exists $hashlist{"$hash.$crlmark$suffix"}) {
|
||||
+ # Hash matches: if fingerprint matches its a duplicate cert
|
||||
+ if ($hashlist{"$hash.$crlmark$suffix"} eq $fprint) {
|
||||
+ my $what = $is_cert ? 'certificate' : 'CRL';
|
||||
+ print STDERR "WARNING: Skipping duplicate $what $fname\n";
|
||||
+ return;
|
||||
+ }
|
||||
+ $suffix++;
|
||||
+ }
|
||||
+ $hash .= ".$crlmark$suffix";
|
||||
+ if ($symlink_exists) {
|
||||
+ print "link $fname -> $hash\n" if $verbose;
|
||||
+ symlink $fname, $hash || warn "Can't symlink, $!";
|
||||
+ } else {
|
||||
+ print "copy $fname -> $hash\n" if $verbose;
|
||||
+ copy_file($fname, $hash);
|
||||
+ }
|
||||
+ $hashlist{$hash} = $fprint;
|
||||
}
|
@ -1,152 +0,0 @@
|
||||
From 919925673d6c9cfed3c1085497f5dfbbed5fc431 Mon Sep 17 00:00:00 2001
|
||||
From: Alex Chernyakhovsky <achernya@google.com>
|
||||
Date: Thu, 16 Jun 2022 12:00:22 +1000
|
||||
Subject: [PATCH] Fix AES OCB encrypt/decrypt for x86 AES-NI
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
aesni_ocb_encrypt and aesni_ocb_decrypt operate by having a fast-path
|
||||
that performs operations on 6 16-byte blocks concurrently (the
|
||||
"grandloop") and then proceeds to handle the "short" tail (which can
|
||||
be anywhere from 0 to 5 blocks) that remain.
|
||||
|
||||
As part of initialization, the assembly initializes $len to the true
|
||||
length, less 96 bytes and converts it to a pointer so that the $inp
|
||||
can be compared to it. Each iteration of "grandloop" checks to see if
|
||||
there's a full 96-byte chunk to process, and if so, continues. Once
|
||||
this has been exhausted, it falls through to "short", which handles
|
||||
the remaining zero to five blocks.
|
||||
|
||||
Unfortunately, the jump at the end of "grandloop" had a fencepost
|
||||
error, doing a `jb` ("jump below") rather than `jbe` (jump below or
|
||||
equal). This should be `jbe`, as $inp is pointing to the *end* of the
|
||||
chunk currently being handled. If $inp == $len, that means that
|
||||
there's a whole 96-byte chunk waiting to be handled. If $inp > $len,
|
||||
then there's 5 or fewer 16-byte blocks left to be handled, and the
|
||||
fall-through is intended.
|
||||
|
||||
The net effect of `jb` instead of `jbe` is that the last 16-byte block
|
||||
of the last 96-byte chunk was completely omitted. The contents of
|
||||
`out` in this position were never written to. Additionally, since
|
||||
those bytes were never processed, the authentication tag generated is
|
||||
also incorrect.
|
||||
|
||||
The same fencepost error, and identical logic, exists in both
|
||||
aesni_ocb_encrypt and aesni_ocb_decrypt.
|
||||
|
||||
This addresses CVE-2022-2097.
|
||||
|
||||
Co-authored-by: Alejandro Sedeño <asedeno@google.com>
|
||||
Co-authored-by: David Benjamin <davidben@google.com>
|
||||
|
||||
Reviewed-by: Paul Dale <pauli@openssl.org>
|
||||
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
||||
Upstream-Status: Backport [https://github.com/openssl/openssl/commit/919925673d6c9cfed3c1085497f5dfbbed5fc431]
|
||||
---
|
||||
crypto/aes/asm/aesni-x86.pl | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/crypto/aes/asm/aesni-x86.pl b/crypto/aes/asm/aesni-x86.pl
|
||||
index fe2b26542ab6..812758e02e04 100644
|
||||
--- a/crypto/aes/asm/aesni-x86.pl
|
||||
+++ b/crypto/aes/asm/aesni-x86.pl
|
||||
@@ -2027,7 +2027,7 @@ sub aesni_generate6
|
||||
&movdqu (&QWP(-16*2,$out,$inp),$inout4);
|
||||
&movdqu (&QWP(-16*1,$out,$inp),$inout5);
|
||||
&cmp ($inp,$len); # done yet?
|
||||
- &jb (&label("grandloop"));
|
||||
+ &jbe (&label("grandloop"));
|
||||
|
||||
&set_label("short");
|
||||
&add ($len,16*6);
|
||||
@@ -2453,7 +2453,7 @@ sub aesni_generate6
|
||||
&pxor ($rndkey1,$inout5);
|
||||
&movdqu (&QWP(-16*1,$out,$inp),$inout5);
|
||||
&cmp ($inp,$len); # done yet?
|
||||
- &jb (&label("grandloop"));
|
||||
+ &jbe (&label("grandloop"));
|
||||
|
||||
&set_label("short");
|
||||
&add ($len,16*6);
|
||||
From 9131afdca30b6d1650af9ea6179569a80ab8cb06 Mon Sep 17 00:00:00 2001
|
||||
From: Alex Chernyakhovsky <achernya@google.com>
|
||||
Date: Thu, 16 Jun 2022 12:02:37 +1000
|
||||
Subject: [PATCH] AES OCB test vectors
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add test vectors for AES OCB for x86 AES-NI multiple of 96 byte issue.
|
||||
|
||||
Co-authored-by: Alejandro Sedeño <asedeno@google.com>
|
||||
Co-authored-by: David Benjamin <davidben@google.com>
|
||||
|
||||
Reviewed-by: Paul Dale <pauli@openssl.org>
|
||||
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
||||
Upstream-Status: Backport [https://github.com/openssl/openssl/commit/9131afdca30b6d1650af9ea6179569a80ab8cb06]
|
||||
---
|
||||
test/recipes/30-test_evp_data/evpciph.txt | 50 +++++++++++++++++++++++
|
||||
1 file changed, 50 insertions(+)
|
||||
|
||||
diff --git a/test/recipes/30-test_evp_data/evpciph.txt b/test/recipes/30-test_evp_data/evpciph.txt
|
||||
index 1c02ea1e9c2d..e12670d9a4b4 100644
|
||||
--- a/test/recipes/30-test_evp_data/evpciph.txt
|
||||
+++ b/test/recipes/30-test_evp_data/evpciph.txt
|
||||
@@ -1188,6 +1188,56 @@ Ciphertext = 09A4FD29DE949D9A9AA9924248422097AD4883B4713E6C214FF6567ADA08A967B21
|
||||
Operation = DECRYPT
|
||||
Result = CIPHERFINAL_ERROR
|
||||
|
||||
+#Test vectors generated to validate aesni_ocb_encrypt on x86
|
||||
+Cipher = aes-128-ocb
|
||||
+Key = 000102030405060708090A0B0C0D0E0F
|
||||
+IV = 000000000001020304050607
|
||||
+Tag = C14DFF7D62A13C4A3422456207453190
|
||||
+Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
|
||||
+Ciphertext = F5186C9CC3506386919B6FD9443956E05B203313F8AB35E916AB36932EBDDCD2945901BABE7CF29404929F322F954C916065FABF8F1E52F4BD7C538C0F96899519DBC6BC504D837D8EBD1436B45D33F528CB642FA2EB2C403FE604C12B819333
|
||||
+
|
||||
+Cipher = aes-128-ocb
|
||||
+Key = 000102030405060708090A0B0C0D0E0F
|
||||
+IV = 000000000001020304050607
|
||||
+Tag = D47D84F6FF912C79B6A4223AB9BE2DB8
|
||||
+Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F
|
||||
+Ciphertext = F5186C9CC3506386919B6FD9443956E05B203313F8AB35E916AB36932EBDDCD2945901BABE7CF29404929F322F954C916065FABF8F1E52F4BD7C538C0F96899519DBC6BC504D837D8EBD1436B45D33F528CB642FA2EB2C403FE604C12B8193332374120A78A1171D23ED9E9CB1ADC204
|
||||
+
|
||||
+Cipher = aes-128-ocb
|
||||
+Key = 000102030405060708090A0B0C0D0E0F
|
||||
+IV = 000000000001020304050607
|
||||
+Tag = 41970D13737B7BD1B5FBF49ED4412CA5
|
||||
+Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071000102030405060708090A0B0C0D
|
||||
+Ciphertext = F5186C9CC3506386919B6FD9443956E05B203313F8AB35E916AB36932EBDDCD2945901BABE7CF29404929F322F954C916065FABF8F1E52F4BD7C538C0F96899519DBC6BC504D837D8EBD1436B45D33F528CB642FA2EB2C403FE604C12B8193332374120A78A1171D23ED9E9CB1ADC20412C017AD0CA498827C768DDD99B26E91
|
||||
+
|
||||
+Cipher = aes-128-ocb
|
||||
+Key = 000102030405060708090A0B0C0D0E0F
|
||||
+IV = 000000000001020304050607
|
||||
+Tag = BE0228651ED4E48A11BDED68D953F3A0
|
||||
+Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D
|
||||
+Ciphertext = F5186C9CC3506386919B6FD9443956E05B203313F8AB35E916AB36932EBDDCD2945901BABE7CF29404929F322F954C916065FABF8F1E52F4BD7C538C0F96899519DBC6BC504D837D8EBD1436B45D33F528CB642FA2EB2C403FE604C12B8193332374120A78A1171D23ED9E9CB1ADC20412C017AD0CA498827C768DDD99B26E91EDB8681700FF30366F07AEDE8CEACC1F
|
||||
+
|
||||
+Cipher = aes-128-ocb
|
||||
+Key = 000102030405060708090A0B0C0D0E0F
|
||||
+IV = 000000000001020304050607
|
||||
+Tag = 17BC6E10B16E5FDC52836E7D589518C7
|
||||
+Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D
|
||||
+Ciphertext = F5186C9CC3506386919B6FD9443956E05B203313F8AB35E916AB36932EBDDCD2945901BABE7CF29404929F322F954C916065FABF8F1E52F4BD7C538C0F96899519DBC6BC504D837D8EBD1436B45D33F528CB642FA2EB2C403FE604C12B8193332374120A78A1171D23ED9E9CB1ADC20412C017AD0CA498827C768DDD99B26E91EDB8681700FF30366F07AEDE8CEACC1F39BE69B91BC808FA7A193F7EEA43137B
|
||||
+
|
||||
+Cipher = aes-128-ocb
|
||||
+Key = 000102030405060708090A0B0C0D0E0F
|
||||
+IV = 000000000001020304050607
|
||||
+Tag = E84AAC18666116990A3A37B3A5FC55BD
|
||||
+Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D
|
||||
+Ciphertext = F5186C9CC3506386919B6FD9443956E05B203313F8AB35E916AB36932EBDDCD2945901BABE7CF29404929F322F954C916065FABF8F1E52F4BD7C538C0F96899519DBC6BC504D837D8EBD1436B45D33F528CB642FA2EB2C403FE604C12B8193332374120A78A1171D23ED9E9CB1ADC20412C017AD0CA498827C768DDD99B26E91EDB8681700FF30366F07AEDE8CEACC1F39BE69B91BC808FA7A193F7EEA43137B11CF99263D693AEBDF8ADE1A1D838DED
|
||||
+
|
||||
+Cipher = aes-128-ocb
|
||||
+Key = 000102030405060708090A0B0C0D0E0F
|
||||
+IV = 000000000001020304050607
|
||||
+Tag = 3E5EA7EE064FE83B313E28D411E91EAD
|
||||
+Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D
|
||||
+Ciphertext = F5186C9CC3506386919B6FD9443956E05B203313F8AB35E916AB36932EBDDCD2945901BABE7CF29404929F322F954C916065FABF8F1E52F4BD7C538C0F96899519DBC6BC504D837D8EBD1436B45D33F528CB642FA2EB2C403FE604C12B8193332374120A78A1171D23ED9E9CB1ADC20412C017AD0CA498827C768DDD99B26E91EDB8681700FF30366F07AEDE8CEACC1F39BE69B91BC808FA7A193F7EEA43137B11CF99263D693AEBDF8ADE1A1D838DED48D9E09F452F8E6FBEB76A3DED47611C
|
||||
+
|
||||
Title = AES XTS test vectors from IEEE Std 1619-2007
|
||||
|
||||
# Using the same key twice for encryption is always banned.
|
@ -1,805 +0,0 @@
|
||||
From 43d8f88511991533f53680a751e9326999a6a31f Mon Sep 17 00:00:00 2001
|
||||
From: Matt Caswell <matt@openssl.org>
|
||||
Date: Fri, 20 Jan 2023 15:26:54 +0000
|
||||
Subject: [PATCH 1/6] Fix Timing Oracle in RSA decryption
|
||||
|
||||
A timing based side channel exists in the OpenSSL RSA Decryption
|
||||
implementation which could be sufficient to recover a plaintext across
|
||||
a network in a Bleichenbacher style attack. To achieve a successful
|
||||
decryption an attacker would have to be able to send a very large number
|
||||
of trial messages for decryption. The vulnerability affects all RSA
|
||||
padding modes: PKCS#1 v1.5, RSA-OEAP and RSASVE.
|
||||
|
||||
Patch written by Dmitry Belyavsky and Hubert Kario
|
||||
|
||||
CVE-2022-4304
|
||||
|
||||
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
||||
---
|
||||
crypto/bn/bn_blind.c | 14 -
|
||||
crypto/bn/bn_err.c | 2 +
|
||||
crypto/bn/bn_local.h | 14 +
|
||||
crypto/bn/build.info | 3 +-
|
||||
crypto/bn/rsa_sup_mul.c | 614 ++++++++++++++++++++++++++++++++++++++++
|
||||
crypto/err/openssl.txt | 3 +-
|
||||
crypto/rsa/rsa_ossl.c | 17 +-
|
||||
include/crypto/bn.h | 5 +
|
||||
include/openssl/bnerr.h | 1 +
|
||||
9 files changed, 653 insertions(+), 20 deletions(-)
|
||||
create mode 100644 crypto/bn/rsa_sup_mul.c
|
||||
|
||||
diff --git a/crypto/bn/bn_blind.c b/crypto/bn/bn_blind.c
|
||||
index 76fc7ebcff..6e9d239321 100644
|
||||
--- a/crypto/bn/bn_blind.c
|
||||
+++ b/crypto/bn/bn_blind.c
|
||||
@@ -13,20 +13,6 @@
|
||||
|
||||
#define BN_BLINDING_COUNTER 32
|
||||
|
||||
-struct bn_blinding_st {
|
||||
- BIGNUM *A;
|
||||
- BIGNUM *Ai;
|
||||
- BIGNUM *e;
|
||||
- BIGNUM *mod; /* just a reference */
|
||||
- CRYPTO_THREAD_ID tid;
|
||||
- int counter;
|
||||
- unsigned long flags;
|
||||
- BN_MONT_CTX *m_ctx;
|
||||
- int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
|
||||
- const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
|
||||
- CRYPTO_RWLOCK *lock;
|
||||
-};
|
||||
-
|
||||
BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod)
|
||||
{
|
||||
BN_BLINDING *ret = NULL;
|
||||
diff --git a/crypto/bn/bn_err.c b/crypto/bn/bn_err.c
|
||||
index dd87c152cf..3dd8d9a568 100644
|
||||
--- a/crypto/bn/bn_err.c
|
||||
+++ b/crypto/bn/bn_err.c
|
||||
@@ -73,6 +73,8 @@ static const ERR_STRING_DATA BN_str_functs[] = {
|
||||
{ERR_PACK(ERR_LIB_BN, BN_F_BN_SET_WORDS, 0), "bn_set_words"},
|
||||
{ERR_PACK(ERR_LIB_BN, BN_F_BN_STACK_PUSH, 0), "BN_STACK_push"},
|
||||
{ERR_PACK(ERR_LIB_BN, BN_F_BN_USUB, 0), "BN_usub"},
|
||||
+ {ERR_PACK(ERR_LIB_BN, BN_F_OSSL_BN_RSA_DO_UNBLIND, 0),
|
||||
+ "ossl_bn_rsa_do_unblind"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
diff --git a/crypto/bn/bn_local.h b/crypto/bn/bn_local.h
|
||||
index 62a969b134..4d8cb64675 100644
|
||||
--- a/crypto/bn/bn_local.h
|
||||
+++ b/crypto/bn/bn_local.h
|
||||
@@ -283,6 +283,20 @@ struct bn_gencb_st {
|
||||
} cb;
|
||||
};
|
||||
|
||||
+struct bn_blinding_st {
|
||||
+ BIGNUM *A;
|
||||
+ BIGNUM *Ai;
|
||||
+ BIGNUM *e;
|
||||
+ BIGNUM *mod; /* just a reference */
|
||||
+ CRYPTO_THREAD_ID tid;
|
||||
+ int counter;
|
||||
+ unsigned long flags;
|
||||
+ BN_MONT_CTX *m_ctx;
|
||||
+ int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
|
||||
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
|
||||
+ CRYPTO_RWLOCK *lock;
|
||||
+};
|
||||
+
|
||||
/*-
|
||||
* BN_window_bits_for_exponent_size -- macro for sliding window mod_exp functions
|
||||
*
|
||||
diff --git a/crypto/bn/build.info b/crypto/bn/build.info
|
||||
index b9ed5322fa..c9fe2fdada 100644
|
||||
--- a/crypto/bn/build.info
|
||||
+++ b/crypto/bn/build.info
|
||||
@@ -5,7 +5,8 @@ SOURCE[../../libcrypto]=\
|
||||
bn_kron.c bn_sqrt.c bn_gcd.c bn_prime.c bn_err.c bn_sqr.c \
|
||||
{- $target{bn_asm_src} -} \
|
||||
bn_recp.c bn_mont.c bn_mpi.c bn_exp2.c bn_gf2m.c bn_nist.c \
|
||||
- bn_depr.c bn_const.c bn_x931p.c bn_intern.c bn_dh.c bn_srp.c
|
||||
+ bn_depr.c bn_const.c bn_x931p.c bn_intern.c bn_dh.c bn_srp.c \
|
||||
+ rsa_sup_mul.c
|
||||
|
||||
INCLUDE[bn_exp.o]=..
|
||||
|
||||
diff --git a/crypto/bn/rsa_sup_mul.c b/crypto/bn/rsa_sup_mul.c
|
||||
new file mode 100644
|
||||
index 0000000000..acafefd5fe
|
||||
--- /dev/null
|
||||
+++ b/crypto/bn/rsa_sup_mul.c
|
||||
@@ -0,0 +1,614 @@
|
||||
+#include <openssl/e_os2.h>
|
||||
+#include <stddef.h>
|
||||
+#include <sys/types.h>
|
||||
+#include <string.h>
|
||||
+#include <openssl/bn.h>
|
||||
+#include <openssl/err.h>
|
||||
+#include <openssl/rsaerr.h>
|
||||
+#include "internal/numbers.h"
|
||||
+#include "internal/constant_time.h"
|
||||
+#include "bn_local.h"
|
||||
+
|
||||
+# if BN_BYTES == 8
|
||||
+typedef uint64_t limb_t;
|
||||
+# if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__ == 16
|
||||
+/* nonstandard; implemented by gcc on 64-bit platforms */
|
||||
+typedef __uint128_t limb2_t;
|
||||
+# define HAVE_LIMB2_T
|
||||
+# endif
|
||||
+# define LIMB_BIT_SIZE 64
|
||||
+# define LIMB_BYTE_SIZE 8
|
||||
+# elif BN_BYTES == 4
|
||||
+typedef uint32_t limb_t;
|
||||
+typedef uint64_t limb2_t;
|
||||
+# define LIMB_BIT_SIZE 32
|
||||
+# define LIMB_BYTE_SIZE 4
|
||||
+# define HAVE_LIMB2_T
|
||||
+# else
|
||||
+# error "Not supported"
|
||||
+# endif
|
||||
+
|
||||
+/*
|
||||
+ * For multiplication we're using schoolbook multiplication,
|
||||
+ * so if we have two numbers, each with 6 "digits" (words)
|
||||
+ * the multiplication is calculated as follows:
|
||||
+ * A B C D E F
|
||||
+ * x I J K L M N
|
||||
+ * --------------
|
||||
+ * N*F
|
||||
+ * N*E
|
||||
+ * N*D
|
||||
+ * N*C
|
||||
+ * N*B
|
||||
+ * N*A
|
||||
+ * M*F
|
||||
+ * M*E
|
||||
+ * M*D
|
||||
+ * M*C
|
||||
+ * M*B
|
||||
+ * M*A
|
||||
+ * L*F
|
||||
+ * L*E
|
||||
+ * L*D
|
||||
+ * L*C
|
||||
+ * L*B
|
||||
+ * L*A
|
||||
+ * K*F
|
||||
+ * K*E
|
||||
+ * K*D
|
||||
+ * K*C
|
||||
+ * K*B
|
||||
+ * K*A
|
||||
+ * J*F
|
||||
+ * J*E
|
||||
+ * J*D
|
||||
+ * J*C
|
||||
+ * J*B
|
||||
+ * J*A
|
||||
+ * I*F
|
||||
+ * I*E
|
||||
+ * I*D
|
||||
+ * I*C
|
||||
+ * I*B
|
||||
+ * + I*A
|
||||
+ * ==========================
|
||||
+ * N*B N*D N*F
|
||||
+ * + N*A N*C N*E
|
||||
+ * + M*B M*D M*F
|
||||
+ * + M*A M*C M*E
|
||||
+ * + L*B L*D L*F
|
||||
+ * + L*A L*C L*E
|
||||
+ * + K*B K*D K*F
|
||||
+ * + K*A K*C K*E
|
||||
+ * + J*B J*D J*F
|
||||
+ * + J*A J*C J*E
|
||||
+ * + I*B I*D I*F
|
||||
+ * + I*A I*C I*E
|
||||
+ *
|
||||
+ * 1+1 1+3 1+5
|
||||
+ * 1+0 1+2 1+4
|
||||
+ * 0+1 0+3 0+5
|
||||
+ * 0+0 0+2 0+4
|
||||
+ *
|
||||
+ * 0 1 2 3 4 5 6
|
||||
+ * which requires n^2 multiplications and 2n full length additions
|
||||
+ * as we can keep every other result of limb multiplication in two separate
|
||||
+ * limbs
|
||||
+ */
|
||||
+
|
||||
+#if defined HAVE_LIMB2_T
|
||||
+static ossl_inline void _mul_limb(limb_t *hi, limb_t *lo, limb_t a, limb_t b)
|
||||
+{
|
||||
+ limb2_t t;
|
||||
+ /*
|
||||
+ * this is idiomatic code to tell compiler to use the native mul
|
||||
+ * those three lines will actually compile to single instruction
|
||||
+ */
|
||||
+
|
||||
+ t = (limb2_t)a * b;
|
||||
+ *hi = t >> LIMB_BIT_SIZE;
|
||||
+ *lo = (limb_t)t;
|
||||
+}
|
||||
+#elif (BN_BYTES == 8) && (defined _MSC_VER)
|
||||
+/* https://learn.microsoft.com/en-us/cpp/intrinsics/umul128?view=msvc-170 */
|
||||
+#pragma intrinsic(_umul128)
|
||||
+static ossl_inline void _mul_limb(limb_t *hi, limb_t *lo, limb_t a, limb_t b)
|
||||
+{
|
||||
+ *lo = _umul128(a, b, hi);
|
||||
+}
|
||||
+#else
|
||||
+/*
|
||||
+ * if the compiler doesn't have either a 128bit data type nor a "return
|
||||
+ * high 64 bits of multiplication"
|
||||
+ */
|
||||
+static ossl_inline void _mul_limb(limb_t *hi, limb_t *lo, limb_t a, limb_t b)
|
||||
+{
|
||||
+ limb_t a_low = (limb_t)(uint32_t)a;
|
||||
+ limb_t a_hi = a >> 32;
|
||||
+ limb_t b_low = (limb_t)(uint32_t)b;
|
||||
+ limb_t b_hi = b >> 32;
|
||||
+
|
||||
+ limb_t p0 = a_low * b_low;
|
||||
+ limb_t p1 = a_low * b_hi;
|
||||
+ limb_t p2 = a_hi * b_low;
|
||||
+ limb_t p3 = a_hi * b_hi;
|
||||
+
|
||||
+ uint32_t cy = (uint32_t)(((p0 >> 32) + (uint32_t)p1 + (uint32_t)p2) >> 32);
|
||||
+
|
||||
+ *lo = p0 + (p1 << 32) + (p2 << 32);
|
||||
+ *hi = p3 + (p1 >> 32) + (p2 >> 32) + cy;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+/* add two limbs with carry in, return carry out */
|
||||
+static ossl_inline limb_t _add_limb(limb_t *ret, limb_t a, limb_t b, limb_t carry)
|
||||
+{
|
||||
+ limb_t carry1, carry2, t;
|
||||
+ /*
|
||||
+ * `c = a + b; if (c < a)` is idiomatic code that makes compilers
|
||||
+ * use add with carry on assembly level
|
||||
+ */
|
||||
+
|
||||
+ *ret = a + carry;
|
||||
+ if (*ret < a)
|
||||
+ carry1 = 1;
|
||||
+ else
|
||||
+ carry1 = 0;
|
||||
+
|
||||
+ t = *ret;
|
||||
+ *ret = t + b;
|
||||
+ if (*ret < t)
|
||||
+ carry2 = 1;
|
||||
+ else
|
||||
+ carry2 = 0;
|
||||
+
|
||||
+ return carry1 + carry2;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * add two numbers of the same size, return overflow
|
||||
+ *
|
||||
+ * add a to b, place result in ret; all arrays need to be n limbs long
|
||||
+ * return overflow from addition (0 or 1)
|
||||
+ */
|
||||
+static ossl_inline limb_t add(limb_t *ret, limb_t *a, limb_t *b, size_t n)
|
||||
+{
|
||||
+ limb_t c = 0;
|
||||
+ ossl_ssize_t i;
|
||||
+
|
||||
+ for(i = n - 1; i > -1; i--)
|
||||
+ c = _add_limb(&ret[i], a[i], b[i], c);
|
||||
+
|
||||
+ return c;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * return number of limbs necessary for temporary values
|
||||
+ * when multiplying numbers n limbs large
|
||||
+ */
|
||||
+static ossl_inline size_t mul_limb_numb(size_t n)
|
||||
+{
|
||||
+ return 2 * n * 2;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * multiply two numbers of the same size
|
||||
+ *
|
||||
+ * multiply a by b, place result in ret; a and b need to be n limbs long
|
||||
+ * ret needs to be 2*n limbs long, tmp needs to be mul_limb_numb(n) limbs
|
||||
+ * long
|
||||
+ */
|
||||
+static void limb_mul(limb_t *ret, limb_t *a, limb_t *b, size_t n, limb_t *tmp)
|
||||
+{
|
||||
+ limb_t *r_odd, *r_even;
|
||||
+ size_t i, j, k;
|
||||
+
|
||||
+ r_odd = tmp;
|
||||
+ r_even = &tmp[2 * n];
|
||||
+
|
||||
+ memset(ret, 0, 2 * n * sizeof(limb_t));
|
||||
+
|
||||
+ for (i = 0; i < n; i++) {
|
||||
+ for (k = 0; k < i + n + 1; k++) {
|
||||
+ r_even[k] = 0;
|
||||
+ r_odd[k] = 0;
|
||||
+ }
|
||||
+ for (j = 0; j < n; j++) {
|
||||
+ /*
|
||||
+ * place results from even and odd limbs in separate arrays so that
|
||||
+ * we don't have to calculate overflow every time we get individual
|
||||
+ * limb multiplication result
|
||||
+ */
|
||||
+ if (j % 2 == 0)
|
||||
+ _mul_limb(&r_even[i + j], &r_even[i + j + 1], a[i], b[j]);
|
||||
+ else
|
||||
+ _mul_limb(&r_odd[i + j], &r_odd[i + j + 1], a[i], b[j]);
|
||||
+ }
|
||||
+ /*
|
||||
+ * skip the least significant limbs when adding multiples of
|
||||
+ * more significant limbs (they're zero anyway)
|
||||
+ */
|
||||
+ add(ret, ret, r_even, n + i + 1);
|
||||
+ add(ret, ret, r_odd, n + i + 1);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* modifies the value in place by performing a right shift by one bit */
|
||||
+static ossl_inline void rshift1(limb_t *val, size_t n)
|
||||
+{
|
||||
+ limb_t shift_in = 0, shift_out = 0;
|
||||
+ size_t i;
|
||||
+
|
||||
+ for (i = 0; i < n; i++) {
|
||||
+ shift_out = val[i] & 1;
|
||||
+ val[i] = shift_in << (LIMB_BIT_SIZE - 1) | (val[i] >> 1);
|
||||
+ shift_in = shift_out;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* extend the LSB of flag to all bits of limb */
|
||||
+static ossl_inline limb_t mk_mask(limb_t flag)
|
||||
+{
|
||||
+ flag |= flag << 1;
|
||||
+ flag |= flag << 2;
|
||||
+ flag |= flag << 4;
|
||||
+ flag |= flag << 8;
|
||||
+ flag |= flag << 16;
|
||||
+#if (LIMB_BYTE_SIZE == 8)
|
||||
+ flag |= flag << 32;
|
||||
+#endif
|
||||
+ return flag;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * copy from either a or b to ret based on flag
|
||||
+ * when flag == 0, then copies from b
|
||||
+ * when flag == 1, then copies from a
|
||||
+ */
|
||||
+static ossl_inline void cselect(limb_t flag, limb_t *ret, limb_t *a, limb_t *b, size_t n)
|
||||
+{
|
||||
+ /*
|
||||
+ * would be more efficient with non volatile mask, but then gcc
|
||||
+ * generates code with jumps
|
||||
+ */
|
||||
+ volatile limb_t mask;
|
||||
+ size_t i;
|
||||
+
|
||||
+ mask = mk_mask(flag);
|
||||
+ for (i = 0; i < n; i++) {
|
||||
+#if (LIMB_BYTE_SIZE == 8)
|
||||
+ ret[i] = constant_time_select_64(mask, a[i], b[i]);
|
||||
+#else
|
||||
+ ret[i] = constant_time_select_32(mask, a[i], b[i]);
|
||||
+#endif
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static limb_t _sub_limb(limb_t *ret, limb_t a, limb_t b, limb_t borrow)
|
||||
+{
|
||||
+ limb_t borrow1, borrow2, t;
|
||||
+ /*
|
||||
+ * while it doesn't look constant-time, this is idiomatic code
|
||||
+ * to tell compilers to use the carry bit from subtraction
|
||||
+ */
|
||||
+
|
||||
+ *ret = a - borrow;
|
||||
+ if (*ret > a)
|
||||
+ borrow1 = 1;
|
||||
+ else
|
||||
+ borrow1 = 0;
|
||||
+
|
||||
+ t = *ret;
|
||||
+ *ret = t - b;
|
||||
+ if (*ret > t)
|
||||
+ borrow2 = 1;
|
||||
+ else
|
||||
+ borrow2 = 0;
|
||||
+
|
||||
+ return borrow1 + borrow2;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * place the result of a - b into ret, return the borrow bit.
|
||||
+ * All arrays need to be n limbs long
|
||||
+ */
|
||||
+static limb_t sub(limb_t *ret, limb_t *a, limb_t *b, size_t n)
|
||||
+{
|
||||
+ limb_t borrow = 0;
|
||||
+ ossl_ssize_t i;
|
||||
+
|
||||
+ for (i = n - 1; i > -1; i--)
|
||||
+ borrow = _sub_limb(&ret[i], a[i], b[i], borrow);
|
||||
+
|
||||
+ return borrow;
|
||||
+}
|
||||
+
|
||||
+/* return the number of limbs necessary to allocate for the mod() tmp operand */
|
||||
+static ossl_inline size_t mod_limb_numb(size_t anum, size_t modnum)
|
||||
+{
|
||||
+ return (anum + modnum) * 3;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * calculate a % mod, place the result in ret
|
||||
+ * size of a is defined by anum, size of ret and mod is modnum,
|
||||
+ * size of tmp is returned by mod_limb_numb()
|
||||
+ */
|
||||
+static void mod(limb_t *ret, limb_t *a, size_t anum, limb_t *mod,
|
||||
+ size_t modnum, limb_t *tmp)
|
||||
+{
|
||||
+ limb_t *atmp, *modtmp, *rettmp;
|
||||
+ limb_t res;
|
||||
+ size_t i;
|
||||
+
|
||||
+ memset(tmp, 0, mod_limb_numb(anum, modnum) * LIMB_BYTE_SIZE);
|
||||
+
|
||||
+ atmp = tmp;
|
||||
+ modtmp = &tmp[anum + modnum];
|
||||
+ rettmp = &tmp[(anum + modnum) * 2];
|
||||
+
|
||||
+ for (i = modnum; i <modnum + anum; i++)
|
||||
+ atmp[i] = a[i-modnum];
|
||||
+
|
||||
+ for (i = 0; i < modnum; i++)
|
||||
+ modtmp[i] = mod[i];
|
||||
+
|
||||
+ for (i = 0; i < anum * LIMB_BIT_SIZE; i++) {
|
||||
+ rshift1(modtmp, anum + modnum);
|
||||
+ res = sub(rettmp, atmp, modtmp, anum+modnum);
|
||||
+ cselect(res, atmp, atmp, rettmp, anum+modnum);
|
||||
+ }
|
||||
+
|
||||
+ memcpy(ret, &atmp[anum], sizeof(limb_t) * modnum);
|
||||
+}
|
||||
+
|
||||
+/* necessary size of tmp for a _mul_add_limb() call with provided anum */
|
||||
+static ossl_inline size_t _mul_add_limb_numb(size_t anum)
|
||||
+{
|
||||
+ return 2 * (anum + 1);
|
||||
+}
|
||||
+
|
||||
+/* multiply a by m, add to ret, return carry */
|
||||
+static limb_t _mul_add_limb(limb_t *ret, limb_t *a, size_t anum,
|
||||
+ limb_t m, limb_t *tmp)
|
||||
+{
|
||||
+ limb_t carry = 0;
|
||||
+ limb_t *r_odd, *r_even;
|
||||
+ size_t i;
|
||||
+
|
||||
+ memset(tmp, 0, sizeof(limb_t) * (anum + 1) * 2);
|
||||
+
|
||||
+ r_odd = tmp;
|
||||
+ r_even = &tmp[anum + 1];
|
||||
+
|
||||
+ for (i = 0; i < anum; i++) {
|
||||
+ /*
|
||||
+ * place the results from even and odd limbs in separate arrays
|
||||
+ * so that we have to worry about carry just once
|
||||
+ */
|
||||
+ if (i % 2 == 0)
|
||||
+ _mul_limb(&r_even[i], &r_even[i + 1], a[i], m);
|
||||
+ else
|
||||
+ _mul_limb(&r_odd[i], &r_odd[i + 1], a[i], m);
|
||||
+ }
|
||||
+ /* assert: add() carry here will be equal zero */
|
||||
+ add(r_even, r_even, r_odd, anum + 1);
|
||||
+ /*
|
||||
+ * while here it will not overflow as the max value from multiplication
|
||||
+ * is -2 while max overflow from addition is 1, so the max value of
|
||||
+ * carry is -1 (i.e. max int)
|
||||
+ */
|
||||
+ carry = add(ret, ret, &r_even[1], anum) + r_even[0];
|
||||
+
|
||||
+ return carry;
|
||||
+}
|
||||
+
|
||||
+static ossl_inline size_t mod_montgomery_limb_numb(size_t modnum)
|
||||
+{
|
||||
+ return modnum * 2 + _mul_add_limb_numb(modnum);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * calculate a % mod, place result in ret
|
||||
+ * assumes that a is in Montgomery form with the R (Montgomery modulus) being
|
||||
+ * smallest power of two big enough to fit mod and that's also a power
|
||||
+ * of the count of number of bits in limb_t (B).
|
||||
+ * For calculation, we also need n', such that mod * n' == -1 mod B.
|
||||
+ * anum must be <= 2 * modnum
|
||||
+ * ret needs to be modnum words long
|
||||
+ * tmp needs to be mod_montgomery_limb_numb(modnum) limbs long
|
||||
+ */
|
||||
+static void mod_montgomery(limb_t *ret, limb_t *a, size_t anum, limb_t *mod,
|
||||
+ size_t modnum, limb_t ni0, limb_t *tmp)
|
||||
+{
|
||||
+ limb_t carry, v;
|
||||
+ limb_t *res, *rp, *tmp2;
|
||||
+ ossl_ssize_t i;
|
||||
+
|
||||
+ res = tmp;
|
||||
+ /*
|
||||
+ * for intermediate result we need an integer twice as long as modulus
|
||||
+ * but keep the input in the least significant limbs
|
||||
+ */
|
||||
+ memset(res, 0, sizeof(limb_t) * (modnum * 2));
|
||||
+ memcpy(&res[modnum * 2 - anum], a, sizeof(limb_t) * anum);
|
||||
+ rp = &res[modnum];
|
||||
+ tmp2 = &res[modnum * 2];
|
||||
+
|
||||
+ carry = 0;
|
||||
+
|
||||
+ /* add multiples of the modulus to the value until R divides it cleanly */
|
||||
+ for (i = modnum; i > 0; i--, rp--) {
|
||||
+ v = _mul_add_limb(rp, mod, modnum, rp[modnum - 1] * ni0, tmp2);
|
||||
+ v = v + carry + rp[-1];
|
||||
+ carry |= (v != rp[-1]);
|
||||
+ carry &= (v <= rp[-1]);
|
||||
+ rp[-1] = v;
|
||||
+ }
|
||||
+
|
||||
+ /* perform the final reduction by mod... */
|
||||
+ carry -= sub(ret, rp, mod, modnum);
|
||||
+
|
||||
+ /* ...conditionally */
|
||||
+ cselect(carry, ret, rp, ret, modnum);
|
||||
+}
|
||||
+
|
||||
+/* allocated buffer should be freed afterwards */
|
||||
+static void BN_to_limb(const BIGNUM *bn, limb_t *buf, size_t limbs)
|
||||
+{
|
||||
+ int i;
|
||||
+ int real_limbs = (BN_num_bytes(bn) + LIMB_BYTE_SIZE - 1) / LIMB_BYTE_SIZE;
|
||||
+ limb_t *ptr = buf + (limbs - real_limbs);
|
||||
+
|
||||
+ for (i = 0; i < real_limbs; i++)
|
||||
+ ptr[i] = bn->d[real_limbs - i - 1];
|
||||
+}
|
||||
+
|
||||
+#if LIMB_BYTE_SIZE == 8
|
||||
+static ossl_inline uint64_t be64(uint64_t host)
|
||||
+{
|
||||
+ const union {
|
||||
+ long one;
|
||||
+ char little;
|
||||
+ } is_endian = { 1 };
|
||||
+
|
||||
+ if (is_endian.little) {
|
||||
+ uint64_t big = 0;
|
||||
+
|
||||
+ big |= (host & 0xff00000000000000) >> 56;
|
||||
+ big |= (host & 0x00ff000000000000) >> 40;
|
||||
+ big |= (host & 0x0000ff0000000000) >> 24;
|
||||
+ big |= (host & 0x000000ff00000000) >> 8;
|
||||
+ big |= (host & 0x00000000ff000000) << 8;
|
||||
+ big |= (host & 0x0000000000ff0000) << 24;
|
||||
+ big |= (host & 0x000000000000ff00) << 40;
|
||||
+ big |= (host & 0x00000000000000ff) << 56;
|
||||
+ return big;
|
||||
+ } else {
|
||||
+ return host;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+#else
|
||||
+/* Not all platforms have htobe32(). */
|
||||
+static ossl_inline uint32_t be32(uint32_t host)
|
||||
+{
|
||||
+ const union {
|
||||
+ long one;
|
||||
+ char little;
|
||||
+ } is_endian = { 1 };
|
||||
+
|
||||
+ if (is_endian.little) {
|
||||
+ uint32_t big = 0;
|
||||
+
|
||||
+ big |= (host & 0xff000000) >> 24;
|
||||
+ big |= (host & 0x00ff0000) >> 8;
|
||||
+ big |= (host & 0x0000ff00) << 8;
|
||||
+ big |= (host & 0x000000ff) << 24;
|
||||
+ return big;
|
||||
+ } else {
|
||||
+ return host;
|
||||
+ }
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+/*
|
||||
+ * We assume that intermediate, possible_arg2, blinding, and ctx are used
|
||||
+ * similar to BN_BLINDING_invert_ex() arguments.
|
||||
+ * to_mod is RSA modulus.
|
||||
+ * buf and num is the serialization buffer and its length.
|
||||
+ *
|
||||
+ * Here we use classic/Montgomery multiplication and modulo. After the calculation finished
|
||||
+ * we serialize the new structure instead of BIGNUMs taking endianness into account.
|
||||
+ */
|
||||
+int ossl_bn_rsa_do_unblind(const BIGNUM *intermediate,
|
||||
+ const BN_BLINDING *blinding,
|
||||
+ const BIGNUM *possible_arg2,
|
||||
+ const BIGNUM *to_mod, BN_CTX *ctx,
|
||||
+ unsigned char *buf, int num)
|
||||
+{
|
||||
+ limb_t *l_im = NULL, *l_mul = NULL, *l_mod = NULL;
|
||||
+ limb_t *l_ret = NULL, *l_tmp = NULL, l_buf;
|
||||
+ size_t l_im_count = 0, l_mul_count = 0, l_size = 0, l_mod_count = 0;
|
||||
+ size_t l_tmp_count = 0;
|
||||
+ int ret = 0;
|
||||
+ size_t i;
|
||||
+ unsigned char *tmp;
|
||||
+ const BIGNUM *arg1 = intermediate;
|
||||
+ const BIGNUM *arg2 = (possible_arg2 == NULL) ? blinding->Ai : possible_arg2;
|
||||
+
|
||||
+ l_im_count = (BN_num_bytes(arg1) + LIMB_BYTE_SIZE - 1) / LIMB_BYTE_SIZE;
|
||||
+ l_mul_count = (BN_num_bytes(arg2) + LIMB_BYTE_SIZE - 1) / LIMB_BYTE_SIZE;
|
||||
+ l_mod_count = (BN_num_bytes(to_mod) + LIMB_BYTE_SIZE - 1) / LIMB_BYTE_SIZE;
|
||||
+
|
||||
+ l_size = l_im_count > l_mul_count ? l_im_count : l_mul_count;
|
||||
+ l_im = OPENSSL_zalloc(l_size * LIMB_BYTE_SIZE);
|
||||
+ l_mul = OPENSSL_zalloc(l_size * LIMB_BYTE_SIZE);
|
||||
+ l_mod = OPENSSL_zalloc(l_mod_count * LIMB_BYTE_SIZE);
|
||||
+
|
||||
+ if ((l_im == NULL) || (l_mul == NULL) || (l_mod == NULL))
|
||||
+ goto err;
|
||||
+
|
||||
+ BN_to_limb(arg1, l_im, l_size);
|
||||
+ BN_to_limb(arg2, l_mul, l_size);
|
||||
+ BN_to_limb(to_mod, l_mod, l_mod_count);
|
||||
+
|
||||
+ l_ret = OPENSSL_malloc(2 * l_size * LIMB_BYTE_SIZE);
|
||||
+
|
||||
+ if (blinding->m_ctx != NULL) {
|
||||
+ l_tmp_count = mul_limb_numb(l_size) > mod_montgomery_limb_numb(l_mod_count) ?
|
||||
+ mul_limb_numb(l_size) : mod_montgomery_limb_numb(l_mod_count);
|
||||
+ l_tmp = OPENSSL_malloc(l_tmp_count * LIMB_BYTE_SIZE);
|
||||
+ } else {
|
||||
+ l_tmp_count = mul_limb_numb(l_size) > mod_limb_numb(2 * l_size, l_mod_count) ?
|
||||
+ mul_limb_numb(l_size) : mod_limb_numb(2 * l_size, l_mod_count);
|
||||
+ l_tmp = OPENSSL_malloc(l_tmp_count * LIMB_BYTE_SIZE);
|
||||
+ }
|
||||
+
|
||||
+ if ((l_ret == NULL) || (l_tmp == NULL))
|
||||
+ goto err;
|
||||
+
|
||||
+ if (blinding->m_ctx != NULL) {
|
||||
+ limb_mul(l_ret, l_im, l_mul, l_size, l_tmp);
|
||||
+ mod_montgomery(l_ret, l_ret, 2 * l_size, l_mod, l_mod_count,
|
||||
+ blinding->m_ctx->n0[0], l_tmp);
|
||||
+ } else {
|
||||
+ limb_mul(l_ret, l_im, l_mul, l_size, l_tmp);
|
||||
+ mod(l_ret, l_ret, 2 * l_size, l_mod, l_mod_count, l_tmp);
|
||||
+ }
|
||||
+
|
||||
+ /* modulus size in bytes can be equal to num but after limbs conversion it becomes bigger */
|
||||
+ if (num < BN_num_bytes(to_mod)) {
|
||||
+ BNerr(BN_F_OSSL_BN_RSA_DO_UNBLIND, ERR_R_PASSED_INVALID_ARGUMENT);
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ memset(buf, 0, num);
|
||||
+ tmp = buf + num - BN_num_bytes(to_mod);
|
||||
+ for (i = 0; i < l_mod_count; i++) {
|
||||
+#if LIMB_BYTE_SIZE == 8
|
||||
+ l_buf = be64(l_ret[i]);
|
||||
+#else
|
||||
+ l_buf = be32(l_ret[i]);
|
||||
+#endif
|
||||
+ if (i == 0) {
|
||||
+ int delta = LIMB_BYTE_SIZE - ((l_mod_count * LIMB_BYTE_SIZE) - num);
|
||||
+
|
||||
+ memcpy(tmp, ((char *)&l_buf) + LIMB_BYTE_SIZE - delta, delta);
|
||||
+ tmp += delta;
|
||||
+ } else {
|
||||
+ memcpy(tmp, &l_buf, LIMB_BYTE_SIZE);
|
||||
+ tmp += LIMB_BYTE_SIZE;
|
||||
+ }
|
||||
+ }
|
||||
+ ret = num;
|
||||
+
|
||||
+ err:
|
||||
+ OPENSSL_free(l_im);
|
||||
+ OPENSSL_free(l_mul);
|
||||
+ OPENSSL_free(l_mod);
|
||||
+ OPENSSL_free(l_tmp);
|
||||
+ OPENSSL_free(l_ret);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
|
||||
index 9f91a4a811..ba3a46d5b9 100644
|
||||
--- a/crypto/err/openssl.txt
|
||||
+++ b/crypto/err/openssl.txt
|
||||
@@ -1,4 +1,4 @@
|
||||
-# Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
|
||||
+# Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the OpenSSL license (the "License"). You may not use
|
||||
# this file except in compliance with the License. You can obtain a copy
|
||||
@@ -232,6 +232,7 @@ BN_F_BN_RSHIFT:146:BN_rshift
|
||||
BN_F_BN_SET_WORDS:144:bn_set_words
|
||||
BN_F_BN_STACK_PUSH:148:BN_STACK_push
|
||||
BN_F_BN_USUB:115:BN_usub
|
||||
+BN_F_OSSL_BN_RSA_DO_UNBLIND:151:ossl_bn_rsa_do_unblind
|
||||
BUF_F_BUF_MEM_GROW:100:BUF_MEM_grow
|
||||
BUF_F_BUF_MEM_GROW_CLEAN:105:BUF_MEM_grow_clean
|
||||
BUF_F_BUF_MEM_NEW:101:BUF_MEM_new
|
||||
diff --git a/crypto/rsa/rsa_ossl.c b/crypto/rsa/rsa_ossl.c
|
||||
index b52a66f6a6..6c3c0cf78d 100644
|
||||
--- a/crypto/rsa/rsa_ossl.c
|
||||
+++ b/crypto/rsa/rsa_ossl.c
|
||||
@@ -465,11 +465,20 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from,
|
||||
BN_free(d);
|
||||
}
|
||||
|
||||
- if (blinding)
|
||||
- if (!rsa_blinding_invert(blinding, ret, unblind, ctx))
|
||||
+ if (blinding) {
|
||||
+ /*
|
||||
+ * ossl_bn_rsa_do_unblind() combines blinding inversion and
|
||||
+ * 0-padded BN BE serialization
|
||||
+ */
|
||||
+ j = ossl_bn_rsa_do_unblind(ret, blinding, unblind, rsa->n, ctx,
|
||||
+ buf, num);
|
||||
+ if (j == 0)
|
||||
goto err;
|
||||
-
|
||||
- j = BN_bn2binpad(ret, buf, num);
|
||||
+ } else {
|
||||
+ j = BN_bn2binpad(ret, buf, num);
|
||||
+ if (j < 0)
|
||||
+ goto err;
|
||||
+ }
|
||||
|
||||
switch (padding) {
|
||||
case RSA_PKCS1_PADDING:
|
||||
diff --git a/include/crypto/bn.h b/include/crypto/bn.h
|
||||
index 60afda1dad..b5f36fb25a 100644
|
||||
--- a/include/crypto/bn.h
|
||||
+++ b/include/crypto/bn.h
|
||||
@@ -86,5 +86,10 @@ int bn_lshift_fixed_top(BIGNUM *r, const BIGNUM *a, int n);
|
||||
int bn_rshift_fixed_top(BIGNUM *r, const BIGNUM *a, int n);
|
||||
int bn_div_fixed_top(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
|
||||
const BIGNUM *d, BN_CTX *ctx);
|
||||
+int ossl_bn_rsa_do_unblind(const BIGNUM *intermediate,
|
||||
+ const BN_BLINDING *blinding,
|
||||
+ const BIGNUM *possible_arg2,
|
||||
+ const BIGNUM *to_mod, BN_CTX *ctx,
|
||||
+ unsigned char *buf, int num);
|
||||
|
||||
#endif
|
||||
diff --git a/include/openssl/bnerr.h b/include/openssl/bnerr.h
|
||||
index 9f3c7cfaab..a0752cea52 100644
|
||||
--- a/include/openssl/bnerr.h
|
||||
+++ b/include/openssl/bnerr.h
|
||||
@@ -72,6 +72,7 @@ int ERR_load_BN_strings(void);
|
||||
# define BN_F_BN_SET_WORDS 144
|
||||
# define BN_F_BN_STACK_PUSH 148
|
||||
# define BN_F_BN_USUB 115
|
||||
+# define BN_F_OSSL_BN_RSA_DO_UNBLIND 151
|
||||
|
||||
/*
|
||||
* BN reason codes.
|
||||
--
|
||||
2.39.1
|
||||
|
@ -1,103 +0,0 @@
|
||||
From bbcf509bd046b34cca19c766bbddc31683d0858b Mon Sep 17 00:00:00 2001
|
||||
From: Matt Caswell <matt@openssl.org>
|
||||
Date: Tue, 13 Dec 2022 14:54:55 +0000
|
||||
Subject: [PATCH 2/6] Avoid dangling ptrs in header and data params for
|
||||
PEM_read_bio_ex
|
||||
|
||||
In the event of a failure in PEM_read_bio_ex() we free the buffers we
|
||||
allocated for the header and data buffers. However we were not clearing
|
||||
the ptrs stored in *header and *data. Since, on success, the caller is
|
||||
responsible for freeing these ptrs this can potentially lead to a double
|
||||
free if the caller frees them even on failure.
|
||||
|
||||
Thanks to Dawei Wang for reporting this issue.
|
||||
|
||||
Based on a proposed patch by Kurt Roeckx.
|
||||
|
||||
CVE-2022-4450
|
||||
|
||||
Reviewed-by: Paul Dale <pauli@openssl.org>
|
||||
Reviewed-by: Hugo Landau <hlandau@openssl.org>
|
||||
---
|
||||
crypto/pem/pem_lib.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/crypto/pem/pem_lib.c b/crypto/pem/pem_lib.c
|
||||
index d416d939ea..328c30cdbb 100644
|
||||
--- a/crypto/pem/pem_lib.c
|
||||
+++ b/crypto/pem/pem_lib.c
|
||||
@@ -957,7 +957,9 @@ int PEM_read_bio_ex(BIO *bp, char **name_out, char **header,
|
||||
*data = pem_malloc(len, flags);
|
||||
if (*header == NULL || *data == NULL) {
|
||||
pem_free(*header, flags, 0);
|
||||
+ *header = NULL;
|
||||
pem_free(*data, flags, 0);
|
||||
+ *data = NULL;
|
||||
goto end;
|
||||
}
|
||||
BIO_read(headerB, *header, headerlen);
|
||||
--
|
||||
2.39.1
|
||||
|
||||
From 2bd611267868a008afa576846ba71566bd0d4d15 Mon Sep 17 00:00:00 2001
|
||||
From: Matt Caswell <matt@openssl.org>
|
||||
Date: Tue, 13 Dec 2022 15:02:26 +0000
|
||||
Subject: [PATCH 3/6] Add a test for CVE-2022-4450
|
||||
|
||||
Call PEM_read_bio_ex() and expect a failure. There should be no dangling
|
||||
ptrs and therefore there should be no double free if we free the ptrs on
|
||||
error.
|
||||
|
||||
Reviewed-by: Paul Dale <pauli@openssl.org>
|
||||
Reviewed-by: Hugo Landau <hlandau@openssl.org>
|
||||
---
|
||||
test/pemtest.c | 30 ++++++++++++++++++++++++++++++
|
||||
1 file changed, 30 insertions(+)
|
||||
|
||||
diff --git a/test/pemtest.c b/test/pemtest.c
|
||||
index 3203d976be..edeb0a1205 100644
|
||||
--- a/test/pemtest.c
|
||||
+++ b/test/pemtest.c
|
||||
@@ -83,9 +83,39 @@ static int test_invalid(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
+static int test_empty_payload(void)
|
||||
+{
|
||||
+ BIO *b;
|
||||
+ static char *emptypay =
|
||||
+ "-----BEGIN CERTIFICATE-----\n"
|
||||
+ "-\n" /* Base64 EOF character */
|
||||
+ "-----END CERTIFICATE-----";
|
||||
+ char *name = NULL, *header = NULL;
|
||||
+ unsigned char *data = NULL;
|
||||
+ long len;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ b = BIO_new_mem_buf(emptypay, strlen(emptypay));
|
||||
+ if (!TEST_ptr(b))
|
||||
+ return 0;
|
||||
+
|
||||
+ /* Expected to fail because the payload is empty */
|
||||
+ if (!TEST_false(PEM_read_bio_ex(b, &name, &header, &data, &len, 0)))
|
||||
+ goto err;
|
||||
+
|
||||
+ ret = 1;
|
||||
+ err:
|
||||
+ OPENSSL_free(name);
|
||||
+ OPENSSL_free(header);
|
||||
+ OPENSSL_free(data);
|
||||
+ BIO_free(b);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
int setup_tests(void)
|
||||
{
|
||||
ADD_ALL_TESTS(test_b64, OSSL_NELEM(b64_pem_data));
|
||||
ADD_TEST(test_invalid);
|
||||
+ ADD_TEST(test_empty_payload);
|
||||
return 1;
|
||||
}
|
||||
--
|
||||
2.39.1
|
||||
|
@ -1,186 +0,0 @@
|
||||
From c3829dd8825c654652201e16f8a0a0c46ee3f344 Mon Sep 17 00:00:00 2001
|
||||
From: Matt Caswell <matt@openssl.org>
|
||||
Date: Wed, 14 Dec 2022 16:18:14 +0000
|
||||
Subject: [PATCH 4/6] Fix a UAF resulting from a bug in BIO_new_NDEF
|
||||
|
||||
If the aux->asn1_cb() call fails in BIO_new_NDEF then the "out" BIO will
|
||||
be part of an invalid BIO chain. This causes a "use after free" when the
|
||||
BIO is eventually freed.
|
||||
|
||||
Based on an original patch by Viktor Dukhovni and an idea from Theo
|
||||
Buehler.
|
||||
|
||||
Thanks to Octavio Galland for reporting this issue.
|
||||
|
||||
Reviewed-by: Paul Dale <pauli@openssl.org>
|
||||
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
||||
---
|
||||
crypto/asn1/bio_ndef.c | 39 ++++++++++++++++++++++++++++++++-------
|
||||
1 file changed, 32 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/crypto/asn1/bio_ndef.c b/crypto/asn1/bio_ndef.c
|
||||
index 760e4846a4..f8d4b1b9aa 100644
|
||||
--- a/crypto/asn1/bio_ndef.c
|
||||
+++ b/crypto/asn1/bio_ndef.c
|
||||
@@ -49,12 +49,19 @@ static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
|
||||
static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen,
|
||||
void *parg);
|
||||
|
||||
+/*
|
||||
+ * On success, the returned BIO owns the input BIO as part of its BIO chain.
|
||||
+ * On failure, NULL is returned and the input BIO is owned by the caller.
|
||||
+ *
|
||||
+ * Unfortunately cannot constify this due to CMS_stream() and PKCS7_stream()
|
||||
+ */
|
||||
BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
|
||||
{
|
||||
NDEF_SUPPORT *ndef_aux = NULL;
|
||||
BIO *asn_bio = NULL;
|
||||
const ASN1_AUX *aux = it->funcs;
|
||||
ASN1_STREAM_ARG sarg;
|
||||
+ BIO *pop_bio = NULL;
|
||||
|
||||
if (!aux || !aux->asn1_cb) {
|
||||
ASN1err(ASN1_F_BIO_NEW_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED);
|
||||
@@ -69,21 +76,39 @@ BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
|
||||
out = BIO_push(asn_bio, out);
|
||||
if (out == NULL)
|
||||
goto err;
|
||||
+ pop_bio = asn_bio;
|
||||
|
||||
- BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
|
||||
- BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free);
|
||||
+ if (BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free) <= 0
|
||||
+ || BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free) <= 0
|
||||
+ || BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux) <= 0)
|
||||
+ goto err;
|
||||
|
||||
/*
|
||||
- * Now let callback prepends any digest, cipher etc BIOs ASN1 structure
|
||||
- * needs.
|
||||
+ * Now let the callback prepend any digest, cipher, etc., that the BIO's
|
||||
+ * ASN1 structure needs.
|
||||
*/
|
||||
|
||||
sarg.out = out;
|
||||
sarg.ndef_bio = NULL;
|
||||
sarg.boundary = NULL;
|
||||
|
||||
- if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0)
|
||||
+ /*
|
||||
+ * The asn1_cb(), must not have mutated asn_bio on error, leaving it in the
|
||||
+ * middle of some partially built, but not returned BIO chain.
|
||||
+ */
|
||||
+ if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0) {
|
||||
+ /*
|
||||
+ * ndef_aux is now owned by asn_bio so we must not free it in the err
|
||||
+ * clean up block
|
||||
+ */
|
||||
+ ndef_aux = NULL;
|
||||
goto err;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * We must not fail now because the callback has prepended additional
|
||||
+ * BIOs to the chain
|
||||
+ */
|
||||
|
||||
ndef_aux->val = val;
|
||||
ndef_aux->it = it;
|
||||
@@ -91,11 +116,11 @@ BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
|
||||
ndef_aux->boundary = sarg.boundary;
|
||||
ndef_aux->out = out;
|
||||
|
||||
- BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);
|
||||
-
|
||||
return sarg.ndef_bio;
|
||||
|
||||
err:
|
||||
+ /* BIO_pop() is NULL safe */
|
||||
+ (void)BIO_pop(pop_bio);
|
||||
BIO_free(asn_bio);
|
||||
OPENSSL_free(ndef_aux);
|
||||
return NULL;
|
||||
--
|
||||
2.39.1
|
||||
|
||||
From f040f2577891d2bdb7610566c172233844cf673a Mon Sep 17 00:00:00 2001
|
||||
From: Matt Caswell <matt@openssl.org>
|
||||
Date: Wed, 14 Dec 2022 17:15:18 +0000
|
||||
Subject: [PATCH 5/6] Check CMS failure during BIO setup with -stream is
|
||||
handled correctly
|
||||
|
||||
Test for the issue fixed in the previous commit
|
||||
|
||||
Reviewed-by: Paul Dale <pauli@openssl.org>
|
||||
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
||||
---
|
||||
test/recipes/80-test_cms.t | 15 +++++++++++++--
|
||||
test/smime-certs/badrsa.pem | 18 ++++++++++++++++++
|
||||
2 files changed, 31 insertions(+), 2 deletions(-)
|
||||
create mode 100644 test/smime-certs/badrsa.pem
|
||||
|
||||
diff --git a/test/recipes/80-test_cms.t b/test/recipes/80-test_cms.t
|
||||
index 5dc6a3aebe..ec11bfc253 100644
|
||||
--- a/test/recipes/80-test_cms.t
|
||||
+++ b/test/recipes/80-test_cms.t
|
||||
@@ -13,7 +13,7 @@ use warnings;
|
||||
use POSIX;
|
||||
use File::Spec::Functions qw/catfile/;
|
||||
use File::Compare qw/compare_text/;
|
||||
-use OpenSSL::Test qw/:DEFAULT srctop_dir srctop_file/;
|
||||
+use OpenSSL::Test qw/:DEFAULT srctop_dir srctop_file with/;
|
||||
use OpenSSL::Test::Utils;
|
||||
|
||||
setup("test_cms");
|
||||
@@ -27,7 +27,7 @@ my $smcont = srctop_file("test", "smcont.txt");
|
||||
my ($no_des, $no_dh, $no_dsa, $no_ec, $no_ec2m, $no_rc2, $no_zlib)
|
||||
= disabled qw/des dh dsa ec ec2m rc2 zlib/;
|
||||
|
||||
-plan tests => 6;
|
||||
+plan tests => 7;
|
||||
|
||||
my @smime_pkcs7_tests = (
|
||||
|
||||
@@ -584,3 +584,14 @@ sub check_availability {
|
||||
|
||||
return "";
|
||||
}
|
||||
+
|
||||
+# Check that we get the expected failure return code
|
||||
+with({ exit_checker => sub { return shift == 6; } },
|
||||
+ sub {
|
||||
+ ok(run(app(['openssl', 'cms', '-encrypt',
|
||||
+ '-in', srctop_file("test", "smcont.txt"),
|
||||
+ '-stream', '-recip',
|
||||
+ srctop_file("test/smime-certs", "badrsa.pem"),
|
||||
+ ])),
|
||||
+ "Check failure during BIO setup with -stream is handled correctly");
|
||||
+ });
|
||||
diff --git a/test/smime-certs/badrsa.pem b/test/smime-certs/badrsa.pem
|
||||
new file mode 100644
|
||||
index 0000000000..f824fc2267
|
||||
--- /dev/null
|
||||
+++ b/test/smime-certs/badrsa.pem
|
||||
@@ -0,0 +1,18 @@
|
||||
+-----BEGIN CERTIFICATE-----
|
||||
+MIIDbTCCAlWgAwIBAgIToTV4Z0iuK08vZP20oTh//hC8BDANBgkqhkiG9w0BAQ0FADAtMSswKQYD
|
||||
+VfcDEyJTYW1wbGUgTEFNUFMgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MCAXDTE5MTEyMDA2NTQxOFoY
|
||||
+DzIwNTIwOTI3MDY1NDE4WjAZMRcwFQYDVQQDEw5BbGljZSBMb3ZlbGFjZTCCASIwDQYJKoZIhvcN
|
||||
+AQEBBQADggEPADCCAQoCggEBALT0iehYOBY+TZp/T5K2KNI05Hwr+E3wP6XTvyi6WWyTgBK9LCOw
|
||||
+I2juwdRrjFBmXkk7pWpjXwsA3A5GOtz0FpfgyC7OxsVcF7q4WHWZWleYXFKlQHJD73nQwXP968+A
|
||||
+/3rBX7PhO0DBbZnfitOLPgPEwjTtdg0VQQ6Wz+CRQ/YbHPKaw7aRphZO63dKvIKp4cQVtkWQHi6s
|
||||
+yTjGsgkLcLNau5LZDQUdsGV+SAo3nBdWCRYV+I65x8Kf4hCxqqmjV3d/2NKRu0BXnDe/N+iDz3X0
|
||||
+zEoj0fqXgq4SWcC0nsG1lyyXt1TL270I6ATKRGJWiQVCCpDtc0NT6vdJ45bCSxgCAwEAAaOBlzCB
|
||||
+lDAMBgNVHRMBAf8EAjAAMB4GA1UdEQQXMBWBE2FsaWNlQHNtaW1lLmV4YW1wbGUwEwYDVR0lBAww
|
||||
+CgYIKwYBBQUHAwQwDwYDVR0PAQH/BAUDAwfAADAdBgNVHQ4EFgQUu/bMsi0dBhIcl64papAQ0yBm
|
||||
+ZnMwHwYDVR0jBBgwFoAUeF8OWnjYa+RUcD2z3ez38fL6wEcwDQYJKoZIhvcNAQENBQADggEBABbW
|
||||
+eonR6TMTckehDKNOabwaCIcekahAIL6l9tTzUX5ew6ufiAPlC6I/zQlmUaU0iSyFDG1NW14kNbFt
|
||||
+5CAokyLhMtE4ASHBIHbiOp/ZSbUBTVYJZB61ot7w1/ol5QECSs08b8zrxIncf+t2DHGuVEy/Qq1d
|
||||
+rBz8d4ay8zpqAE1tUyL5Da6ZiKUfWwZQXSI/JlbjQFzYQqTRDnzHWrg1xPeMTO1P2/cplFaseTiv
|
||||
+yk4cYwOp/W9UAWymOZXF8WcJYCIUXkdcG/nEZxr057KlScrJmFXOoh7Y+8ON4iWYYcAfiNgpUFo/
|
||||
+j8BAwrKKaFvdlZS9k1Ypb2+UQY75mKJE9Bg=
|
||||
+-----END CERTIFICATE-----
|
||||
--
|
||||
2.39.1
|
||||
|
@ -1,63 +0,0 @@
|
||||
From 2c6c9d439b484e1ba9830d8454a34fa4f80fdfe9 Mon Sep 17 00:00:00 2001
|
||||
From: Hugo Landau <hlandau@openssl.org>
|
||||
Date: Tue, 17 Jan 2023 17:45:42 +0000
|
||||
Subject: [PATCH 6/6] CVE-2023-0286: Fix GENERAL_NAME_cmp for x400Address
|
||||
(1.1.1)
|
||||
|
||||
Reviewed-by: Paul Dale <pauli@openssl.org>
|
||||
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
||||
---
|
||||
CHANGES | 18 +++++++++++++++++-
|
||||
crypto/x509v3/v3_genn.c | 2 +-
|
||||
include/openssl/x509v3.h | 2 +-
|
||||
test/v3nametest.c | 8 ++++++++
|
||||
4 files changed, 27 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/crypto/x509v3/v3_genn.c b/crypto/x509v3/v3_genn.c
|
||||
index 87a5eff47c..e54ddc55c9 100644
|
||||
--- a/crypto/x509v3/v3_genn.c
|
||||
+++ b/crypto/x509v3/v3_genn.c
|
||||
@@ -98,7 +98,7 @@ int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)
|
||||
return -1;
|
||||
switch (a->type) {
|
||||
case GEN_X400:
|
||||
- result = ASN1_TYPE_cmp(a->d.x400Address, b->d.x400Address);
|
||||
+ result = ASN1_STRING_cmp(a->d.x400Address, b->d.x400Address);
|
||||
break;
|
||||
|
||||
case GEN_EDIPARTY:
|
||||
diff --git a/include/openssl/x509v3.h b/include/openssl/x509v3.h
|
||||
index 90fa3592ce..e61c0f29d4 100644
|
||||
--- a/include/openssl/x509v3.h
|
||||
+++ b/include/openssl/x509v3.h
|
||||
@@ -136,7 +136,7 @@ typedef struct GENERAL_NAME_st {
|
||||
OTHERNAME *otherName; /* otherName */
|
||||
ASN1_IA5STRING *rfc822Name;
|
||||
ASN1_IA5STRING *dNSName;
|
||||
- ASN1_TYPE *x400Address;
|
||||
+ ASN1_STRING *x400Address;
|
||||
X509_NAME *directoryName;
|
||||
EDIPARTYNAME *ediPartyName;
|
||||
ASN1_IA5STRING *uniformResourceIdentifier;
|
||||
diff --git a/test/v3nametest.c b/test/v3nametest.c
|
||||
index d1852190b8..37819da8fd 100644
|
||||
--- a/test/v3nametest.c
|
||||
+++ b/test/v3nametest.c
|
||||
@@ -646,6 +646,14 @@ static struct gennamedata {
|
||||
0xb7, 0x09, 0x02, 0x02
|
||||
},
|
||||
15
|
||||
+ }, {
|
||||
+ /*
|
||||
+ * Regression test for CVE-2023-0286.
|
||||
+ */
|
||||
+ {
|
||||
+ 0xa3, 0x00
|
||||
+ },
|
||||
+ 2
|
||||
}
|
||||
};
|
||||
|
||||
--
|
||||
2.39.1
|
||||
|
@ -1,127 +0,0 @@
|
||||
From 8780a896543a654e757db1b9396383f9d8095528 Mon Sep 17 00:00:00 2001
|
||||
From: Matt Caswell <matt@openssl.org>
|
||||
Date: Thu, 6 Jul 2023 16:36:35 +0100
|
||||
Subject: [PATCH] Fix DH_check() excessive time with over sized modulus
|
||||
|
||||
The DH_check() function checks numerous aspects of the key or parameters
|
||||
that have been supplied. Some of those checks use the supplied modulus
|
||||
value even if it is excessively large.
|
||||
|
||||
There is already a maximum DH modulus size (10,000 bits) over which
|
||||
OpenSSL will not generate or derive keys. DH_check() will however still
|
||||
perform various tests for validity on such a large modulus. We introduce a
|
||||
new maximum (32,768) over which DH_check() will just fail.
|
||||
|
||||
An application that calls DH_check() and supplies a key or parameters
|
||||
obtained from an untrusted source could be vulnerable to a Denial of
|
||||
Service attack.
|
||||
|
||||
The function DH_check() is itself called by a number of other OpenSSL
|
||||
functions. An application calling any of those other functions may
|
||||
similarly be affected. The other functions affected by this are
|
||||
DH_check_ex() and EVP_PKEY_param_check().
|
||||
|
||||
CVE-2023-3446
|
||||
|
||||
Reviewed-by: Paul Dale <pauli@openssl.org>
|
||||
Reviewed-by: Tom Cosgrove <tom.cosgrove@arm.com>
|
||||
Reviewed-by: Bernd Edlinger <bernd.edlinger@hotmail.de>
|
||||
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
||||
(Merged from https://github.com/openssl/openssl/pull/21452)
|
||||
|
||||
Upstream-Status: Backport [8780a896543a654e757db1b9396383f9d8095528]
|
||||
---
|
||||
crypto/dh/dh_check.c | 6 ++++++
|
||||
crypto/dh/dh_err.c | 3 ++-
|
||||
crypto/err/openssl.txt | 3 ++-
|
||||
include/openssl/dh.h | 3 +++
|
||||
include/openssl/dherr.h | 3 ++-
|
||||
5 files changed, 15 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/crypto/dh/dh_check.c b/crypto/dh/dh_check.c
|
||||
index 4ac169e75c..e5f9dd5030 100644
|
||||
--- a/crypto/dh/dh_check.c
|
||||
+++ b/crypto/dh/dh_check.c
|
||||
@@ -101,6 +101,12 @@ int DH_check(const DH *dh, int *ret)
|
||||
BN_CTX *ctx = NULL;
|
||||
BIGNUM *t1 = NULL, *t2 = NULL;
|
||||
|
||||
+ /* Don't do any checks at all with an excessively large modulus */
|
||||
+ if (BN_num_bits(dh->p) > OPENSSL_DH_CHECK_MAX_MODULUS_BITS) {
|
||||
+ DHerr(DH_F_DH_CHECK, DH_R_MODULUS_TOO_LARGE);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
if (!DH_check_params(dh, ret))
|
||||
return 0;
|
||||
|
||||
diff --git a/crypto/dh/dh_err.c b/crypto/dh/dh_err.c
|
||||
index 7285587b4a..92800d3fcc 100644
|
||||
--- a/crypto/dh/dh_err.c
|
||||
+++ b/crypto/dh/dh_err.c
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -18,6 +18,7 @@ static const ERR_STRING_DATA DH_str_functs[] = {
|
||||
{ERR_PACK(ERR_LIB_DH, DH_F_DHPARAMS_PRINT_FP, 0), "DHparams_print_fp"},
|
||||
{ERR_PACK(ERR_LIB_DH, DH_F_DH_BUILTIN_GENPARAMS, 0),
|
||||
"dh_builtin_genparams"},
|
||||
+ {ERR_PACK(ERR_LIB_DH, DH_F_DH_CHECK, 0), "DH_check"},
|
||||
{ERR_PACK(ERR_LIB_DH, DH_F_DH_CHECK_EX, 0), "DH_check_ex"},
|
||||
{ERR_PACK(ERR_LIB_DH, DH_F_DH_CHECK_PARAMS_EX, 0), "DH_check_params_ex"},
|
||||
{ERR_PACK(ERR_LIB_DH, DH_F_DH_CHECK_PUB_KEY_EX, 0), "DH_check_pub_key_ex"},
|
||||
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
|
||||
index 9f91a4a811..c0a3cd720b 100644
|
||||
--- a/crypto/err/openssl.txt
|
||||
+++ b/crypto/err/openssl.txt
|
||||
@@ -402,6 +402,7 @@ CT_F_SCT_SET_VERSION:104:SCT_set_version
|
||||
DH_F_COMPUTE_KEY:102:compute_key
|
||||
DH_F_DHPARAMS_PRINT_FP:101:DHparams_print_fp
|
||||
DH_F_DH_BUILTIN_GENPARAMS:106:dh_builtin_genparams
|
||||
+DH_F_DH_CHECK:126:DH_check
|
||||
DH_F_DH_CHECK_EX:121:DH_check_ex
|
||||
DH_F_DH_CHECK_PARAMS_EX:122:DH_check_params_ex
|
||||
DH_F_DH_CHECK_PUB_KEY_EX:123:DH_check_pub_key_ex
|
||||
diff --git a/include/openssl/dh.h b/include/openssl/dh.h
|
||||
index 3527540cdd..892e31559d 100644
|
||||
--- a/include/openssl/dh.h
|
||||
+++ b/include/openssl/dh.h
|
||||
@@ -29,6 +29,9 @@ extern "C" {
|
||||
# ifndef OPENSSL_DH_MAX_MODULUS_BITS
|
||||
# define OPENSSL_DH_MAX_MODULUS_BITS 10000
|
||||
# endif
|
||||
+# ifndef OPENSSL_DH_CHECK_MAX_MODULUS_BITS
|
||||
+# define OPENSSL_DH_CHECK_MAX_MODULUS_BITS 32768
|
||||
+# endif
|
||||
|
||||
# define OPENSSL_DH_FIPS_MIN_MODULUS_BITS 1024
|
||||
# define OPENSSL_DH_FIPS_MIN_MODULUS_BITS_GEN 2048
|
||||
|
||||
diff --git a/include/openssl/dherr.h b/include/openssl/dherr.h
|
||||
index 916b3bed0b..528c819856 100644
|
||||
--- a/include/openssl/dherr.h
|
||||
+++ b/include/openssl/dherr.h
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -30,6 +30,7 @@ int ERR_load_DH_strings(void);
|
||||
# define DH_F_COMPUTE_KEY 102
|
||||
# define DH_F_DHPARAMS_PRINT_FP 101
|
||||
# define DH_F_DH_BUILTIN_GENPARAMS 106
|
||||
+# define DH_F_DH_CHECK 126
|
||||
# define DH_F_DH_CHECK_EX 121
|
||||
# define DH_F_DH_CHECK_PARAMS_EX 122
|
||||
# define DH_F_DH_CHECK_PUB_KEY_EX 123
|
||||
--
|
||||
2.41.0
|
||||
|
@ -1,60 +0,0 @@
|
||||
From 91ddeba0f2269b017dc06c46c993a788974b1aa5 Mon Sep 17 00:00:00 2001
|
||||
From: Tomas Mraz <tomas@openssl.org>
|
||||
Date: Fri, 21 Jul 2023 11:39:41 +0200
|
||||
Subject: [PATCH] DH_check(): Do not try checking q properties if it is
|
||||
obviously invalid
|
||||
|
||||
If |q| >= |p| then the q value is obviously wrong as q
|
||||
is supposed to be a prime divisor of p-1.
|
||||
|
||||
We check if p is overly large so this added test implies that
|
||||
q is not large either when performing subsequent tests using that
|
||||
q value.
|
||||
|
||||
Otherwise if it is too large these additional checks of the q value
|
||||
such as the primality test can then trigger DoS by doing overly long
|
||||
computations.
|
||||
|
||||
Fixes CVE-2023-3817
|
||||
|
||||
Reviewed-by: Paul Dale <pauli@openssl.org>
|
||||
Reviewed-by: Matt Caswell <matt@openssl.org>
|
||||
(Merged from https://github.com/openssl/openssl/pull/21551)
|
||||
|
||||
Upstream-Status: Backport [91ddeba0f2269b017dc06c46c993a788974b1aa5]
|
||||
---
|
||||
crypto/dh/dh_check.c | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/crypto/dh/dh_check.c b/crypto/dh/dh_check.c
|
||||
index 2001d2e7cb..9ae96991eb 100644
|
||||
--- a/crypto/dh/dh_check.c
|
||||
+++ b/crypto/dh/dh_check.c
|
||||
@@ -105,7 +105,7 @@ int DH_check_ex(const DH *dh)
|
||||
/* Note: according to documentation - this only checks the params */
|
||||
int DH_check(const DH *dh, int *ret)
|
||||
{
|
||||
- int ok = 0, r;
|
||||
+ int ok = 0, r, q_good = 0;
|
||||
BN_CTX *ctx = NULL;
|
||||
BIGNUM *t1 = NULL, *t2 = NULL;
|
||||
|
||||
@@ -130,7 +130,14 @@ int DH_check(const DH *dh, int *ret)
|
||||
if (t2 == NULL)
|
||||
goto err;
|
||||
|
||||
- if (dh->q) {
|
||||
+ if (dh->q != NULL) {
|
||||
+ if (BN_ucmp(dh->p, dh->q) > 0)
|
||||
+ q_good = 1;
|
||||
+ else
|
||||
+ *ret |= DH_CHECK_INVALID_Q_VALUE;
|
||||
+ }
|
||||
+
|
||||
+ if (q_good) {
|
||||
if (BN_cmp(dh->g, BN_value_one()) <= 0)
|
||||
*ret |= DH_NOT_SUITABLE_GENERATOR;
|
||||
else if (BN_cmp(dh->g, dh->p) >= 0)
|
||||
--
|
||||
2.41.0
|
||||
|
@ -1,154 +0,0 @@
|
||||
From 0814467cc1b6a2839877277d3efa69cdd4582dd7 Mon Sep 17 00:00:00 2001
|
||||
From: Richard Levitte <levitte@openssl.org>
|
||||
Date: Fri, 20 Oct 2023 09:18:19 +0200
|
||||
Subject: [PATCH] Make DH_check_pub_key() and DH_generate_key() safer yet
|
||||
|
||||
We already check for an excessively large P in DH_generate_key(), but not in
|
||||
DH_check_pub_key(), and none of them check for an excessively large Q.
|
||||
|
||||
This change adds all the missing excessive size checks of P and Q.
|
||||
|
||||
It's to be noted that behaviours surrounding excessively sized P and Q
|
||||
differ. DH_check() raises an error on the excessively sized P, but only
|
||||
sets a flag for the excessively sized Q. This behaviour is mimicked in
|
||||
DH_check_pub_key().
|
||||
|
||||
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
||||
Reviewed-by: Matt Caswell <matt@openssl.org>
|
||||
Reviewed-by: Hugo Landau <hlandau@openssl.org>
|
||||
(Merged from https://github.com/openssl/openssl/pull/22518)
|
||||
|
||||
(cherry picked from commit ddeb4b6c6d527e54ce9a99cba785c0f7776e54b6)
|
||||
Backported-by: Clemens Lang <cllang@redhat.com>
|
||||
---
|
||||
crypto/dh/dh_check.c | 17 +++++++++++++++++
|
||||
crypto/dh/dh_err.c | 1 +
|
||||
crypto/dh/dh_key.c | 10 ++++++++++
|
||||
crypto/err/openssl.txt | 1 +
|
||||
include/openssl/dh.h | 6 ++++--
|
||||
include/openssl/dherr.h | 1 +
|
||||
6 files changed, 34 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/crypto/dh/dh_check.c b/crypto/dh/dh_check.c
|
||||
index ae1b03bc92..424a3bb4cd 100644
|
||||
--- a/crypto/dh/dh_check.c
|
||||
+++ b/crypto/dh/dh_check.c
|
||||
@@ -198,10 +198,27 @@ int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret)
|
||||
BN_CTX *ctx = NULL;
|
||||
|
||||
*ret = 0;
|
||||
+
|
||||
ctx = BN_CTX_new();
|
||||
if (ctx == NULL)
|
||||
goto err;
|
||||
BN_CTX_start(ctx);
|
||||
+
|
||||
+ /* Don't do any checks at all with an excessively large modulus */
|
||||
+ if (BN_num_bits(dh->p) > OPENSSL_DH_CHECK_MAX_MODULUS_BITS) {
|
||||
+ DHerr(DH_F_DH_CHECK, DH_R_MODULUS_TOO_LARGE);
|
||||
+ *ret = DH_MODULUS_TOO_LARGE | DH_CHECK_PUBKEY_INVALID;
|
||||
+ goto err;
|
||||
+ }
|
||||
+ if (dh->q != NULL && BN_ucmp(dh->p, dh->q) < 0) {
|
||||
+ *ret |= DH_CHECK_INVALID_Q_VALUE | DH_CHECK_PUBKEY_INVALID;
|
||||
+ /* This may look strange here, but returning 1 after setting ret is
|
||||
+ * correct. See also the behavior of the pub_key^q == 1 mod p check
|
||||
+ * further down, which behaves in the same way. */
|
||||
+ ok = 1;
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
tmp = BN_CTX_get(ctx);
|
||||
if (tmp == NULL || !BN_set_word(tmp, 1))
|
||||
goto err;
|
||||
diff --git a/crypto/dh/dh_err.c b/crypto/dh/dh_err.c
|
||||
index 92800d3fcc..b3b1e7a706 100644
|
||||
--- a/crypto/dh/dh_err.c
|
||||
+++ b/crypto/dh/dh_err.c
|
||||
@@ -87,6 +87,7 @@ static const ERR_STRING_DATA DH_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_DH, 0, DH_R_PARAMETER_ENCODING_ERROR),
|
||||
"parameter encoding error"},
|
||||
{ERR_PACK(ERR_LIB_DH, 0, DH_R_PEER_KEY_ERROR), "peer key error"},
|
||||
+ {ERR_PACK(ERR_LIB_DH, 0, DH_R_Q_TOO_LARGE), "q too large"},
|
||||
{ERR_PACK(ERR_LIB_DH, 0, DH_R_SHARED_INFO_ERROR), "shared info error"},
|
||||
{ERR_PACK(ERR_LIB_DH, 0, DH_R_UNABLE_TO_CHECK_GENERATOR),
|
||||
"unable to check generator"},
|
||||
diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c
|
||||
index 117f2fa883..9f5e6f6d4c 100644
|
||||
--- a/crypto/dh/dh_key.c
|
||||
+++ b/crypto/dh/dh_key.c
|
||||
@@ -140,6 +140,11 @@ static int generate_key(DH *dh)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+ if (dh->q != NULL && BN_num_bits(dh->q) > OPENSSL_DH_MAX_MODULUS_BITS) {
|
||||
+ DHerr(DH_F_GENERATE_KEY, DH_R_Q_TOO_LARGE);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
ctx = BN_CTX_new();
|
||||
if (ctx == NULL)
|
||||
goto err;
|
||||
@@ -250,6 +255,12 @@ static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
|
||||
DHerr(DH_F_COMPUTE_KEY, DH_R_MODULUS_TOO_LARGE);
|
||||
goto err;
|
||||
}
|
||||
+
|
||||
+ if (dh->q != NULL && BN_num_bits(dh->q) > OPENSSL_DH_MAX_MODULUS_BITS) {
|
||||
+ DHerr(DH_F_COMPUTE_KEY, DH_R_Q_TOO_LARGE);
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
#ifdef OPENSSL_FIPS
|
||||
if (FIPS_mode()
|
||||
&& (BN_num_bits(dh->p) < OPENSSL_DH_FIPS_MIN_MODULUS_BITS)) {
|
||||
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
|
||||
index c0a3cd720b..5e0ff47516 100644
|
||||
--- a/crypto/err/openssl.txt
|
||||
+++ b/crypto/err/openssl.txt
|
||||
@@ -2151,6 +2151,7 @@DH_R_NO_PARAMETERS_SET:107:no parameters set
|
||||
DH_R_NO_PRIVATE_VALUE:100:no private value
|
||||
DH_R_PARAMETER_ENCODING_ERROR:105:parameter encoding error
|
||||
DH_R_PEER_KEY_ERROR:111:peer key error
|
||||
+DH_R_Q_TOO_LARGE:130:q too large
|
||||
DH_R_SHARED_INFO_ERROR:113:shared info error
|
||||
DH_R_UNABLE_TO_CHECK_GENERATOR:121:unable to check generator
|
||||
DSA_R_BAD_Q_VALUE:102:bad q value
|
||||
diff --git a/include/openssl/dh.h b/include/openssl/dh.h
|
||||
index 6c6ff3636a..b7df43b44f 100644
|
||||
--- a/include/openssl/dh.h
|
||||
+++ b/include/openssl/dh.h
|
||||
@@ -72,14 +72,16 @@ DECLARE_ASN1_ITEM(DHparams)
|
||||
/* #define DH_GENERATOR_3 3 */
|
||||
# define DH_GENERATOR_5 5
|
||||
|
||||
-/* DH_check error codes */
|
||||
+/* DH_check error codes, some of them shared with DH_check_pub_key */
|
||||
# define DH_CHECK_P_NOT_PRIME 0x01
|
||||
# define DH_CHECK_P_NOT_SAFE_PRIME 0x02
|
||||
# define DH_UNABLE_TO_CHECK_GENERATOR 0x04
|
||||
# define DH_NOT_SUITABLE_GENERATOR 0x08
|
||||
# define DH_CHECK_Q_NOT_PRIME 0x10
|
||||
-# define DH_CHECK_INVALID_Q_VALUE 0x20
|
||||
+# define DH_CHECK_INVALID_Q_VALUE 0x20 /* +DH_check_pub_key */
|
||||
# define DH_CHECK_INVALID_J_VALUE 0x40
|
||||
+/* DH_MODULUS_TOO_SMALL is 0x80 upstream */
|
||||
+# define DH_MODULUS_TOO_LARGE 0x100 /* +DH_check_pub_key */
|
||||
|
||||
/* DH_check_pub_key error codes */
|
||||
# define DH_CHECK_PUBKEY_TOO_SMALL 0x01
|
||||
diff --git a/include/openssl/dherr.h b/include/openssl/dherr.h
|
||||
index 528c819856..d66c35aa8e 100644
|
||||
--- a/include/openssl/dherr.h
|
||||
+++ b/include/openssl/dherr.h
|
||||
@@ -87,6 +87,7 @@ int ERR_load_DH_strings(void);
|
||||
# define DH_R_NON_FIPS_METHOD 202
|
||||
# define DH_R_PARAMETER_ENCODING_ERROR 105
|
||||
# define DH_R_PEER_KEY_ERROR 111
|
||||
+# define DH_R_Q_TOO_LARGE 130
|
||||
# define DH_R_SHARED_INFO_ERROR 113
|
||||
# define DH_R_UNABLE_TO_CHECK_GENERATOR 121
|
||||
|
||||
--
|
||||
2.41.0
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -22,7 +22,7 @@
|
||||
Summary: Utilities from the general purpose cryptography library with TLS implementation
|
||||
Name: openssl
|
||||
Version: 1.1.1k
|
||||
Release: 12%{?dist}
|
||||
Release: 6%{?dist}
|
||||
Epoch: 1
|
||||
# We have to remove certain patented algorithms from the openssl source
|
||||
# tarball with the hobble-openssl script which is included below.
|
||||
@ -83,22 +83,6 @@ Patch74: openssl-1.1.1-addrconfig.patch
|
||||
Patch75: openssl-1.1.1-tls13-curves.patch
|
||||
Patch81: openssl-1.1.1-read-buff.patch
|
||||
Patch82: openssl-1.1.1-cve-2022-0778.patch
|
||||
Patch83: openssl-1.1.1-replace-expired-certs.patch
|
||||
Patch84: openssl-1.1.1-cve-2022-1292.patch
|
||||
Patch85: openssl-1.1.1-cve-2022-2068.patch
|
||||
Patch86: openssl-1.1.1-cve-2022-2097.patch
|
||||
#OpenSSL 1.1.1t CVEs
|
||||
Patch101: openssl-1.1.1-cve-2022-4304-RSA-oracle.patch
|
||||
Patch102: openssl-1.1.1-cve-2022-4450-PEM-bio.patch
|
||||
Patch103: openssl-1.1.1-cve-2023-0215-BIO-UAF.patch
|
||||
Patch104: openssl-1.1.1-cve-2023-0286-X400.patch
|
||||
# OpenSSL 1.1.1v CVEs
|
||||
Patch105: openssl-1.1.1-cve-2023-3446.patch
|
||||
Patch106: openssl-1.1.1-cve-2023-3817.patch
|
||||
Patch107: openssl-1.1.1-cve-2023-5678.patch
|
||||
# Backport from OpenSSL 3.2/RHEL 9
|
||||
# Proper fix for CVE-2020-25659
|
||||
Patch108: openssl-1.1.1-pkcs1-implicit-rejection.patch
|
||||
|
||||
License: OpenSSL and ASL 2.0
|
||||
URL: http://www.openssl.org/
|
||||
@ -220,18 +204,7 @@ cp %{SOURCE13} test/
|
||||
%patch80 -p1 -b .s390x-test-aes
|
||||
%patch81 -p1 -b .read-buff
|
||||
%patch82 -p1 -b .cve-2022-0778
|
||||
%patch83 -p1 -b .replace-expired-certs
|
||||
%patch84 -p1 -b .cve-2022-1292
|
||||
%patch85 -p1 -b .cve-2022-2068
|
||||
%patch86 -p1 -b .cve-2022-2097
|
||||
%patch101 -p1 -b .cve-2022-4304
|
||||
%patch102 -p1 -b .cve-2022-4450
|
||||
%patch103 -p1 -b .cve-2023-0215
|
||||
%patch104 -p1 -b .cve-2023-0286
|
||||
%patch105 -p1 -b .cve-2023-3446
|
||||
%patch106 -p1 -b .cve-2023-3817
|
||||
%patch107 -p1 -b .cve-2023-5678
|
||||
%patch108 -p1 -b .pkcs15imprejection
|
||||
|
||||
|
||||
%build
|
||||
# Figure out which flags we want to use.
|
||||
@ -515,53 +488,13 @@ export LD_LIBRARY_PATH
|
||||
%postun libs -p /sbin/ldconfig
|
||||
|
||||
%changelog
|
||||
* Thu Nov 30 2023 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:1.1.1k-12
|
||||
- Backport implicit rejection mechanism for RSA PKCS#1 v1.5 to RHEL-8 series
|
||||
(a proper fix for CVE-2020-25659)
|
||||
Resolves: RHEL-17696
|
||||
|
||||
* Wed Nov 15 2023 Clemens Lang <cllang@redhat.com> - 1:1.1.1k-11
|
||||
- Fix CVE-2023-5678: Generating excessively long X9.42 DH keys or checking
|
||||
excessively long X9.42 DH keys or parameters may be very slow
|
||||
Resolves: RHEL-16538
|
||||
|
||||
* Thu Oct 19 2023 Clemens Lang <cllang@redhat.com> - 1:1.1.1k-10
|
||||
- Fix CVE-2023-3446: Excessive time spent checking DH keys and parameters
|
||||
Resolves: RHEL-14245
|
||||
- Fix CVE-2023-3817: Excessive time spent checking DH q parameter value
|
||||
Resolves: RHEL-14239
|
||||
|
||||
* Wed Feb 08 2023 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:1.1.1k-9
|
||||
- Fixed Timing Oracle in RSA Decryption
|
||||
Resolves: CVE-2022-4304
|
||||
- Fixed Double free after calling PEM_read_bio_ex
|
||||
Resolves: CVE-2022-4450
|
||||
- Fixed Use-after-free following BIO_new_NDEF
|
||||
Resolves: CVE-2023-0215
|
||||
- Fixed X.400 address type confusion in X.509 GeneralName
|
||||
Resolves: CVE-2023-0286
|
||||
|
||||
* Thu Jul 21 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:1.1.1k-8
|
||||
- Fix no-ec build
|
||||
Resolves: rhbz#2071020
|
||||
|
||||
* Tue Jul 05 2022 Clemens Lang <cllang@redhat.com> - 1:1.1.1k-7
|
||||
- Fix CVE-2022-2097: AES OCB fails to encrypt some bytes on 32-bit x86
|
||||
Resolves: CVE-2022-2097
|
||||
- Update expired certificates used in the testsuite
|
||||
Resolves: rhbz#2092462
|
||||
- Fix CVE-2022-1292: openssl: c_rehash script allows command injection
|
||||
Resolves: rhbz#2090372
|
||||
- Fix CVE-2022-2068: the c_rehash script allows command injection
|
||||
Resolves: rhbz#2098279
|
||||
|
||||
* Wed Mar 23 2022 Clemens Lang <cllang@redhat.com> - 1:1.1.1k-6
|
||||
- Fixes CVE-2022-0778 openssl: Infinite loop in BN_mod_sqrt() reachable when parsing certificates
|
||||
- Resolves: rhbz#2067146
|
||||
- Resolves: rhbz#2067144
|
||||
|
||||
* Tue Nov 16 2021 Sahana Prasad <sahana@redhat.com> - 1:1.1.1k-5
|
||||
- Fixes CVE-2021-3712 openssl: Read buffer overruns processing ASN.1 strings
|
||||
- Resolves: rhbz#2005402
|
||||
* Fri Nov 12 2021 Sahana Prasad <sahana@redhat.com> - 1:1.1.1k-5
|
||||
- CVE-2021-3712 openssl: Read buffer overruns processing ASN.1 strings
|
||||
- Resolves: rhbz#2005400
|
||||
|
||||
* Fri Jul 16 2021 Sahana Prasad <sahana@redhat.com> - 1:1.1.1k-4
|
||||
- Fixes bugs in s390x AES code.
|
||||
|
Loading…
Reference in New Issue
Block a user