The BN_GF2m_poly2arr() function converts characteristic-2 field
(GF_{2^m}) Galois polynomials from a representation as a BIGNUM bitmask,
to a compact array with just the exponents of the non-zero terms.
These polynomials are then used in BN_GF2m_mod_arr() to perform modular
reduction. A precondition of calling BN_GF2m_mod_arr() is that the
polynomial must have a non-zero constant term (i.e. the array has `0` as
its final element).
Internally, callers of BN_GF2m_poly2arr() did not verify that
precondition, and binary EC curve parameters with an invalid polynomial
could lead to out of bounds memory reads and writes in BN_GF2m_mod_arr().
The precondition is always true for polynomials that arise from the
standard form of EC parameters for characteristic-two fields (X9.62).
See the "Finite Field Identification" section of:
https://www.itu.int/ITU-T/formal-language/itu-t/x/x894/2018-cor1/ANSI-X9-62.html
The OpenSSL GF(2^m) code supports only the trinomial and pentanomial
basis X9.62 forms.
This commit updates BN_GF2m_poly2arr() to return `0` (failure) when
the constant term is zero (i.e. the input bitmask BIGNUM is not odd).
Additionally, the return value is made unambiguous when there is not
enough space to also pad the array with a final `-1` sentinel value.
The return value is now always the number of elements (including the
final `-1`) that would be filled when the output array is sufficiently
large. Previously the same count was returned both when the array has
just enough room for the final `-1` and when it had only enough space
for non-sentinel values.
Finally, BN_GF2m_poly2arr() is updated to reject polynomials whose
degree exceeds `OPENSSL_ECC_MAX_FIELD_BITS`, this guards against
CPU exhausition attacks via excessively large inputs.
The above issues do not arise in processing X.509 certificates. These
generally have EC keys from "named curves", and RFC5840 (Section 2.1.1)
disallows explicit EC parameters. The TLS code in OpenSSL enforces this
constraint only after the certificate is decoded, but, even if explicit
parameters are specified, they are in X9.62 form, which cannot represent
problem values as noted above.
Initially reported as oss-fuzz issue 71623.
A closely related issue was earlier reported in
<https://github.com/openssl/openssl/issues/19826>.
Severity: Low, CVE-2024-9143
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Bernd Edlinger <bernd.edlinger@hotmail.de>
Reviewed-by: Paul Dale <ppzgs1@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/25639)
If p is set to 1 when calling BN_GF2m_mod_inv then an infinite loop will
result. Calling this function set 1 when applications call this directly
is a non-sensical value - so this would be considered a bug in the caller.
It does not seem possible to cause OpenSSL internal callers of
BN_GF2m_mod_inv to call it with a value of 1.
So, for the above reasons, this is not considered a security issue.
Reported by Bing Shi.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Todd Short <todd.short@me.com>
(Merged from https://github.com/openssl/openssl/pull/22960)
Since OPENSSL_malloc() and friends report ERR_R_MALLOC_FAILURE, and
at least handle the file name and line number they are called from,
there's no need to report ERR_R_MALLOC_FAILURE where they are called
directly, or when SSLfatal() and RLAYERfatal() is used, the reason
`ERR_R_MALLOC_FAILURE` is changed to `ERR_R_CRYPTO_LIB`.
There were a number of places where `ERR_R_MALLOC_FAILURE` was reported
even though it was a function from a different sub-system that was
called. Those places are changed to report ERR_R_{lib}_LIB, where
{lib} is the name of that sub-system.
Some of them are tricky to get right, as we have a lot of functions
that belong in the ASN1 sub-system, and all the `sk_` calls or from
the CRYPTO sub-system.
Some extra adaptation was necessary where there were custom OPENSSL_malloc()
wrappers, and some bugs are fixed alongside these changes.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Hugo Landau <hlandau@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/19301)
Remove unused -DCONF_DEBUG and -DBN_CTX_DEBUG.
Rename REF_PRINT to REF_DEBUG for consistency, and add a new
tracing category and use it for printing reference counts.
Rename -DDEBUG_UNUSED to -DUNUSED_RESULT_DEBUG
Fix BN_DEBUG_RAND so it compiles and, when set, force DEBUG_RAND to
be set also.
Rename engine_debug_ref to be ENGINE_REF_PRINT also for consistency.
Fixes#15357
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15353)
clean a few style nits.
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14806)
This includes error reporting for libcrypto sub-libraries in surprising
places.
This was done using util/err-to-raise
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/13318)
Also added blanks lines after declarations in a couple of places.
Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9916)
Apart from public and internal header files, there is a third type called
local header files, which are located next to source files in the source
directory. Currently, they have different suffixes like
'*_lcl.h', '*_local.h', or '*_int.h'
This commit changes the different suffixes to '*_local.h' uniformly.
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9333)
The FIPS provider does not have a default OPENSSL_CTX so, where
necessary, we need to ensure we can always access an explicit
OPENSSL_CTX. We remove functions from the FIPS provider that use
the default OPENSSL_CTX, and fixup some places which were using
those removed functions.
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/9310)
Experiments have shown that the lookup table used by BN_GF2m_mod_arr
introduces sufficient timing signal to recover the private key for an
attacker with access to cache timing information on the victim's host.
This only affects binary curves (which are less frequently used).
No CVE is considered necessary for this issue.
The fix is to replace the lookup table with an on-the-fly calculation of
the value from the table instead, which can be performed in constant time.
Thanks to Youngjoo Shin for reporting this issue.
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6270)
Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Andy Polyakov <appro@openssl.org>
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6070)
Since return is inconsistent, I removed unnecessary parentheses and
unified them.
Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/4541)
Add a new global DRBG for private keys used by RAND_priv_bytes.
Add BN_priv_rand() and BN_priv_rand_range() which use RAND_priv_bytes().
Change callers to use the appropriate BN_priv... function.
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/4076)
To make it consistent in the code base
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Bernd Edlinger <bernd.edlinger@hotmail.de>
(Merged from https://github.com/openssl/openssl/pull/3749)
This was done by the following
find . -name '*.[ch]' | /tmp/pl
where /tmp/pl is the following three-line script:
print unless $. == 1 && m@/\* .*\.[ch] \*/@;
close ARGV if eof; # Close file to reset $.
And then some hand-editing of other files.
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
There are header files in crypto/ that are used by a number of crypto/
submodules. Move those to crypto/include/internal and adapt the
affected source code and Makefiles.
The header files that got moved are:
crypto/cryptolib.h
crypto/md32_common.h
Reviewed-by: Rich Salz <rsalz@openssl.org>
For a local variable:
TYPE *p;
Allocations like this are "risky":
p = OPENSSL_malloc(sizeof(TYPE));
if the type of p changes, and the malloc call isn't updated, you
could get memory corruption. Instead do this:
p = OPENSSL_malloc(sizeof(*p));
Also fixed a few memset() calls that I noticed while doing this.
Reviewed-by: Richard Levitte <levitte@openssl.org>
Exact improvement coefficients vary from one benchmark and platform to
another, e.g. it performs 70%-33% better on ARM, hereafter less for
longer keys, and 100%-90% better on x86_64.