git: 0904c29a0a11 - stable/13 - OpenSSL: Merge OpenSSL 1.1.1t
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 07 Feb 2023 22:40:53 UTC
The branch stable/13 has been updated by jkim:
URL: https://cgit.FreeBSD.org/src/commit/?id=0904c29a0a116eb7d67a2d35d926580a65f0ddfb
commit 0904c29a0a116eb7d67a2d35d926580a65f0ddfb
Author: Jung-uk Kim <jkim@FreeBSD.org>
AuthorDate: 2023-02-07 18:51:38 +0000
Commit: Jung-uk Kim <jkim@FreeBSD.org>
CommitDate: 2023-02-07 22:38:40 +0000
OpenSSL: Merge OpenSSL 1.1.1t
(cherry picked from commit 640242a5915761ce63205bdb0542fa3c1473c0ff)
---
crypto/openssl/CHANGES | 76 ++-
crypto/openssl/Configure | 18 +-
crypto/openssl/NEWS | 7 +
crypto/openssl/README | 2 +-
crypto/openssl/crypto/asn1/asn_mime.c | 6 +-
crypto/openssl/crypto/asn1/bio_asn1.c | 4 +-
crypto/openssl/crypto/asn1/bio_ndef.c | 41 +-
crypto/openssl/crypto/bio/b_print.c | 22 +-
crypto/openssl/crypto/bn/bn_blind.c | 16 +-
crypto/openssl/crypto/bn/bn_err.c | 4 +-
crypto/openssl/crypto/bn/bn_exp.c | 36 +-
crypto/openssl/crypto/bn/bn_local.h | 36 +-
crypto/openssl/crypto/bn/bn_mont.c | 4 +-
crypto/openssl/crypto/bn/build.info | 3 +-
crypto/openssl/crypto/bn/rsa_sup_mul.c | 614 +++++++++++++++++++++++++
crypto/openssl/crypto/cms/cms_enc.c | 5 +
crypto/openssl/crypto/cms/cms_err.c | 2 +
crypto/openssl/crypto/err/openssl.txt | 5 +-
crypto/openssl/crypto/evp/bio_enc.c | 9 +-
crypto/openssl/crypto/pem/pem_lib.c | 8 +-
crypto/openssl/crypto/rsa/rsa_ameth.c | 1 +
crypto/openssl/crypto/rsa/rsa_ossl.c | 19 +-
crypto/openssl/crypto/txt_db/txt_db.c | 4 +-
crypto/openssl/crypto/x509/by_dir.c | 18 +-
crypto/openssl/crypto/x509/x_name.c | 8 +-
crypto/openssl/crypto/x509v3/v3_genn.c | 4 +-
crypto/openssl/engines/asm/e_padlock-x86.pl | 4 +-
crypto/openssl/engines/asm/e_padlock-x86_64.pl | 4 +-
crypto/openssl/include/crypto/bn.h | 7 +-
crypto/openssl/include/openssl/bnerr.h | 3 +-
crypto/openssl/include/openssl/cmserr.h | 1 +
crypto/openssl/include/openssl/opensslv.h | 4 +-
crypto/openssl/include/openssl/x509v3.h | 4 +-
crypto/openssl/ssl/record/rec_layer_s3.c | 26 +-
crypto/openssl/ssl/record/ssl3_buffer.c | 9 +-
35 files changed, 938 insertions(+), 96 deletions(-)
diff --git a/crypto/openssl/CHANGES b/crypto/openssl/CHANGES
index 882dd2034efe..459605bf71b6 100644
--- a/crypto/openssl/CHANGES
+++ b/crypto/openssl/CHANGES
@@ -7,11 +7,85 @@
https://github.com/openssl/openssl/commits/ and pick the appropriate
release branch.
+ Changes between 1.1.1s and 1.1.1t [7 Feb 2023]
+
+ *) Fixed X.400 address type confusion in X.509 GeneralName.
+
+ There is a type confusion vulnerability relating to X.400 address processing
+ inside an X.509 GeneralName. X.400 addresses were parsed as an ASN1_STRING
+ but subsequently interpreted by GENERAL_NAME_cmp as an ASN1_TYPE. This
+ vulnerability may allow an attacker who can provide a certificate chain and
+ CRL (neither of which need have a valid signature) to pass arbitrary
+ pointers to a memcmp call, creating a possible read primitive, subject to
+ some constraints. Refer to the advisory for more information. Thanks to
+ David Benjamin for discovering this issue. (CVE-2023-0286)
+
+ This issue has been fixed by changing the public header file definition of
+ GENERAL_NAME so that x400Address reflects the implementation. It was not
+ possible for any existing application to successfully use the existing
+ definition; however, if any application references the x400Address field
+ (e.g. in dead code), note that the type of this field has changed. There is
+ no ABI change.
+ [Hugo Landau]
+
+ *) Fixed Use-after-free following BIO_new_NDEF.
+
+ The public API function BIO_new_NDEF is a helper function used for
+ streaming ASN.1 data via a BIO. It is primarily used internally to OpenSSL
+ to support the SMIME, CMS and PKCS7 streaming capabilities, but may also
+ be called directly by end user applications.
+
+ The function receives a BIO from the caller, prepends a new BIO_f_asn1
+ filter BIO onto the front of it to form a BIO chain, and then returns
+ the new head of the BIO chain to the caller. Under certain conditions,
+ for example if a CMS recipient public key is invalid, the new filter BIO
+ is freed and the function returns a NULL result indicating a failure.
+ However, in this case, the BIO chain is not properly cleaned up and the
+ BIO passed by the caller still retains internal pointers to the previously
+ freed filter BIO. If the caller then goes on to call BIO_pop() on the BIO
+ then a use-after-free will occur. This will most likely result in a crash.
+ (CVE-2023-0215)
+ [Viktor Dukhovni, Matt Caswell]
+
+ *) Fixed Double free after calling PEM_read_bio_ex.
+
+ The function PEM_read_bio_ex() reads a PEM file from a BIO and parses and
+ decodes the "name" (e.g. "CERTIFICATE"), any header data and the payload
+ data. If the function succeeds then the "name_out", "header" and "data"
+ arguments are populated with pointers to buffers containing the relevant
+ decoded data. The caller is responsible for freeing those buffers. It is
+ possible to construct a PEM file that results in 0 bytes of payload data.
+ In this case PEM_read_bio_ex() will return a failure code but will populate
+ the header argument with a pointer to a buffer that has already been freed.
+ If the caller also frees this buffer then a double free will occur. This
+ will most likely lead to a crash.
+
+ The functions PEM_read_bio() and PEM_read() are simple wrappers around
+ PEM_read_bio_ex() and therefore these functions are also directly affected.
+
+ These functions are also called indirectly by a number of other OpenSSL
+ functions including PEM_X509_INFO_read_bio_ex() and
+ SSL_CTX_use_serverinfo_file() which are also vulnerable. Some OpenSSL
+ internal uses of these functions are not vulnerable because the caller does
+ not free the header argument if PEM_read_bio_ex() returns a failure code.
+ (CVE-2022-4450)
+ [Kurt Roeckx, Matt Caswell]
+
+ *) Fixed 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.
+ (CVE-2022-4304)
+ [Dmitry Belyavsky, Hubert Kario]
+
Changes between 1.1.1r and 1.1.1s [1 Nov 2022]
*) Fixed a regression introduced in 1.1.1r version not refreshing the
certificate data to be signed before signing the certificate.
-
[Gibeom Gwon]
Changes between 1.1.1q and 1.1.1r [11 Oct 2022]
diff --git a/crypto/openssl/Configure b/crypto/openssl/Configure
index 92e59b9ce7a6..37a99d14715c 100755
--- a/crypto/openssl/Configure
+++ b/crypto/openssl/Configure
@@ -1,6 +1,6 @@
#! /usr/bin/env perl
# -*- mode: perl; -*-
-# Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2016-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
@@ -1217,7 +1217,7 @@ $target{build_scheme} = [ $target{build_scheme} ]
my ($builder, $builder_platform, @builder_opts) =
@{$target{build_scheme}};
-foreach my $checker (($builder_platform."-".$target{build_file}."-checker.pm",
+foreach my $checker (($builder_platform."-".$config{build_file}."-checker.pm",
$builder_platform."-checker.pm")) {
my $checker_path = catfile($srcdir, "Configurations", $checker);
if (-f $checker_path) {
@@ -1741,8 +1741,8 @@ if ($builder eq "unified") {
# Store the name of the template file we will build the build file from
# in %config. This may be useful for the build file itself.
my @build_file_template_names =
- ( $builder_platform."-".$target{build_file}.".tmpl",
- $target{build_file}.".tmpl" );
+ ( $builder_platform."-".$config{build_file}.".tmpl",
+ $config{build_file}.".tmpl" );
my @build_file_templates = ();
# First, look in the user provided directory, if given
@@ -1966,8 +1966,8 @@ if ($builder eq "unified") {
}
next if @skip && $skip[$#skip] <= 0;
push @rawlines, $_
- if ($target_kind eq $target{build_file}
- || $target_kind eq $target{build_file}."(".$builder_platform.")");
+ if ($target_kind eq $config{build_file}
+ || $target_kind eq $config{build_file}."(".$builder_platform.")");
}
},
qr/^\s*(?:#.*)?$/ => sub { },
@@ -2842,8 +2842,8 @@ if ($builder_platform eq 'unix') {
my %builders = (
unified => sub {
- print 'Creating ',$target{build_file},"\n";
- run_dofile(catfile($blddir, $target{build_file}),
+ print 'Creating ',$config{build_file},"\n";
+ run_dofile(catfile($blddir, $config{build_file}),
@{$config{build_file_templates}});
},
);
@@ -2897,7 +2897,7 @@ exit(0);
#
sub death_handler {
die @_ if $^S; # To prevent the added message in eval blocks
- my $build_file = $target{build_file} // "build file";
+ my $build_file = $config{build_file} // "build file";
my @message = ( <<"_____", @_ );
Failure! $build_file wasn't produced.
diff --git a/crypto/openssl/NEWS b/crypto/openssl/NEWS
index c9e63eea63a6..2724fc4d85ba 100644
--- a/crypto/openssl/NEWS
+++ b/crypto/openssl/NEWS
@@ -5,6 +5,13 @@
This file gives a brief overview of the major changes between each OpenSSL
release. For more details please read the CHANGES file.
+ Major changes between OpenSSL 1.1.1s and OpenSSL 1.1.1t [7 Feb 2023]
+
+ o Fixed X.400 address type confusion in X.509 GeneralName (CVE-2023-0286)
+ o Fixed Use-after-free following BIO_new_NDEF (CVE-2023-0215)
+ o Fixed Double free after calling PEM_read_bio_ex (CVE-2022-4450)
+ o Fixed Timing Oracle in RSA Decryption (CVE-2022-4304)
+
Major changes between OpenSSL 1.1.1r and OpenSSL 1.1.1s [1 Nov 2022]
o Fixed a regression introduced in OpenSSL 1.1.1r not refreshing the
diff --git a/crypto/openssl/README b/crypto/openssl/README
index 2f6d91c6337c..b2f806be3a44 100644
--- a/crypto/openssl/README
+++ b/crypto/openssl/README
@@ -1,5 +1,5 @@
- OpenSSL 1.1.1s 1 Nov 2022
+ OpenSSL 1.1.1t 7 Feb 2023
Copyright (c) 1998-2022 The OpenSSL Project
Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
diff --git a/crypto/openssl/crypto/asn1/asn_mime.c b/crypto/openssl/crypto/asn1/asn_mime.c
index 38735cd86f3e..36853612b69c 100644
--- a/crypto/openssl/crypto/asn1/asn_mime.c
+++ b/crypto/openssl/crypto/asn1/asn_mime.c
@@ -489,6 +489,7 @@ int SMIME_crlf_copy(BIO *in, BIO *out, int flags)
char eol;
int len;
char linebuf[MAX_SMLEN];
+ int ret;
/*
* Buffer output so we don't write one line at a time. This is useful
* when streaming as we don't end up with one OCTET STRING per line.
@@ -523,9 +524,12 @@ int SMIME_crlf_copy(BIO *in, BIO *out, int flags)
BIO_write(out, "\r\n", 2);
}
}
- (void)BIO_flush(out);
+ ret = BIO_flush(out);
BIO_pop(out);
BIO_free(bf);
+ if (ret <= 0)
+ return 0;
+
return 1;
}
diff --git a/crypto/openssl/crypto/asn1/bio_asn1.c b/crypto/openssl/crypto/asn1/bio_asn1.c
index 914d77c866c6..17b0d1aa6cad 100644
--- a/crypto/openssl/crypto/asn1/bio_asn1.c
+++ b/crypto/openssl/crypto/asn1/bio_asn1.c
@@ -172,7 +172,7 @@ static int asn1_bio_write(BIO *b, const char *in, int inl)
case ASN1_STATE_START:
if (!asn1_bio_setup_ex(b, ctx, ctx->prefix,
ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER))
- return 0;
+ return -1;
break;
/* Copy any pre data first */
@@ -189,7 +189,7 @@ static int asn1_bio_write(BIO *b, const char *in, int inl)
case ASN1_STATE_HEADER:
ctx->buflen = ASN1_object_size(0, inl, ctx->asn1_tag) - inl;
if (!ossl_assert(ctx->buflen <= ctx->bufsize))
- return 0;
+ return -1;
p = ctx->buf;
ASN1_put_object(&p, 0, inl, ctx->asn1_tag, ctx->asn1_class);
ctx->copylen = inl;
diff --git a/crypto/openssl/crypto/asn1/bio_ndef.c b/crypto/openssl/crypto/asn1/bio_ndef.c
index 760e4846a474..c8a776b482d0 100644
--- a/crypto/openssl/crypto/asn1/bio_ndef.c
+++ b/crypto/openssl/crypto/asn1/bio_ndef.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2008-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
@@ -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;
diff --git a/crypto/openssl/crypto/bio/b_print.c b/crypto/openssl/crypto/bio/b_print.c
index 41b7f5e2f61d..45d4e9f004b1 100644
--- a/crypto/openssl/crypto/bio/b_print.c
+++ b/crypto/openssl/crypto/bio/b_print.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2020 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
@@ -13,6 +13,7 @@
#include "crypto/ctype.h"
#include "internal/numbers.h"
#include <openssl/bio.h>
+#include <openssl/opensslconf.h>
/*
* Copyright Patrick Powell 1995
@@ -31,8 +32,10 @@ static int fmtstr(char **, char **, size_t *, size_t *,
const char *, int, int, int);
static int fmtint(char **, char **, size_t *, size_t *,
int64_t, int, int, int, int);
+#ifndef OPENSSL_SYS_UEFI
static int fmtfp(char **, char **, size_t *, size_t *,
LDOUBLE, int, int, int, int);
+#endif
static int doapr_outch(char **, char **, size_t *, size_t *, int);
static int _dopr(char **sbuffer, char **buffer,
size_t *maxlen, size_t *retlen, int *truncated,
@@ -88,7 +91,9 @@ _dopr(char **sbuffer,
{
char ch;
int64_t value;
+#ifndef OPENSSL_SYS_UEFI
LDOUBLE fvalue;
+#endif
char *strvalue;
int min;
int max;
@@ -259,6 +264,7 @@ _dopr(char **sbuffer,
min, max, flags))
return 0;
break;
+#ifndef OPENSSL_SYS_UEFI
case 'f':
if (cflags == DP_C_LDOUBLE)
fvalue = va_arg(args, LDOUBLE);
@@ -292,6 +298,16 @@ _dopr(char **sbuffer,
flags, G_FORMAT))
return 0;
break;
+#else
+ case 'f':
+ case 'E':
+ case 'e':
+ case 'G':
+ case 'g':
+ /* not implemented for UEFI */
+ ERR_raise(ERR_LIB_BIO, ERR_R_UNSUPPORTED);
+ return 0;
+#endif
case 'c':
if (!doapr_outch(sbuffer, buffer, &currlen, maxlen,
va_arg(args, int)))
@@ -512,6 +528,8 @@ fmtint(char **sbuffer,
return 1;
}
+#ifndef OPENSSL_SYS_UEFI
+
static LDOUBLE abs_val(LDOUBLE value)
{
LDOUBLE result = value;
@@ -803,6 +821,8 @@ fmtfp(char **sbuffer,
return 1;
}
+#endif /* OPENSSL_SYS_UEFI */
+
#define BUFFER_INC 1024
static int
diff --git a/crypto/openssl/crypto/bn/bn_blind.c b/crypto/openssl/crypto/bn/bn_blind.c
index 76fc7ebcffc0..dd5beea7c93e 100644
--- a/crypto/openssl/crypto/bn/bn_blind.c
+++ b/crypto/openssl/crypto/bn/bn_blind.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1998-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1998-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
@@ -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/openssl/crypto/bn/bn_err.c b/crypto/openssl/crypto/bn/bn_err.c
index dd87c152cf37..6f5464b54054 100644
--- a/crypto/openssl/crypto/bn/bn_err.c
+++ b/crypto/openssl/crypto/bn/bn_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
@@ -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/openssl/crypto/bn/bn_exp.c b/crypto/openssl/crypto/bn/bn_exp.c
index e21dcff027c5..517e3c29fc70 100644
--- a/crypto/openssl/crypto/bn/bn_exp.c
+++ b/crypto/openssl/crypto/bn/bn_exp.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2022 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
@@ -37,6 +37,15 @@ extern unsigned int OPENSSL_sparcv9cap_P[];
/* maximum precomputation table size for *variable* sliding windows */
#define TABLE_SIZE 32
+/*
+ * Beyond this limit the constant time code is disabled due to
+ * the possible overflow in the computation of powerbufLen in
+ * BN_mod_exp_mont_consttime.
+ * When this limit is exceeded, the computation will be done using
+ * non-constant time code, but it will take very long.
+ */
+#define BN_CONSTTIME_SIZE_LIMIT (INT_MAX / BN_BYTES / 256)
+
/* this one works - simple but works */
int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
{
@@ -305,12 +314,6 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
BIGNUM *val[TABLE_SIZE];
BN_MONT_CTX *mont = NULL;
- if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0
- || BN_get_flags(a, BN_FLG_CONSTTIME) != 0
- || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) {
- return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont);
- }
-
bn_check_top(a);
bn_check_top(p);
bn_check_top(m);
@@ -319,6 +322,14 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
BNerr(BN_F_BN_MOD_EXP_MONT, BN_R_CALLED_WITH_EVEN_MODULUS);
return 0;
}
+
+ if (m->top <= BN_CONSTTIME_SIZE_LIMIT
+ && (BN_get_flags(p, BN_FLG_CONSTTIME) != 0
+ || BN_get_flags(a, BN_FLG_CONSTTIME) != 0
+ || BN_get_flags(m, BN_FLG_CONSTTIME) != 0)) {
+ return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont);
+ }
+
bits = BN_num_bits(p);
if (bits == 0) {
/* x**0 mod 1, or x**0 mod -1 is still zero. */
@@ -618,6 +629,11 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
top = m->top;
+ if (top > BN_CONSTTIME_SIZE_LIMIT) {
+ /* Prevent overflowing the powerbufLen computation below */
+ return BN_mod_exp_mont(rr, a, p, m, ctx, in_mont);
+ }
+
/*
* Use all bits stored in |p|, rather than |BN_num_bits|, so we do not leak
* whether the top bits are zero.
@@ -697,7 +713,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
else
#endif
#if defined(OPENSSL_BN_ASM_MONT5)
- if (window >= 5) {
+ if (window >= 5 && top <= BN_SOFT_LIMIT) {
window = 5; /* ~5% improvement for RSA2048 sign, and even
* for RSA4096 */
/* reserve space for mont->N.d[] copy */
@@ -758,6 +774,9 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
if (!bn_to_mont_fixed_top(&am, a, mont, ctx))
goto err;
+ if (top > BN_SOFT_LIMIT)
+ goto fallback;
+
#if defined(SPARC_T4_MONT)
if (t4) {
typedef int (*bn_pwr5_mont_f) (BN_ULONG *tp, const BN_ULONG *np,
@@ -1029,6 +1048,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
} else
#endif
{
+ fallback:
if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 0, window))
goto err;
if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&am, top, powerbuf, 1, window))
diff --git a/crypto/openssl/crypto/bn/bn_local.h b/crypto/openssl/crypto/bn/bn_local.h
index 8ad69ccd3639..30b7614fdbb2 100644
--- a/crypto/openssl/crypto/bn/bn_local.h
+++ b/crypto/openssl/crypto/bn/bn_local.h
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2020 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
@@ -35,6 +35,26 @@
/* #define BN_DEBUG */
/* #define BN_DEBUG_RAND */
+/*
+ * This should limit the stack usage due to alloca to about 4K.
+ * BN_SOFT_LIMIT is a soft limit equivalent to 2*OPENSSL_RSA_MAX_MODULUS_BITS.
+ * Beyond that size bn_mul_mont is no longer used, and the constant time
+ * assembler code is disabled, due to the blatant alloca and bn_mul_mont usage.
+ * Note that bn_mul_mont does an alloca that is hidden away in assembly.
+ * It is not recommended to do computations with numbers exceeding this limit,
+ * since the result will be highly version dependent:
+ * While the current OpenSSL version will use non-optimized, but safe code,
+ * previous versions will use optimized code, that may crash due to unexpected
+ * stack overflow, and future versions may very well turn this into a hard
+ * limit.
+ * Note however, that it is possible to override the size limit using
+ * "./config -DBN_SOFT_LIMIT=<limit>" if necessary, and the O/S specific
+ * stack limit is known and taken into consideration.
+ */
+# ifndef BN_SOFT_LIMIT
+# define BN_SOFT_LIMIT (4096 / BN_BYTES)
+# endif
+
# ifndef OPENSSL_SMALL_FOOTPRINT
# define BN_MUL_COMBA
# define BN_SQR_COMBA
@@ -263,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/openssl/crypto/bn/bn_mont.c b/crypto/openssl/crypto/bn/bn_mont.c
index 1e5045a010bb..7617b0df5e70 100644
--- a/crypto/openssl/crypto/bn/bn_mont.c
+++ b/crypto/openssl/crypto/bn/bn_mont.c
@@ -1,5 +1,5 @@
/*
- * 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
@@ -42,7 +42,7 @@ int bn_mul_mont_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
int num = mont->N.top;
#if defined(OPENSSL_BN_ASM_MONT) && defined(MONT_WORD)
- if (num > 1 && a->top == num && b->top == num) {
+ if (num > 1 && num <= BN_SOFT_LIMIT && a->top == num && b->top == num) {
if (bn_wexpand(r, num) == NULL)
return 0;
if (bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) {
diff --git a/crypto/openssl/crypto/bn/build.info b/crypto/openssl/crypto/bn/build.info
index b9ed5322fa68..c9fe2fdada69 100644
--- a/crypto/openssl/crypto/bn/build.info
+++ b/crypto/openssl/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/openssl/crypto/bn/rsa_sup_mul.c b/crypto/openssl/crypto/bn/rsa_sup_mul.c
new file mode 100644
index 000000000000..acafefd5febf
--- /dev/null
+++ b/crypto/openssl/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
+ }
+}
+
*** 834 LINES SKIPPED ***