From 0d51f658515c605fcc4a8073cb5a8e0d7d904088 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Tue, 7 Feb 2023 12:05:11 -0500 Subject: [PATCH] Import OpenSSL 1.1.1t --- CHANGES | 76 +++- Configure | 18 +- NEWS | 7 + README | 2 +- crypto/asn1/asn_mime.c | 6 +- crypto/asn1/bio_asn1.c | 4 +- crypto/asn1/bio_ndef.c | 41 ++- crypto/bio/b_print.c | 22 +- crypto/bn/bn_blind.c | 16 +- crypto/bn/bn_err.c | 4 +- crypto/bn/bn_exp.c | 36 +- crypto/bn/bn_local.h | 36 +- crypto/bn/bn_mont.c | 4 +- crypto/bn/build.info | 3 +- crypto/bn/rsa_sup_mul.c | 614 ++++++++++++++++++++++++++++++++ crypto/cms/cms_enc.c | 5 + crypto/cms/cms_err.c | 2 + crypto/err/openssl.txt | 5 +- crypto/evp/bio_enc.c | 9 +- crypto/pem/pem_lib.c | 8 +- crypto/rsa/rsa_ameth.c | 1 + crypto/rsa/rsa_ossl.c | 19 +- crypto/txt_db/txt_db.c | 4 +- crypto/x509/by_dir.c | 18 +- crypto/x509/x_name.c | 8 +- crypto/x509v3/v3_genn.c | 4 +- engines/asm/e_padlock-x86.pl | 4 +- engines/asm/e_padlock-x86_64.pl | 4 +- include/crypto/bn.h | 7 +- include/openssl/bnerr.h | 3 +- include/openssl/cmserr.h | 1 + include/openssl/opensslv.h | 4 +- include/openssl/x509v3.h | 4 +- ssl/record/rec_layer_s3.c | 17 +- ssl/record/ssl3_buffer.c | 9 +- 35 files changed, 934 insertions(+), 91 deletions(-) create mode 100644 crypto/bn/rsa_sup_mul.c diff --git a/CHANGES b/CHANGES index 979170072d17..1e2d651b7514 100644 --- a/CHANGES +++ b/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/Configure b/Configure index 4bea49d7da76..6cb1a84f4b7f 100755 --- a/Configure +++ b/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 @@ -1215,7 +1215,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) { @@ -1712,8 +1712,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 @@ -1937,8 +1937,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 { }, @@ -2813,8 +2813,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}}); }, ); @@ -2868,7 +2868,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/NEWS b/NEWS index c9e63eea63a6..2724fc4d85ba 100644 --- a/NEWS +++ b/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/README b/README index 2f6d91c6337c..b2f806be3a44 100644 --- a/README +++ b/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/asn1/asn_mime.c b/crypto/asn1/asn_mime.c index 38735cd86f3e..36853612b69c 100644 --- a/crypto/asn1/asn_mime.c +++ b/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/asn1/bio_asn1.c b/crypto/asn1/bio_asn1.c index 914d77c866c6..17b0d1aa6cad 100644 --- a/crypto/asn1/bio_asn1.c +++ b/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/asn1/bio_ndef.c b/crypto/asn1/bio_ndef.c index 760e4846a474..c8a776b482d0 100644 --- a/crypto/asn1/bio_ndef.c +++ b/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/bio/b_print.c b/crypto/bio/b_print.c index 41b7f5e2f61d..45d4e9f004b1 100644 --- a/crypto/bio/b_print.c +++ b/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 +#include /* * 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/bn/bn_blind.c b/crypto/bn/bn_blind.c index 76fc7ebcffc0..dd5beea7c93e 100644 --- a/crypto/bn/bn_blind.c +++ b/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/bn/bn_err.c b/crypto/bn/bn_err.c index dd87c152cf37..6f5464b54054 100644 --- a/crypto/bn/bn_err.c +++ b/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/bn/bn_exp.c b/crypto/bn/bn_exp.c index e21dcff027c5..517e3c29fc70 100644 --- a/crypto/bn/bn_exp.c +++ b/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/bn/bn_local.h b/crypto/bn/bn_local.h index 8ad69ccd3639..30b7614fdbb2 100644 --- a/crypto/bn/bn_local.h +++ b/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=" 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/bn/bn_mont.c b/crypto/bn/bn_mont.c index 1e5045a010bb..7617b0df5e70 100644 --- a/crypto/bn/bn_mont.c +++ b/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/bn/build.info b/crypto/bn/build.info index b9ed5322fa68..c9fe2fdada69 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 000000000000..acafefd5febf --- /dev/null +++ b/crypto/bn/rsa_sup_mul.c @@ -0,0 +1,614 @@ +#include +#include +#include +#include +#include +#include +#include +#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 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/cms/cms_enc.c b/crypto/cms/cms_enc.c index fc490303d4c6..6f077b339a87 100644 --- a/crypto/cms/cms_enc.c +++ b/crypto/cms/cms_enc.c @@ -68,7 +68,12 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) if (enc) { int ivlen; + calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx)); + if (calg->algorithm == NULL) { + CMSerr(ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM); + goto err; + } /* Generate a random IV if we need one */ ivlen = EVP_CIPHER_CTX_iv_length(ctx); if (ivlen > 0) { diff --git a/crypto/cms/cms_err.c b/crypto/cms/cms_err.c index a211f4954ce1..408fe13b87d9 100644 --- a/crypto/cms/cms_err.c +++ b/crypto/cms/cms_err.c @@ -264,6 +264,8 @@ static const ERR_STRING_DATA CMS_str_reasons[] = { {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNKNOWN_ID), "unknown id"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM), "unsupported compression algorithm"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM), + "unsupported content encryption algorithm"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_CONTENT_TYPE), "unsupported content type"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_KEK_ALGORITHM), diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 902e97b84355..ba3a46d5b988 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 @@ -2023,6 +2024,8 @@ CMS_R_UNKNOWN_CIPHER:148:unknown cipher CMS_R_UNKNOWN_DIGEST_ALGORITHM:149:unknown digest algorithm CMS_R_UNKNOWN_ID:150:unknown id CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM:151:unsupported compression algorithm +CMS_R_UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM:194:\ + unsupported content encryption algorithm CMS_R_UNSUPPORTED_CONTENT_TYPE:152:unsupported content type CMS_R_UNSUPPORTED_KEK_ALGORITHM:153:unsupported kek algorithm CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM:179:\ diff --git a/crypto/evp/bio_enc.c b/crypto/evp/bio_enc.c index 6639061eae9a..9afce7c08409 100644 --- a/crypto/evp/bio_enc.c +++ b/crypto/evp/bio_enc.c @@ -299,6 +299,7 @@ static long enc_ctrl(BIO *b, int cmd, long num, void *ptr) int i; EVP_CIPHER_CTX **c_ctx; BIO *next; + int pend; ctx = BIO_get_data(b); next = BIO_next(b); @@ -334,8 +335,14 @@ static long enc_ctrl(BIO *b, int cmd, long num, void *ptr) /* do a final write */ again: while (ctx->buf_len != ctx->buf_off) { + pend = ctx->buf_len - ctx->buf_off; i = enc_write(b, NULL, 0); - if (i < 0) + /* + * i should never be > 0 here because we didn't ask to write any + * new data. We stop if we get an error or we failed to make any + * progress writing pending data. + */ + if (i < 0 || (ctx->buf_len - ctx->buf_off) == pend) return i; } diff --git a/crypto/pem/pem_lib.c b/crypto/pem/pem_lib.c index aae42d98d297..14f9ca4aa4d6 100644 --- a/crypto/pem/pem_lib.c +++ b/crypto/pem/pem_lib.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 @@ -791,7 +791,7 @@ static int get_header_and_data(BIO *bp, BIO **header, BIO **data, char *name, { BIO *tmp = *header; char *linebuf, *p; - int len, line, ret = 0, end = 0, prev_partial_line_read = 0, partial_line_read = 0; + int len, ret = 0, end = 0, prev_partial_line_read = 0, partial_line_read = 0; /* 0 if not seen (yet), 1 if reading header, 2 if finished header */ enum header_status got_header = MAYBE_HEADER; unsigned int flags_mask; @@ -805,7 +805,7 @@ static int get_header_and_data(BIO *bp, BIO **header, BIO **data, char *name, return 0; } - for (line = 0; ; line++) { + for (;;) { flags_mask = ~0u; len = BIO_gets(bp, linebuf, LINESIZE); if (len <= 0) { @@ -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); diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c index fb045544a832..2c9c46ea53c8 100644 --- a/crypto/rsa/rsa_ameth.c +++ b/crypto/rsa/rsa_ameth.c @@ -172,6 +172,7 @@ static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) strtype, str, rk, rklen)) { RSAerr(RSA_F_RSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); ASN1_STRING_free(str); + OPENSSL_clear_free(rk, rklen); return 0; } diff --git a/crypto/rsa/rsa_ossl.c b/crypto/rsa/rsa_ossl.c index b52a66f6a628..2e3ee4ab33dc 100644 --- a/crypto/rsa/rsa_ossl.c +++ b/crypto/rsa/rsa_ossl.c @@ -1,5 +1,5 @@ /* - * 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 @@ -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/crypto/txt_db/txt_db.c b/crypto/txt_db/txt_db.c index c4e1782514d8..cbb81905ac81 100644 --- a/crypto/txt_db/txt_db.c +++ b/crypto/txt_db/txt_db.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 @@ -21,7 +21,6 @@ TXT_DB *TXT_DB_read(BIO *in, int num) { TXT_DB *ret = NULL; int esc = 0; - long ln = 0; int i, add, n; int size = BUFSIZE; int offset = 0; @@ -61,7 +60,6 @@ TXT_DB *TXT_DB_read(BIO *in, int num) } buf->data[offset] = '\0'; BIO_gets(in, &(buf->data[offset]), size - offset); - ln++; if (buf->data[offset] == '\0') break; if ((offset == 0) && (buf->data[0] == '#')) diff --git a/crypto/x509/by_dir.c b/crypto/x509/by_dir.c index 238c2519a6e2..46a861e90de0 100644 --- a/crypto/x509/by_dir.c +++ b/crypto/x509/by_dir.c @@ -1,5 +1,5 @@ /* - * 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 @@ -332,9 +332,13 @@ static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, j); X509_STORE_unlock(xl->store_ctx); - /* If a CRL, update the last file suffix added for this */ - - if (type == X509_LU_CRL) { + /* + * If a CRL, update the last file suffix added for this. + * We don't need to add an entry if k is 0 as this is the initial value. + * This avoids the need for a write lock and sort operation in the + * simple case where no CRL is present for a hash. + */ + if (type == X509_LU_CRL && k > 0) { CRYPTO_THREAD_write_lock(ctx->lock); /* * Look for entry again in case another thread added an entry @@ -362,6 +366,12 @@ static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, ok = 0; goto finish; } + + /* + * Ensure stack is sorted so that subsequent sk_BY_DIR_HASH_find + * will not mutate the stack and therefore require a write lock. + */ + sk_BY_DIR_HASH_sort(ent->hashes); } else if (hent->suffix < k) { hent->suffix = k; } diff --git a/crypto/x509/x_name.c b/crypto/x509/x_name.c index 59ac6895bc26..dc4a494fb543 100644 --- a/crypto/x509/x_name.c +++ b/crypto/x509/x_name.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 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 @@ -493,9 +493,7 @@ int X509_NAME_set(X509_NAME **xn, X509_NAME *name) int X509_NAME_print(BIO *bp, const X509_NAME *name, int obase) { char *s, *c, *b; - int l, i; - - l = 80 - 2 - obase; + int i; b = X509_NAME_oneline(name, NULL, 0); if (!b) @@ -521,12 +519,10 @@ int X509_NAME_print(BIO *bp, const X509_NAME *name, int obase) if (BIO_write(bp, ", ", 2) != 2) goto err; } - l--; } if (*s == '\0') break; s++; - l--; } OPENSSL_free(b); diff --git a/crypto/x509v3/v3_genn.c b/crypto/x509v3/v3_genn.c index 87a5eff47cd9..fd307c43cf20 100644 --- a/crypto/x509v3/v3_genn.c +++ b/crypto/x509v3/v3_genn.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2020 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 @@ -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/engines/asm/e_padlock-x86.pl b/engines/asm/e_padlock-x86.pl index 5b097ce3ef9b..7d5c92d98ce3 100644 --- a/engines/asm/e_padlock-x86.pl +++ b/engines/asm/e_padlock-x86.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2011-2018 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2011-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 @@ -116,6 +116,8 @@ $chunk="ebx"; &function_begin_B("padlock_key_bswap"); &mov ("edx",&wparam(0)); &mov ("ecx",&DWP(240,"edx")); + &inc ("ecx"); + &shl ("ecx",2); &set_label("bswap_loop"); &mov ("eax",&DWP(0,"edx")); &bswap ("eax"); diff --git a/engines/asm/e_padlock-x86_64.pl b/engines/asm/e_padlock-x86_64.pl index 09b0aaa48dfe..f60bec1e7d5d 100644 --- a/engines/asm/e_padlock-x86_64.pl +++ b/engines/asm/e_padlock-x86_64.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2011-2018 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2011-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 @@ -92,6 +92,8 @@ padlock_capability: .align 16 padlock_key_bswap: mov 240($arg1),%edx + inc %edx + shl \$2,%edx .Lbswap_loop: mov ($arg1),%eax bswap %eax diff --git a/include/crypto/bn.h b/include/crypto/bn.h index 60afda1dadee..9f866ed71abf 100644 --- a/include/crypto/bn.h +++ b/include/crypto/bn.h @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2014-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 @@ -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 9f3c7cfaab67..5c83777f9f06 100644 --- a/include/openssl/bnerr.h +++ b/include/openssl/bnerr.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 @@ -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. diff --git a/include/openssl/cmserr.h b/include/openssl/cmserr.h index 7dbc13dc939e..d589f592c805 100644 --- a/include/openssl/cmserr.h +++ b/include/openssl/cmserr.h @@ -187,6 +187,7 @@ int ERR_load_CMS_strings(void); # define CMS_R_UNKNOWN_DIGEST_ALGORITHM 149 # define CMS_R_UNKNOWN_ID 150 # define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM 151 +# define CMS_R_UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM 194 # define CMS_R_UNSUPPORTED_CONTENT_TYPE 152 # define CMS_R_UNSUPPORTED_KEK_ALGORITHM 153 # define CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM 179 diff --git a/include/openssl/opensslv.h b/include/openssl/opensslv.h index fd9400a43600..7b6c212fa097 100644 --- a/include/openssl/opensslv.h +++ b/include/openssl/opensslv.h @@ -39,8 +39,8 @@ extern "C" { * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for * major minor fix final patch/beta) */ -# define OPENSSL_VERSION_NUMBER 0x1010113fL -# define OPENSSL_VERSION_TEXT "OpenSSL 1.1.1s 1 Nov 2022" +# define OPENSSL_VERSION_NUMBER 0x1010114fL +# define OPENSSL_VERSION_TEXT "OpenSSL 1.1.1t 7 Feb 2023" /*- * The macros below are to be used for shared library (.so, .dll, ...) diff --git a/include/openssl/x509v3.h b/include/openssl/x509v3.h index 90fa3592ce58..3a4f04c183e9 100644 --- a/include/openssl/x509v3.h +++ b/include/openssl/x509v3.h @@ -1,5 +1,5 @@ /* - * 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 @@ -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/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c index fe4abd672308..1db1712a0986 100644 --- a/ssl/record/rec_layer_s3.c +++ b/ssl/record/rec_layer_s3.c @@ -16,6 +16,7 @@ #include #include "record_local.h" #include "../packet_local.h" +#include "internal/cryptlib.h" #if defined(OPENSSL_SMALL_FOOTPRINT) || \ !( defined(AESNI_ASM) && ( \ @@ -983,11 +984,14 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, } /* - * Reserve some bytes for any growth that may occur during encryption. - * This will be at most one cipher block or the tag length if using - * AEAD. SSL_RT_MAX_CIPHER_BLOCK_SIZE covers either case. - */ - if (!WPACKET_reserve_bytes(thispkt, SSL_RT_MAX_CIPHER_BLOCK_SIZE, + * Reserve some bytes for any growth that may occur during encryption. If + * we are adding the MAC independently of the cipher algorithm, then the + * max encrypted overhead does not need to include an allocation for that + * MAC + */ + if (!WPACKET_reserve_bytes(thispkt, + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + - mac_size, NULL) /* * We also need next the amount of bytes written to this @@ -1037,6 +1041,9 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, /* Allocate bytes for the encryption overhead */ if (!WPACKET_get_length(thispkt, &origlen) + /* Check we allowed enough room for the encryption growth */ + || !ossl_assert(origlen + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + - mac_size >= thiswr->length) /* Encryption should never shrink the data! */ || origlen > thiswr->length || (thiswr->length > origlen diff --git a/ssl/record/ssl3_buffer.c b/ssl/record/ssl3_buffer.c index b9ba25e0c3f8..fa597c274671 100644 --- a/ssl/record/ssl3_buffer.c +++ b/ssl/record/ssl3_buffer.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 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 @@ -97,11 +97,16 @@ int ssl3_setup_write_buffer(SSL *s, size_t numwpipes, size_t len) #endif len = ssl_get_max_send_fragment(s) - + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align; + + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align + + SSL_RT_MAX_CIPHER_BLOCK_SIZE /* Explicit IV allowance */; #ifndef OPENSSL_NO_COMP if (ssl_allow_compression(s)) len += SSL3_RT_MAX_COMPRESSED_OVERHEAD; #endif + /* + * We don't need to add an allowance for eivlen here since empty + * fragments only occur when we don't have an explicit IV + */ if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) len += headerlen + align + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD; }