summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>2019-09-18 11:44:24 +0200
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>2019-09-18 12:17:16 +0200
commitc68cb02a89bc062c6b99af42d69cbb749240cf65 (patch)
tree8af455c91e5e221020fbbbd280be5e829cacb78b
parenta47da67cfe68e4a7b1c0b546bdcf71004ba703b1 (diff)
parent7e25cb9bea3993135aa8154a98032fd30fc16e1c (diff)
downloadopenssl-tizen_5.5_base_mobile_hotfix.tar.gz
openssl-tizen_5.5_base_mobile_hotfix.tar.bz2
openssl-tizen_5.5_base_mobile_hotfix.zip
Change-Id: I052187c6bd9cc55d587fd63c000608ead364e629
-rw-r--r--CHANGES42
-rwxr-xr-xConfigure4
-rw-r--r--INSTALL.DJGPP14
-rw-r--r--INSTALL.W3224
-rw-r--r--INSTALL.W6412
-rw-r--r--INSTALL.WCE13
-rw-r--r--Makefile2
-rw-r--r--NEWS15
-rw-r--r--README2
-rw-r--r--crypto/arm_arch.h2
-rw-r--r--crypto/armcap.c1
-rw-r--r--crypto/bn/Makefile4
-rw-r--r--crypto/bn/bn_lib.c122
-rw-r--r--crypto/bn_int.h3
-rw-r--r--crypto/cms/cms_env.c20
-rw-r--r--crypto/cms/cms_lcl.h4
-rw-r--r--crypto/cms/cms_smime.c6
-rw-r--r--crypto/constant_time_locl.h22
-rw-r--r--crypto/cryptlib.h2
-rw-r--r--crypto/ec/Makefile2
-rw-r--r--crypto/ec/ec.h8
-rw-r--r--crypto/ec/ec_asn1.c78
-rw-r--r--crypto/ec/ec_curve.c116
-rw-r--r--crypto/ec/ec_err.c3
-rw-r--r--crypto/ec/ec_lcl.h17
-rw-r--r--crypto/ec/ec_lib.c159
-rw-r--r--crypto/ec/ecp_nistp224.c63
-rw-r--r--crypto/ec/ecp_nistp256.c64
-rw-r--r--crypto/ec/ecp_nistp521.c64
-rw-r--r--crypto/opensslv.h6
-rw-r--r--crypto/pem/pvkfmt.c4
-rw-r--r--crypto/pkcs7/pk7_doit.c12
-rw-r--r--crypto/rsa/rsa_chk.c10
-rw-r--r--crypto/x509/x509_cmp.c2
-rw-r--r--crypto/x509v3/v3_alt.c11
-rw-r--r--openssl.spec2
-rw-r--r--packaging/openssl.spec2
-rwxr-xr-xutil/libeay.num1
38 files changed, 763 insertions, 175 deletions
diff --git a/CHANGES b/CHANGES
index 8cfdec6..114ea24 100644
--- a/CHANGES
+++ b/CHANGES
@@ -7,6 +7,48 @@
https://github.com/openssl/openssl/commits/ and pick the appropriate
release branch.
+ Changes between 1.0.2s and 1.0.2t [10 Sep 2019]
+
+ *) For built-in EC curves, ensure an EC_GROUP built from the curve name is
+ used even when parsing explicit parameters, when loading a serialized key
+ or calling `EC_GROUP_new_from_ecpkparameters()`/
+ `EC_GROUP_new_from_ecparameters()`.
+ This prevents bypass of security hardening and performance gains,
+ especially for curves with specialized EC_METHODs.
+ By default, if a key encoded with explicit parameters is loaded and later
+ serialized, the output is still encoded with explicit parameters, even if
+ internally a "named" EC_GROUP is used for computation.
+ [Nicola Tuveri]
+
+ *) Compute ECC cofactors if not provided during EC_GROUP construction. Before
+ this change, EC_GROUP_set_generator would accept order and/or cofactor as
+ NULL. After this change, only the cofactor parameter can be NULL. It also
+ does some minimal sanity checks on the passed order.
+ (CVE-2019-1547)
+ [Billy Bob Brumley]
+
+ *) Fixed a padding oracle in PKCS7_dataDecode and CMS_decrypt_set1_pkey.
+ An attack is simple, if the first CMS_recipientInfo is valid but the
+ second CMS_recipientInfo is chosen ciphertext. If the second
+ recipientInfo decodes to PKCS #1 v1.5 form plaintext, the correct
+ encryption key will be replaced by garbage, and the message cannot be
+ decoded, but if the RSA decryption fails, the correct encryption key is
+ used and the recipient will not notice the attack.
+ As a work around for this potential attack the length of the decrypted
+ key must be equal to the cipher default key length, in case the
+ certifiate is not given and all recipientInfo are tried out.
+ The old behaviour can be re-enabled in the CMS code by setting the
+ CMS_DEBUG_DECRYPT flag.
+ (CVE-2019-1563)
+ [Bernd Edlinger]
+
+ *) Document issue with installation paths in diverse Windows builds
+
+ '/usr/local/ssl' is an unsafe prefix for location to install OpenSSL
+ binaries and run-time config file.
+ (CVE-2019-1552)
+ [Richard Levitte]
+
Changes between 1.0.2r and 1.0.2s [28 May 2019]
*) Change the default RSA, DSA and DH size to 2048 bit instead of 1024.
diff --git a/Configure b/Configure
index 54c3f44..e4ca515 100755
--- a/Configure
+++ b/Configure
@@ -118,7 +118,7 @@ my $gcc_devteam_warn = "-Wall -pedantic -DPEDANTIC -Wno-long-long -Wsign-compare
# -Wincompatible-pointer-types-discards-qualifiers, -Wcast-align,
# -Wunreachable-code -Wunused-parameter -Wlanguage-extension-token
# -Wextended-offsetof
-my $clang_disabled_warnings = "-Wno-unused-parameter -Wno-missing-field-initializers -Wno-language-extension-token -Wno-extended-offsetof";
+my $clang_disabled_warnings = "-Wno-unknown-warning-option -Wno-unused-parameter -Wno-missing-field-initializers -Wno-language-extension-token -Wno-extended-offsetof";
# These are used in addition to $gcc_devteam_warn when the compiler is clang.
# TODO(openssl-team): fix problems and investigate if (at least) the
@@ -128,7 +128,7 @@ my $clang_disabled_warnings = "-Wno-unused-parameter -Wno-missing-field-initiali
# -Wincompatible-pointer-types-discards-qualifiers, -Wcast-align,
# -Wunreachable-code -Wunused-parameter -Wlanguage-extension-token
# -Wextended-offsetof
-my $clang_devteam_warn = "-Wno-unused-parameter -Wno-missing-field-initializers -Wno-language-extension-token -Wno-extended-offsetof -Qunused-arguments";
+my $clang_devteam_warn = "-Wno-unknown-warning-option -Wno-unused-parameter -Wno-missing-field-initializers -Wno-language-extension-token -Wno-extended-offsetof -Qunused-arguments";
# Warn that "make depend" should be run?
my $warn_make_depend = 0;
diff --git a/INSTALL.DJGPP b/INSTALL.DJGPP
index 1047ec9..ecbf493 100644
--- a/INSTALL.DJGPP
+++ b/INSTALL.DJGPP
@@ -33,8 +33,18 @@
running in a DOS box under Windows. If so, just close the BASH
shell, go back to Windows, and restart BASH. Then run "make" again.
- RUN-TIME CAVEAT LECTOR
- --------------
+ CAVEAT LECTOR
+ -------------
+
+ ### Default install and config paths
+
+ ./Configure defaults to '/usr/local/ssl' as installation top. This is
+ suitable for Unix, but not for Windows, where this usually is a world
+ writable directory and therefore accessible for change by untrusted users.
+ It is therefore recommended to set your own --prefix or --openssldir to
+ some location that is not world writeable (see the example above)
+
+ ### Entropy
Quoting FAQ:
diff --git a/INSTALL.W32 b/INSTALL.W32
index bd10187..b97a3d0 100644
--- a/INSTALL.W32
+++ b/INSTALL.W32
@@ -34,6 +34,17 @@
get it all to work. See the trouble shooting section later on for if (when?)
it goes wrong.
+ CAVEAT LECTOR
+ -------------
+
+ ### Default install and config paths
+
+ ./Configure defaults to '/usr/local/ssl' as installation top. This is
+ suitable for Unix, but not for Windows, where this usually is a world
+ writable directory and therefore accessible for change by untrusted users.
+ It is therefore recommended to set your own --prefix or --openssldir to
+ some location that is not world writeable (see the example above)
+
Visual C++
----------
@@ -104,7 +115,7 @@
---------------------
* Configure for building with Borland Builder:
- > perl Configure BC-32
+ > perl Configure BC-32 --prefix=c:\some\openssl\dir
* Create the appropriate makefile
> ms\do_nasm
@@ -196,7 +207,7 @@
* Compile OpenSSL:
- $ ./config
+ $ ./config --prefix=c:/some/openssl/dir
[...]
$ make
[...]
@@ -206,7 +217,11 @@
and openssl.exe application in apps directory.
It is also possible to cross-compile it on Linux by configuring
- with './Configure --cross-compile-prefix=i386-mingw32- mingw ...'.
+ like this:
+
+ $ ./Configure --cross-compile-prefix=i386-mingw32- \
+ --prefix=c:/some/openssl/dir mingw ...
+
'make test' is naturally not applicable then.
libcrypto.a and libssl.a are the static libraries. To use the DLLs,
@@ -240,6 +255,9 @@
$ copy /b out32dll\libeay32.dll c:\openssl\bin
$ copy /b out32dll\openssl.exe c:\openssl\bin
+ ("c:\openssl" should be whatever you specified to --prefix when
+ configuring the build)
+
Of course, you can choose another device than c:. C: is used here
because that's usually the first (and often only) harddisk device.
Note: in the modssl INSTALL.Win32, p: is used rather than c:.
diff --git a/INSTALL.W64 b/INSTALL.W64
index 9fa7a19..3f5bf80 100644
--- a/INSTALL.W64
+++ b/INSTALL.W64
@@ -30,6 +30,14 @@
Neither of these is actually big deal and hardly encountered
in real-life applications.
+ ### Default install and config paths
+
+ ./Configure defaults to '/usr/local/ssl' as installation top. This is
+ suitable for Unix, but not for Windows, where this usually is a world
+ writable directory and therefore accessible for change by untrusted users.
+ It is therefore recommended to set your own --prefix or --openssldir to
+ some location that is not world writeable (see the example above)
+
Compiling procedure
-------------------
@@ -43,7 +51,7 @@
To build for Win64/x64:
- > perl Configure VC-WIN64A
+ > perl Configure VC-WIN64A --prefix=c:\some\openssl\dir
> ms\do_win64a
> nmake -f ms\ntdll.mak
> cd out32dll
@@ -51,7 +59,7 @@
To build for Win64/IA64:
- > perl Configure VC-WIN64I
+ > perl Configure VC-WIN64I --prefix=c:\some\openssl\dir
> ms\do_win64i
> nmake -f ms\ntdll.mak
> cd out32dll
diff --git a/INSTALL.WCE b/INSTALL.WCE
index d78c61a..490685d 100644
--- a/INSTALL.WCE
+++ b/INSTALL.WCE
@@ -35,6 +35,17 @@
redirects IO to active sync link, while PortSDK - to NT-like console
driver on the handheld itself.
+ CAVEAT LECTOR
+ -------------
+
+ ### Default install and config paths
+
+ ./Configure defaults to '/usr/local/ssl' as installation top. This is
+ suitable for Unix, but not for Windows, where this usually is a world
+ writable directory and therefore accessible for change by untrusted users.
+ It is therefore recommended to set your own --prefix or --openssldir to
+ some location that is not world writeable (see the example above)
+
Building
--------
@@ -61,7 +72,7 @@
Next you should run Configure:
- > perl Configure VC-CE
+ > perl Configure VC-CE --prefix=c:\some\openssl\dir
Next you need to build the Makefiles:
diff --git a/Makefile b/Makefile
index 1f018f5..5f80ba8 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@
## Makefile for OpenSSL
##
-VERSION=1.0.2s
+VERSION=1.0.2t
MAJOR=1
MINOR=0.2
SHLIB_VERSION_NUMBER=1.0.0
diff --git a/NEWS b/NEWS
index 4d4e9df..a9705fe 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,21 @@
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.0.2s and OpenSSL 1.0.2t [10 Sep 2019]
+
+ o Fixed a padding oracle in PKCS7_dataDecode and CMS_decrypt_set1_pkey
+ (CVE-2019-1563)
+ o For built-in EC curves, ensure an EC_GROUP built from the curve name is
+ used even when parsing explicit parameters
+ o Compute ECC cofactors if not provided during EC_GROUP construction
+ (CVE-2019-1547)
+ o Document issue with installation paths in diverse Windows builds
+ (CVE-2019-1552)
+
+ Major changes between OpenSSL 1.0.2r and OpenSSL 1.0.2s [28 May 2019]
+
+ o None
+
Major changes between OpenSSL 1.0.2q and OpenSSL 1.0.2r [26 Feb 2019]
o 0-byte record padding oracle (CVE-2019-1559)
diff --git a/README b/README
index 4288325..dc20742 100644
--- a/README
+++ b/README
@@ -1,5 +1,5 @@
- OpenSSL 1.0.2s 28 May 2019
+ OpenSSL 1.0.2t 10 Sep 2019
Copyright (c) 1998-2019 The OpenSSL Project
Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
diff --git a/crypto/arm_arch.h b/crypto/arm_arch.h
index 9d6e588..de592de 100644
--- a/crypto/arm_arch.h
+++ b/crypto/arm_arch.h
@@ -64,7 +64,7 @@
# endif
# endif
-# if !__ASSEMBLER__
+# ifndef __ASSEMBLER__
extern unsigned int OPENSSL_armcap_P;
# endif
diff --git a/crypto/armcap.c b/crypto/armcap.c
index 356fa15..6283e37 100644
--- a/crypto/armcap.c
+++ b/crypto/armcap.c
@@ -5,6 +5,7 @@
#include <signal.h>
#include <crypto.h>
+#include "cryptlib.h"
#include "arm_arch.h"
unsigned int OPENSSL_armcap_P = 0;
diff --git a/crypto/bn/Makefile b/crypto/bn/Makefile
index 9fc4447..7a3bf5d 100644
--- a/crypto/bn/Makefile
+++ b/crypto/bn/Makefile
@@ -297,8 +297,8 @@ bn_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
bn_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
bn_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
bn_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bn_lib.o: ../../include/openssl/symhacks.h ../bn_int.h ../cryptlib.h bn_lcl.h
-bn_lib.o: bn_lib.c
+bn_lib.o: ../../include/openssl/symhacks.h ../bn_int.h ../constant_time_locl.h
+bn_lib.o: ../cryptlib.h bn_lcl.h bn_lib.c
bn_mod.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
bn_mod.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
bn_mod.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
diff --git a/crypto/bn/bn_lib.c b/crypto/bn/bn_lib.c
index 2a84698..d4419a3 100644
--- a/crypto/bn/bn_lib.c
+++ b/crypto/bn/bn_lib.c
@@ -66,6 +66,7 @@
#include <stdio.h>
#include "cryptlib.h"
#include "bn_lcl.h"
+#include "constant_time_locl.h"
const char BN_version[] = "Big Number" OPENSSL_VERSION_PTEXT;
@@ -187,13 +188,57 @@ int BN_num_bits_word(BN_ULONG l)
return bits;
}
+/*
+ * This function still leaks `a->dmax`: it's caller's responsibility to
+ * expand the input `a` in advance to a public length.
+ */
+static inline
+int bn_num_bits_consttime(const BIGNUM *a)
+{
+ int j, ret;
+ unsigned int mask, past_i;
+ int i = a->top - 1;
+ bn_check_top(a);
+
+ for (j = 0, past_i = 0, ret = 0; j < a->dmax; j++) {
+ mask = constant_time_eq_int(i, j); /* 0xff..ff if i==j, 0x0 otherwise */
+
+ ret += BN_BITS2 & (~mask & ~past_i);
+ ret += BN_num_bits_word(a->d[j]) & mask;
+
+ past_i |= mask; /* past_i will become 0xff..ff after i==j */
+ }
+
+ /*
+ * if BN_is_zero(a) => i is -1 and ret contains garbage, so we mask the
+ * final result.
+ */
+ mask = ~(constant_time_eq_int(i, ((int)-1)));
+
+ return ret & mask;
+}
+
int BN_num_bits(const BIGNUM *a)
{
int i = a->top - 1;
bn_check_top(a);
+ if (a->flags & BN_FLG_CONSTTIME) {
+ /*
+ * We assume that BIGNUMs flagged as CONSTTIME have also been expanded
+ * so that a->dmax is not leaking secret information.
+ *
+ * In other words, it's the caller's responsibility to ensure `a` has
+ * been preallocated in advance to a public length if we hit this
+ * branch.
+ *
+ */
+ return bn_num_bits_consttime(a);
+ }
+
if (BN_is_zero(a))
return 0;
+
return ((i * BN_BITS2) + BN_num_bits_word(a->d[i]));
}
@@ -613,8 +658,11 @@ BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
return (ret);
}
+typedef enum {big, little} endianess_t;
+
/* ignore negative */
-static int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
+static
+int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen, endianess_t endianess)
{
int n;
size_t i, lasti, j, atop, mask;
@@ -646,10 +694,17 @@ static int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
lasti = atop - 1;
atop = a->top * BN_BYTES;
- for (i = 0, j = 0, to += tolen; j < (size_t)tolen; j++) {
+ if (endianess == big)
+ to += tolen; /* start from the end of the buffer */
+ for (i = 0, j = 0; j < (size_t)tolen; j++) {
+ unsigned char val;
l = a->d[i / BN_BYTES];
mask = 0 - ((j - atop) >> (8 * sizeof(i) - 1));
- *--to = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask);
+ val = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask);
+ if (endianess == big)
+ *--to = val;
+ else
+ *to++ = val;
i += (i - lasti) >> (8 * sizeof(i) - 1); /* stay on last limb */
}
@@ -660,21 +715,66 @@ int bn_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
{
if (tolen < 0)
return -1;
- return bn2binpad(a, to, tolen);
+ return bn2binpad(a, to, tolen, big);
}
int BN_bn2bin(const BIGNUM *a, unsigned char *to)
{
- int n, i;
+ return bn2binpad(a, to, -1, big);
+}
+
+BIGNUM *bn_lebin2bn(const unsigned char *s, int len, BIGNUM *ret)
+{
+ unsigned int i, m;
+ unsigned int n;
BN_ULONG l;
+ BIGNUM *bn = NULL;
- bn_check_top(a);
- n = i = BN_num_bytes(a);
- while (i--) {
- l = a->d[i / BN_BYTES];
- *(to++) = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff;
+ if (ret == NULL)
+ ret = bn = BN_new();
+ if (ret == NULL)
+ return NULL;
+ bn_check_top(ret);
+ s += len;
+ /* Skip trailing zeroes. */
+ for ( ; len > 0 && s[-1] == 0; s--, len--)
+ continue;
+ n = len;
+ if (n == 0) {
+ ret->top = 0;
+ return ret;
+ }
+ i = ((n - 1) / BN_BYTES) + 1;
+ m = ((n - 1) % (BN_BYTES));
+ if (bn_wexpand(ret, (int)i) == NULL) {
+ BN_free(bn);
+ return NULL;
+ }
+ ret->top = i;
+ ret->neg = 0;
+ l = 0;
+ while (n--) {
+ s--;
+ l = (l << 8L) | *s;
+ if (m-- == 0) {
+ ret->d[--i] = l;
+ l = 0;
+ m = BN_BYTES - 1;
+ }
}
- return (n);
+ /*
+ * need to call this due to clear byte at top if avoiding having the top
+ * bit set (-ve number)
+ */
+ bn_correct_top(ret);
+ return ret;
+}
+
+int bn_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen)
+{
+ if (tolen < 0)
+ return -1;
+ return bn2binpad(a, to, tolen, little);
}
int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
diff --git a/crypto/bn_int.h b/crypto/bn_int.h
index a552cc2..6791154 100644
--- a/crypto/bn_int.h
+++ b/crypto/bn_int.h
@@ -19,3 +19,6 @@ int bn_mul_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
int bn_sqr_fixed_top(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx);
int bn_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen);
+
+BIGNUM *bn_lebin2bn(const unsigned char *s, int len, BIGNUM *ret);
+int bn_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen);
diff --git a/crypto/cms/cms_env.c b/crypto/cms/cms_env.c
index 93c06cb..e46348f 100644
--- a/crypto/cms/cms_env.c
+++ b/crypto/cms/cms_env.c
@@ -4,7 +4,7 @@
* project.
*/
/* ====================================================================
- * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 2008-2019 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -422,6 +422,7 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
unsigned char *ek = NULL;
size_t eklen;
int ret = 0;
+ size_t fixlen = 0;
CMS_EncryptedContentInfo *ec;
ec = cms->d.envelopedData->encryptedContentInfo;
@@ -430,6 +431,19 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
return 0;
}
+ if (cms->d.envelopedData->encryptedContentInfo->havenocert
+ && !cms->d.envelopedData->encryptedContentInfo->debug) {
+ X509_ALGOR *calg = ec->contentEncryptionAlgorithm;
+ const EVP_CIPHER *ciph = EVP_get_cipherbyobj(calg->algorithm);
+
+ if (ciph == NULL) {
+ CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_UNKNOWN_CIPHER);
+ return 0;
+ }
+
+ fixlen = EVP_CIPHER_key_length(ciph);
+ }
+
ktri->pctx = EVP_PKEY_CTX_new(pkey, NULL);
if (!ktri->pctx)
return 0;
@@ -460,7 +474,9 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
if (EVP_PKEY_decrypt(ktri->pctx, ek, &eklen,
ktri->encryptedKey->data,
- ktri->encryptedKey->length) <= 0) {
+ ktri->encryptedKey->length) <= 0
+ || eklen == 0
+ || (fixlen != 0 && eklen != fixlen)) {
CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB);
goto err;
}
diff --git a/crypto/cms/cms_lcl.h b/crypto/cms/cms_lcl.h
index 20f2c25..9ec13f5 100644
--- a/crypto/cms/cms_lcl.h
+++ b/crypto/cms/cms_lcl.h
@@ -4,7 +4,7 @@
* project.
*/
/* ====================================================================
- * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 2008-2019 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -172,6 +172,8 @@ struct CMS_EncryptedContentInfo_st {
size_t keylen;
/* Set to 1 if we are debugging decrypt and don't fake keys for MMA */
int debug;
+ /* Set to 1 if we have no cert and need extra safety measures for MMA */
+ int havenocert;
};
struct CMS_RecipientInfo_st {
diff --git a/crypto/cms/cms_smime.c b/crypto/cms/cms_smime.c
index 07e3472..f2d81bd 100644
--- a/crypto/cms/cms_smime.c
+++ b/crypto/cms/cms_smime.c
@@ -4,7 +4,7 @@
* project.
*/
/* ====================================================================
- * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 2008-2019 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -737,6 +737,10 @@ int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert,
cms->d.envelopedData->encryptedContentInfo->debug = 1;
else
cms->d.envelopedData->encryptedContentInfo->debug = 0;
+ if (!cert)
+ cms->d.envelopedData->encryptedContentInfo->havenocert = 1;
+ else
+ cms->d.envelopedData->encryptedContentInfo->havenocert = 0;
if (!pk && !cert && !dcont && !out)
return 1;
if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert))
diff --git a/crypto/constant_time_locl.h b/crypto/constant_time_locl.h
index a5734f2..f322e78 100644
--- a/crypto/constant_time_locl.h
+++ b/crypto/constant_time_locl.h
@@ -6,7 +6,7 @@
* Based on previous work by Bodo Moeller, Emilia Kasper, Adam Langley
* (Google).
* ====================================================================
- * Copyright (c) 2014 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 2014-2019 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -185,11 +185,29 @@ static inline unsigned char constant_time_eq_int_8(int a, int b)
return constant_time_eq_8((unsigned)(a), (unsigned)(b));
}
+/*
+ * Returns the value unmodified, but avoids optimizations.
+ * The barriers prevent the compiler from narrowing down the
+ * possible value range of the mask and ~mask in the select
+ * statements, which avoids the recognition of the select
+ * and turning it into a conditional load or branch.
+ */
+static inline unsigned int value_barrier(unsigned int a)
+{
+#if !defined(OPENSSL_NO_ASM) && defined(__GNUC__)
+ unsigned int r;
+ __asm__("" : "=r"(r) : "0"(a));
+#else
+ volatile unsigned int r = a;
+#endif
+ return r;
+}
+
static inline unsigned int constant_time_select(unsigned int mask,
unsigned int a,
unsigned int b)
{
- return (mask & a) | (~mask & b);
+ return (value_barrier(mask) & a) | (value_barrier(~mask) & b);
}
static inline unsigned char constant_time_select_8(unsigned char mask,
diff --git a/crypto/cryptlib.h b/crypto/cryptlib.h
index cdbddf1..2f9eced 100644
--- a/crypto/cryptlib.h
+++ b/crypto/cryptlib.h
@@ -106,6 +106,8 @@ extern int OPENSSL_NONPIC_relocated;
char *ossl_safe_getenv(const char *);
+unsigned long OPENSSL_rdtsc(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/crypto/ec/Makefile b/crypto/ec/Makefile
index 6628390..e9d65e3 100644
--- a/crypto/ec/Makefile
+++ b/crypto/ec/Makefile
@@ -156,7 +156,7 @@ ec_curve.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
ec_curve.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
ec_curve.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
ec_curve.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-ec_curve.o: ../../include/openssl/symhacks.h ec_curve.c ec_lcl.h
+ec_curve.o: ../../include/openssl/symhacks.h ../bn_int.h ec_curve.c ec_lcl.h
ec_cvt.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
ec_cvt.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
ec_cvt.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
diff --git a/crypto/ec/ec.h b/crypto/ec/ec.h
index 81e6faf..0127036 100644
--- a/crypto/ec/ec.h
+++ b/crypto/ec/ec.h
@@ -7,7 +7,7 @@
* \author Originally written by Bodo Moeller for the OpenSSL project
*/
/* ====================================================================
- * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1998-2019 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -1073,6 +1073,7 @@ int EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off);
* The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run.
*/
+
void ERR_load_EC_strings(void);
/* Error codes for the EC functions. */
@@ -1270,13 +1271,14 @@ void ERR_load_EC_strings(void);
# define EC_R_SLOT_FULL 108
# define EC_R_UNDEFINED_GENERATOR 113
# define EC_R_UNDEFINED_ORDER 128
+# define EC_R_UNKNOWN_COFACTOR 152
# define EC_R_UNKNOWN_GROUP 129
# define EC_R_UNKNOWN_ORDER 114
# define EC_R_UNSUPPORTED_FIELD 131
# define EC_R_WRONG_CURVE_PARAMETERS 145
# define EC_R_WRONG_ORDER 130
-#ifdef __cplusplus
+# ifdef __cplusplus
}
-#endif
+# endif
#endif
diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c
index b0cd3e1..865130f 100644
--- a/crypto/ec/ec_asn1.c
+++ b/crypto/ec/ec_asn1.c
@@ -3,7 +3,7 @@
* Written by Nils Larsch for the OpenSSL project.
*/
/* ====================================================================
- * Copyright (c) 2000-2003 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 2000-2019 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -695,10 +695,12 @@ ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group,
static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params)
{
int ok = 0, tmp;
- EC_GROUP *ret = NULL;
+ EC_GROUP *ret = NULL, *dup = NULL;
BIGNUM *p = NULL, *a = NULL, *b = NULL;
EC_POINT *point = NULL;
long field_bits;
+ int curve_name = NID_undef;
+ BN_CTX *ctx = NULL;
if (!params->fieldID || !params->fieldID->fieldType ||
!params->fieldID->p.ptr) {
@@ -914,13 +916,75 @@ static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params)
goto err;
}
+ /*
+ * Check if the explicit parameters group just created matches one of the
+ * built-in curves.
+ *
+ * We create a copy of the group just built, so that we can remove optional
+ * fields for the lookup: we do this to avoid the possibility that one of
+ * the optional parameters is used to force the library into using a less
+ * performant and less secure EC_METHOD instead of the specialized one.
+ * In any case, `seed` is not really used in any computation, while a
+ * cofactor different from the one in the built-in table is just
+ * mathematically wrong anyway and should not be used.
+ */
+ if ((ctx = BN_CTX_new()) == NULL) {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
+ goto err;
+ }
+ if ((dup = EC_GROUP_dup(ret)) == NULL
+ || EC_GROUP_set_seed(dup, NULL, 0) != 1
+ || !EC_GROUP_set_generator(dup, point, a, NULL)) {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
+ goto err;
+ }
+ if ((curve_name = ec_curve_nid_from_params(dup, ctx)) != NID_undef) {
+ /*
+ * The input explicit parameters successfully matched one of the
+ * built-in curves: often for built-in curves we have specialized
+ * methods with better performance and hardening.
+ *
+ * In this case we replace the `EC_GROUP` created through explicit
+ * parameters with one created from a named group.
+ */
+ EC_GROUP *named_group = NULL;
+
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+ /*
+ * NID_wap_wsg_idm_ecid_wtls12 and NID_secp224r1 are both aliases for
+ * the same curve, we prefer the SECP nid when matching explicit
+ * parameters as that is associated with a specialized EC_METHOD.
+ */
+ if (curve_name == NID_wap_wsg_idm_ecid_wtls12)
+ curve_name = NID_secp224r1;
+#endif /* !def(OPENSSL_NO_EC_NISTP_64_GCC_128) */
+
+ if ((named_group = EC_GROUP_new_by_curve_name(curve_name)) == NULL) {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
+ goto err;
+ }
+ EC_GROUP_free(ret);
+ ret = named_group;
+
+ /*
+ * Set the flag so that EC_GROUPs created from explicit parameters are
+ * serialized using explicit parameters by default.
+ *
+ * 0x0 = OPENSSL_EC_EXPLICIT_CURVE
+ */
+ EC_GROUP_set_asn1_flag(ret, 0x0);
+ }
+
ok = 1;
- err:if (!ok) {
+ err:
+ if (!ok) {
if (ret)
- EC_GROUP_clear_free(ret);
+ EC_GROUP_free(ret);
ret = NULL;
}
+ if (dup)
+ EC_GROUP_free(dup);
if (p)
BN_free(p);
@@ -930,6 +994,8 @@ static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params)
BN_free(b);
if (point)
EC_POINT_free(point);
+ if (ctx)
+ BN_CTX_free(ctx);
return (ret);
}
@@ -990,7 +1056,7 @@ EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
}
if (a && *a)
- EC_GROUP_clear_free(*a);
+ EC_GROUP_free(*a);
if (a)
*a = group;
@@ -1040,7 +1106,7 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
if (priv_key->parameters) {
if (ret->group)
- EC_GROUP_clear_free(ret->group);
+ EC_GROUP_free(ret->group);
ret->group = ec_asn1_pkparameters2group(priv_key->parameters);
}
diff --git a/crypto/ec/ec_curve.c b/crypto/ec/ec_curve.c
index 6dbe9d8..a6c5083 100644
--- a/crypto/ec/ec_curve.c
+++ b/crypto/ec/ec_curve.c
@@ -3,7 +3,7 @@
* Written by Nils Larsch for the OpenSSL project.
*/
/* ====================================================================
- * Copyright (c) 1998-2010 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1998-2019 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -75,6 +75,8 @@
#include <openssl/obj_mac.h>
#include <openssl/opensslconf.h>
+#include "bn_int.h"
+
#ifdef OPENSSL_FIPS
# include <openssl/fips.h>
#endif
@@ -3246,3 +3248,115 @@ int EC_curve_nist2nid(const char *name)
}
return NID_undef;
}
+
+#define NUM_BN_FIELDS 6
+/*
+ * Validates EC domain parameter data for known named curves.
+ * This can be used when a curve is loaded explicitly (without a curve
+ * name) or to validate that domain parameters have not been modified.
+ *
+ * Returns: The nid associated with the found named curve, or NID_undef
+ * if not found. If there was an error it returns -1.
+ */
+int ec_curve_nid_from_params(const EC_GROUP *group, BN_CTX *ctx)
+{
+ int ret = -1, nid, len, field_type, param_len;
+ size_t i, seed_len;
+ const unsigned char *seed, *params_seed, *params;
+ unsigned char *param_bytes = NULL;
+ const EC_CURVE_DATA *data;
+ const EC_POINT *generator = NULL;
+ const EC_METHOD *meth;
+ const BIGNUM *cofactor = NULL;
+ /* An array of BIGNUMs for (p, a, b, x, y, order) */
+ BIGNUM *bn[NUM_BN_FIELDS] = {NULL, NULL, NULL, NULL, NULL, NULL};
+
+ meth = EC_GROUP_method_of(group);
+ if (meth == NULL)
+ return -1;
+ /* Use the optional named curve nid as a search field */
+ nid = EC_GROUP_get_curve_name(group);
+ field_type = EC_METHOD_get_field_type(meth);
+ seed_len = EC_GROUP_get_seed_len(group);
+ seed = EC_GROUP_get0_seed(group);
+ cofactor = &group->cofactor;
+
+ BN_CTX_start(ctx);
+
+ /*
+ * The built-in curves contains data fields (p, a, b, x, y, order) that are
+ * all zero-padded to be the same size. The size of the padding is
+ * determined by either the number of bytes in the field modulus (p) or the
+ * EC group order, whichever is larger.
+ */
+ param_len = BN_num_bytes(&group->order);
+ len = BN_num_bytes(&group->field);
+ if (len > param_len)
+ param_len = len;
+
+ /* Allocate space to store the padded data for (p, a, b, x, y, order) */
+ param_bytes = OPENSSL_malloc(param_len * NUM_BN_FIELDS);
+ if (param_bytes == NULL)
+ goto end;
+
+ /* Create the bignums */
+ for (i = 0; i < NUM_BN_FIELDS; ++i) {
+ if ((bn[i] = BN_CTX_get(ctx)) == NULL)
+ goto end;
+ }
+ /*
+ * Fill in the bn array with the same values as the internal curves
+ * i.e. the values are p, a, b, x, y, order.
+ */
+ /* Get p, a & b */
+ if (!(ec_group_get_curve(group, bn[0], bn[1], bn[2], ctx)
+ && ((generator = EC_GROUP_get0_generator(group)) != NULL)
+ /* Get x & y */
+ && ec_point_get_affine_coordinates(group, generator, bn[3], bn[4], ctx)
+ /* Get order */
+ && EC_GROUP_get_order(group, bn[5], ctx)))
+ goto end;
+
+ /*
+ * Convert the bignum array to bytes that are joined together to form
+ * a single buffer that contains data for all fields.
+ * (p, a, b, x, y, order) are all zero padded to be the same size.
+ */
+ for (i = 0; i < NUM_BN_FIELDS; ++i) {
+ if (bn_bn2binpad(bn[i], &param_bytes[i*param_len], param_len) <= 0)
+ goto end;
+ }
+
+ for (i = 0; i < curve_list_length; i++) {
+ const ec_list_element curve = curve_list[i];
+
+ data = curve.data;
+ /* Get the raw order byte data */
+ params_seed = (const unsigned char *)(data + 1); /* skip header */
+ params = params_seed + data->seed_len;
+
+ /* Look for unique fields in the fixed curve data */
+ if (data->field_type == field_type
+ && param_len == data->param_len
+ && (nid <= 0 || nid == curve.nid)
+ /* check the optional cofactor (ignore if its zero) */
+ && (BN_is_zero(cofactor)
+ || BN_is_word(cofactor, (const BN_ULONG)curve.data->cofactor))
+ /* Check the optional seed (ignore if its not set) */
+ && (data->seed_len == 0 || seed_len == 0
+ || ((size_t)data->seed_len == seed_len
+ && memcmp(params_seed, seed, seed_len) == 0))
+ /* Check that the groups params match the built-in curve params */
+ && memcmp(param_bytes, params, param_len * NUM_BN_FIELDS)
+ == 0) {
+ ret = curve.nid;
+ goto end;
+ }
+ }
+ /* Gets here if the group was not found */
+ ret = NID_undef;
+end:
+ OPENSSL_free(param_bytes);
+ BN_CTX_end(ctx);
+ return ret;
+}
diff --git a/crypto/ec/ec_err.c b/crypto/ec/ec_err.c
index 6fe5baa..2205411 100644
--- a/crypto/ec/ec_err.c
+++ b/crypto/ec/ec_err.c
@@ -1,6 +1,6 @@
/* crypto/ec/ec_err.c */
/* ====================================================================
- * Copyright (c) 1999-2015 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-2019 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -310,6 +310,7 @@ static ERR_STRING_DATA EC_str_reasons[] = {
{ERR_REASON(EC_R_SLOT_FULL), "slot full"},
{ERR_REASON(EC_R_UNDEFINED_GENERATOR), "undefined generator"},
{ERR_REASON(EC_R_UNDEFINED_ORDER), "undefined order"},
+ {ERR_REASON(EC_R_UNKNOWN_COFACTOR), "unknown cofactor"},
{ERR_REASON(EC_R_UNKNOWN_GROUP), "unknown group"},
{ERR_REASON(EC_R_UNKNOWN_ORDER), "unknown order"},
{ERR_REASON(EC_R_UNSUPPORTED_FIELD), "unsupported field"},
diff --git a/crypto/ec/ec_lcl.h b/crypto/ec/ec_lcl.h
index 8665a4c..14afa3c 100644
--- a/crypto/ec/ec_lcl.h
+++ b/crypto/ec/ec_lcl.h
@@ -3,7 +3,7 @@
* Originally written by Bodo Moeller for the OpenSSL project.
*/
/* ====================================================================
- * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1998-2019 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -565,3 +565,18 @@ EC_GROUP *FIPS_ec_group_new_curve_gf2m(const BIGNUM *p, const BIGNUM *a,
const BIGNUM *b, BN_CTX *ctx);
EC_GROUP *FIPS_ec_group_new_by_curve_name(int nid);
#endif
+
+int ec_curve_nid_from_params(const EC_GROUP *group, BN_CTX *ctx);
+
+/*
+ * The next 2 functions are just internal wrappers around the omonimous
+ * functions with either the `_GFp` or the `_GF2m` suffix.
+ *
+ * They are meant to facilitate backporting of code from newer branches, where
+ * the public API includes a "field agnostic" version of these 2 functions.
+ */
+int ec_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
+ BIGNUM *b, BN_CTX *ctx);
+int ec_point_get_affine_coordinates(const EC_GROUP *group,
+ const EC_POINT *point, BIGNUM *x,
+ BIGNUM *y, BN_CTX *ctx);
diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c
index cd2c420..e3f2e82 100644
--- a/crypto/ec/ec_lib.c
+++ b/crypto/ec/ec_lib.c
@@ -294,6 +294,67 @@ int EC_METHOD_get_field_type(const EC_METHOD *meth)
return meth->field_type;
}
+/*-
+ * Try computing cofactor from the generator order (n) and field cardinality (q).
+ * This works for all curves of cryptographic interest.
+ *
+ * Hasse thm: q + 1 - 2*sqrt(q) <= n*h <= q + 1 + 2*sqrt(q)
+ * h_min = (q + 1 - 2*sqrt(q))/n
+ * h_max = (q + 1 + 2*sqrt(q))/n
+ * h_max - h_min = 4*sqrt(q)/n
+ * So if n > 4*sqrt(q) holds, there is only one possible value for h:
+ * h = \lfloor (h_min + h_max)/2 \rceil = \lfloor (q + 1)/n \rceil
+ *
+ * Otherwise, zero cofactor and return success.
+ */
+static int ec_guess_cofactor(EC_GROUP *group) {
+ int ret = 0;
+ BN_CTX *ctx = NULL;
+ BIGNUM *q = NULL;
+
+ /*-
+ * If the cofactor is too large, we cannot guess it.
+ * The RHS of below is a strict overestimate of lg(4 * sqrt(q))
+ */
+ if (BN_num_bits(&group->order) <= (BN_num_bits(&group->field) + 1) / 2 + 3) {
+ /* default to 0 */
+ BN_zero(&group->cofactor);
+ /* return success */
+ return 1;
+ }
+
+ if ((ctx = BN_CTX_new()) == NULL)
+ return 0;
+
+ BN_CTX_start(ctx);
+ if ((q = BN_CTX_get(ctx)) == NULL)
+ goto err;
+
+ /* set q = 2**m for binary fields; q = p otherwise */
+ if (group->meth->field_type == NID_X9_62_characteristic_two_field) {
+ BN_zero(q);
+ if (!BN_set_bit(q, BN_num_bits(&group->field) - 1))
+ goto err;
+ } else {
+ if (!BN_copy(q, &group->field))
+ goto err;
+ }
+
+ /* compute h = \lfloor (q + 1)/n \rceil = \lfloor (q + 1 + n/2)/n \rfloor */
+ if (!BN_rshift1(&group->cofactor, &group->order) /* n/2 */
+ || !BN_add(&group->cofactor, &group->cofactor, q) /* q + n/2 */
+ /* q + 1 + n/2 */
+ || !BN_add(&group->cofactor, &group->cofactor, BN_value_one())
+ /* (q + 1 + n/2)/n */
+ || !BN_div(&group->cofactor, NULL, &group->cofactor, &group->order, ctx))
+ goto err;
+ ret = 1;
+ err:
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ return ret;
+}
+
int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
const BIGNUM *order, const BIGNUM *cofactor)
{
@@ -302,6 +363,33 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
return 0;
}
+ /* require group->field >= 1 */
+ if (BN_is_zero(&group->field) || BN_is_negative(&group->field)) {
+ ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_INVALID_FIELD);
+ return 0;
+ }
+
+ /*-
+ * - require order >= 1
+ * - enforce upper bound due to Hasse thm: order can be no more than one bit
+ * longer than field cardinality
+ */
+ if (order == NULL || BN_is_zero(order) || BN_is_negative(order)
+ || BN_num_bits(order) > BN_num_bits(&group->field) + 1) {
+ ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_INVALID_GROUP_ORDER);
+ return 0;
+ }
+
+ /*-
+ * Unfortunately the cofactor is an optional field in many standards.
+ * Internally, the lib uses 0 cofactor as a marker for "unknown cofactor".
+ * So accept cofactor == NULL or cofactor >= 0.
+ */
+ if (cofactor != NULL && BN_is_negative(cofactor)) {
+ ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_UNKNOWN_COFACTOR);
+ return 0;
+ }
+
if (group->generator == NULL) {
group->generator = EC_POINT_new(group);
if (group->generator == NULL)
@@ -310,17 +398,17 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
if (!EC_POINT_copy(group->generator, generator))
return 0;
- if (order != NULL) {
- if (!BN_copy(&group->order, order))
- return 0;
- } else
- BN_zero(&group->order);
+ if (!BN_copy(&group->order, order))
+ return 0;
- if (cofactor != NULL) {
+ /* Either take the provided positive cofactor, or try to compute it */
+ if (cofactor != NULL && !BN_is_zero(cofactor)) {
if (!BN_copy(&group->cofactor, cofactor))
return 0;
- } else
+ } else if (!ec_guess_cofactor(group)) {
BN_zero(&group->cofactor);
+ return 0;
+ }
/*-
* Access to the `mont_data` field of an EC_GROUP struct should always be
@@ -1169,3 +1257,60 @@ int ec_precompute_mont_data(EC_GROUP *group)
BN_CTX_free(ctx);
return ret;
}
+
+/*
+ * This is just a wrapper around the public functions
+ * - EC_GROUP_get_curve_GF2m
+ * - EC_GROUP_get_curve_GFp
+ *
+ * It is meant to facilitate backporting of code from newer branches, where
+ * the public API includes a "field agnostic" version of it.
+ */
+int ec_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
+ BIGNUM *b, BN_CTX *ctx)
+{
+ int field_nid;
+
+ field_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
+
+#ifndef OPENSSL_NO_EC2M
+ if (field_nid == NID_X9_62_characteristic_two_field) {
+ return EC_GROUP_get_curve_GF2m(group, p, a, b, ctx);
+ } else
+#endif /* !def(OPENSSL_NO_EC2M) */
+ if (field_nid == NID_X9_62_prime_field) {
+ return EC_GROUP_get_curve_GFp(group, p, a, b, ctx);
+ } else {
+ /* this should never happen */
+ return 0;
+ }
+}
+
+/*
+ * This is just a wrapper around the public functions
+ * - EC_POINT_get_affine_coordinates_GF2m
+ * - EC_POINT_get_affine_coordinates_GFp
+ *
+ * It is meant to facilitate backporting of code from newer branches, where
+ * the public API includes a "field agnostic" version of it.
+ */
+int ec_point_get_affine_coordinates(const EC_GROUP *group,
+ const EC_POINT *point, BIGNUM *x,
+ BIGNUM *y, BN_CTX *ctx)
+{
+ int field_nid;
+
+ field_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
+
+#ifndef OPENSSL_NO_EC2M
+ if (field_nid == NID_X9_62_characteristic_two_field) {
+ return EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx);
+ } else
+#endif /* !def(OPENSSL_NO_EC2M) */
+ if (field_nid == NID_X9_62_prime_field) {
+ return EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx);
+ } else {
+ /* this should never happen */
+ return 0;
+ }
+}
diff --git a/crypto/ec/ecp_nistp224.c b/crypto/ec/ecp_nistp224.c
index 121f587..76eaa70 100644
--- a/crypto/ec/ecp_nistp224.c
+++ b/crypto/ec/ecp_nistp224.c
@@ -37,6 +37,7 @@
# include <string.h>
# include <openssl/err.h>
# include "ec_lcl.h"
+# include "bn_int.h" /* bn_bn2lebinpad, bn_lebin2bn */
# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
/* even with gcc, the typedef won't work for 32-bit platforms */
@@ -334,34 +335,21 @@ static void felem_to_bin28(u8 out[28], const felem in)
}
}
-/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
-static void flip_endian(u8 *out, const u8 *in, unsigned len)
-{
- unsigned i;
- for (i = 0; i < len; ++i)
- out[i] = in[len - 1 - i];
-}
-
/* From OpenSSL BIGNUM to internal representation */
static int BN_to_felem(felem out, const BIGNUM *bn)
{
- felem_bytearray b_in;
felem_bytearray b_out;
- unsigned num_bytes;
+ int num_bytes;
- /* BN_bn2bin eats leading zeroes */
- memset(b_out, 0, sizeof(b_out));
- num_bytes = BN_num_bytes(bn);
- if (num_bytes > sizeof(b_out)) {
+ if (BN_is_negative(bn)) {
ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
return 0;
}
- if (BN_is_negative(bn)) {
+ num_bytes = bn_bn2lebinpad(bn, b_out, sizeof(b_out));
+ if (num_bytes < 0) {
ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
return 0;
}
- num_bytes = BN_bn2bin(bn, b_in);
- flip_endian(b_out, b_in, num_bytes);
bin28_to_felem(out, b_out);
return 1;
}
@@ -369,10 +357,9 @@ static int BN_to_felem(felem out, const BIGNUM *bn)
/* From internal representation to OpenSSL BIGNUM */
static BIGNUM *felem_to_BN(BIGNUM *out, const felem in)
{
- felem_bytearray b_in, b_out;
- felem_to_bin28(b_in, in);
- flip_endian(b_out, b_in, sizeof(b_out));
- return BN_bin2bn(b_out, sizeof(b_out), out);
+ felem_bytearray b_out;
+ felem_to_bin28(b_out, in);
+ return bn_lebin2bn(b_out, sizeof(b_out), out);
}
/******************************************************************************/
@@ -1426,8 +1413,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
felem_bytearray *secrets = NULL;
felem(*pre_comp)[17][3] = NULL;
felem *tmp_felems = NULL;
- felem_bytearray tmp;
- unsigned num_bytes;
+ int num_bytes;
int have_pre_comp = 0;
size_t num_points = num;
felem x_in, y_in, z_in, x_out, y_out, z_out;
@@ -1509,14 +1495,12 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
memset(secrets, 0, num_points * sizeof(felem_bytearray));
memset(pre_comp, 0, num_points * 17 * 3 * sizeof(felem));
for (i = 0; i < num_points; ++i) {
- if (i == num)
+ if (i == num) {
/* the generator */
- {
p = EC_GROUP_get0_generator(group);
p_scalar = scalar;
- } else
+ } else {
/* the i^th point */
- {
p = points[i];
p_scalar = scalars[i];
}
@@ -1532,10 +1516,16 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
goto err;
}
- num_bytes = BN_bn2bin(tmp_scalar, tmp);
- } else
- num_bytes = BN_bn2bin(p_scalar, tmp);
- flip_endian(secrets[i], tmp, num_bytes);
+ num_bytes = bn_bn2lebinpad(tmp_scalar,
+ secrets[i], sizeof(secrets[i]));
+ } else {
+ num_bytes = bn_bn2lebinpad(p_scalar,
+ secrets[i], sizeof(secrets[i]));
+ }
+ if (num_bytes < 0) {
+ ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
+ goto err;
+ }
/* precompute multiples */
if ((!BN_to_felem(x_out, &p->X)) ||
(!BN_to_felem(y_out, &p->Y)) ||
@@ -1578,20 +1568,21 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
goto err;
}
- num_bytes = BN_bn2bin(tmp_scalar, tmp);
- } else
- num_bytes = BN_bn2bin(scalar, tmp);
- flip_endian(g_secret, tmp, num_bytes);
+ num_bytes = bn_bn2lebinpad(tmp_scalar, g_secret, sizeof(g_secret));
+ } else {
+ num_bytes = bn_bn2lebinpad(scalar, g_secret, sizeof(g_secret));
+ }
/* do the multiplication with generator precomputation */
batch_mul(x_out, y_out, z_out,
(const felem_bytearray(*))secrets, num_points,
g_secret,
mixed, (const felem(*)[17][3])pre_comp, g_pre_comp);
- } else
+ } else {
/* do the multiplication without generator precomputation */
batch_mul(x_out, y_out, z_out,
(const felem_bytearray(*))secrets, num_points,
NULL, mixed, (const felem(*)[17][3])pre_comp, NULL);
+ }
/* reduce the output to its unique minimal representation */
felem_contract(x_in, x_out);
felem_contract(y_in, y_out);
diff --git a/crypto/ec/ecp_nistp256.c b/crypto/ec/ecp_nistp256.c
index 378f0ba..5576d31 100644
--- a/crypto/ec/ecp_nistp256.c
+++ b/crypto/ec/ecp_nistp256.c
@@ -38,6 +38,7 @@
# include <string.h>
# include <openssl/err.h>
# include "ec_lcl.h"
+# include "bn_int.h" /* bn_bn2lebinpad, bn_lebin2bn */
# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
/* even with gcc, the typedef won't work for 32-bit platforms */
@@ -144,34 +145,21 @@ static void smallfelem_to_bin32(u8 out[32], const smallfelem in)
*((u64 *)&out[24]) = in[3];
}
-/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
-static void flip_endian(u8 *out, const u8 *in, unsigned len)
-{
- unsigned i;
- for (i = 0; i < len; ++i)
- out[i] = in[len - 1 - i];
-}
-
/* BN_to_felem converts an OpenSSL BIGNUM into an felem */
static int BN_to_felem(felem out, const BIGNUM *bn)
{
- felem_bytearray b_in;
felem_bytearray b_out;
- unsigned num_bytes;
+ int num_bytes;
- /* BN_bn2bin eats leading zeroes */
- memset(b_out, 0, sizeof(b_out));
- num_bytes = BN_num_bytes(bn);
- if (num_bytes > sizeof(b_out)) {
+ if (BN_is_negative(bn)) {
ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
return 0;
}
- if (BN_is_negative(bn)) {
+ num_bytes = bn_bn2lebinpad(bn, b_out, sizeof(b_out));
+ if (num_bytes < 0) {
ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
return 0;
}
- num_bytes = BN_bn2bin(bn, b_in);
- flip_endian(b_out, b_in, num_bytes);
bin32_to_felem(out, b_out);
return 1;
}
@@ -179,10 +167,9 @@ static int BN_to_felem(felem out, const BIGNUM *bn)
/* felem_to_BN converts an felem into an OpenSSL BIGNUM */
static BIGNUM *smallfelem_to_BN(BIGNUM *out, const smallfelem in)
{
- felem_bytearray b_in, b_out;
- smallfelem_to_bin32(b_in, in);
- flip_endian(b_out, b_in, sizeof(b_out));
- return BN_bin2bn(b_out, sizeof(b_out), out);
+ felem_bytearray b_out;
+ smallfelem_to_bin32(b_out, in);
+ return bn_lebin2bn(b_out, sizeof(b_out), out);
}
/*-
@@ -2014,8 +2001,8 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
felem_bytearray *secrets = NULL;
smallfelem(*pre_comp)[17][3] = NULL;
smallfelem *tmp_smallfelems = NULL;
- felem_bytearray tmp;
- unsigned i, num_bytes;
+ unsigned i;
+ int num_bytes;
int have_pre_comp = 0;
size_t num_points = num;
smallfelem x_in, y_in, z_in;
@@ -2097,17 +2084,15 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
memset(secrets, 0, num_points * sizeof(felem_bytearray));
memset(pre_comp, 0, num_points * 17 * 3 * sizeof(smallfelem));
for (i = 0; i < num_points; ++i) {
- if (i == num)
+ if (i == num) {
/*
* we didn't have a valid precomputation, so we pick the
* generator
*/
- {
p = EC_GROUP_get0_generator(group);
p_scalar = scalar;
- } else
+ } else {
/* the i^th point */
- {
p = points[i];
p_scalar = scalars[i];
}
@@ -2123,10 +2108,16 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
goto err;
}
- num_bytes = BN_bn2bin(tmp_scalar, tmp);
- } else
- num_bytes = BN_bn2bin(p_scalar, tmp);
- flip_endian(secrets[i], tmp, num_bytes);
+ num_bytes = bn_bn2lebinpad(tmp_scalar,
+ secrets[i], sizeof(secrets[i]));
+ } else {
+ num_bytes = bn_bn2lebinpad(p_scalar,
+ secrets[i], sizeof(secrets[i]));
+ }
+ if (num_bytes < 0) {
+ ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
+ goto err;
+ }
/* precompute multiples */
if ((!BN_to_felem(x_out, &p->X)) ||
(!BN_to_felem(y_out, &p->Y)) ||
@@ -2171,20 +2162,21 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
goto err;
}
- num_bytes = BN_bn2bin(tmp_scalar, tmp);
- } else
- num_bytes = BN_bn2bin(scalar, tmp);
- flip_endian(g_secret, tmp, num_bytes);
+ num_bytes = bn_bn2lebinpad(tmp_scalar, g_secret, sizeof(g_secret));
+ } else {
+ num_bytes = bn_bn2lebinpad(scalar, g_secret, sizeof(g_secret));
+ }
/* do the multiplication with generator precomputation */
batch_mul(x_out, y_out, z_out,
(const felem_bytearray(*))secrets, num_points,
g_secret,
mixed, (const smallfelem(*)[17][3])pre_comp, g_pre_comp);
- } else
+ } else {
/* do the multiplication without generator precomputation */
batch_mul(x_out, y_out, z_out,
(const felem_bytearray(*))secrets, num_points,
NULL, mixed, (const smallfelem(*)[17][3])pre_comp, NULL);
+ }
/* reduce the output to its unique minimal representation */
felem_contract(x_in, x_out);
felem_contract(y_in, y_out);
diff --git a/crypto/ec/ecp_nistp521.c b/crypto/ec/ecp_nistp521.c
index 1a42068..007cffa 100644
--- a/crypto/ec/ecp_nistp521.c
+++ b/crypto/ec/ecp_nistp521.c
@@ -38,6 +38,7 @@
# include <string.h>
# include <openssl/err.h>
# include "ec_lcl.h"
+# include "bn_int.h" /* bn_bn2lebinpad, bn_lebin2bn */
# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
/* even with gcc, the typedef won't work for 32-bit platforms */
@@ -168,34 +169,21 @@ static void felem_to_bin66(u8 out[66], const felem in)
(*((limb *) & out[58])) = in[8];
}
-/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
-static void flip_endian(u8 *out, const u8 *in, unsigned len)
-{
- unsigned i;
- for (i = 0; i < len; ++i)
- out[i] = in[len - 1 - i];
-}
-
/* BN_to_felem converts an OpenSSL BIGNUM into an felem */
static int BN_to_felem(felem out, const BIGNUM *bn)
{
- felem_bytearray b_in;
felem_bytearray b_out;
- unsigned num_bytes;
+ int num_bytes;
- /* BN_bn2bin eats leading zeroes */
- memset(b_out, 0, sizeof(b_out));
- num_bytes = BN_num_bytes(bn);
- if (num_bytes > sizeof(b_out)) {
+ if (BN_is_negative(bn)) {
ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
return 0;
}
- if (BN_is_negative(bn)) {
+ num_bytes = bn_bn2lebinpad(bn, b_out, sizeof(b_out));
+ if (num_bytes < 0) {
ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
return 0;
}
- num_bytes = BN_bn2bin(bn, b_in);
- flip_endian(b_out, b_in, num_bytes);
bin66_to_felem(out, b_out);
return 1;
}
@@ -203,10 +191,9 @@ static int BN_to_felem(felem out, const BIGNUM *bn)
/* felem_to_BN converts an felem into an OpenSSL BIGNUM */
static BIGNUM *felem_to_BN(BIGNUM *out, const felem in)
{
- felem_bytearray b_in, b_out;
- felem_to_bin66(b_in, in);
- flip_endian(b_out, b_in, sizeof(b_out));
- return BN_bin2bn(b_out, sizeof(b_out), out);
+ felem_bytearray b_out;
+ felem_to_bin66(b_out, in);
+ return bn_lebin2bn(b_out, sizeof(b_out), out);
}
/*-
@@ -1826,8 +1813,8 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
felem_bytearray *secrets = NULL;
felem(*pre_comp)[17][3] = NULL;
felem *tmp_felems = NULL;
- felem_bytearray tmp;
- unsigned i, num_bytes;
+ unsigned i;
+ int num_bytes;
int have_pre_comp = 0;
size_t num_points = num;
felem x_in, y_in, z_in, x_out, y_out, z_out;
@@ -1909,17 +1896,15 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
memset(secrets, 0, num_points * sizeof(felem_bytearray));
memset(pre_comp, 0, num_points * 17 * 3 * sizeof(felem));
for (i = 0; i < num_points; ++i) {
- if (i == num)
+ if (i == num) {
/*
* we didn't have a valid precomputation, so we pick the
* generator
*/
- {
p = EC_GROUP_get0_generator(group);
p_scalar = scalar;
- } else
+ } else {
/* the i^th point */
- {
p = points[i];
p_scalar = scalars[i];
}
@@ -1935,10 +1920,16 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
goto err;
}
- num_bytes = BN_bn2bin(tmp_scalar, tmp);
- } else
- num_bytes = BN_bn2bin(p_scalar, tmp);
- flip_endian(secrets[i], tmp, num_bytes);
+ num_bytes = bn_bn2lebinpad(tmp_scalar,
+ secrets[i], sizeof(secrets[i]));
+ } else {
+ num_bytes = bn_bn2lebinpad(p_scalar,
+ secrets[i], sizeof(secrets[i]));
+ }
+ if (num_bytes < 0) {
+ ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
+ goto err;
+ }
/* precompute multiples */
if ((!BN_to_felem(x_out, &p->X)) ||
(!BN_to_felem(y_out, &p->Y)) ||
@@ -1981,21 +1972,22 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
goto err;
}
- num_bytes = BN_bn2bin(tmp_scalar, tmp);
- } else
- num_bytes = BN_bn2bin(scalar, tmp);
- flip_endian(g_secret, tmp, num_bytes);
+ num_bytes = bn_bn2lebinpad(tmp_scalar, g_secret, sizeof(g_secret));
+ } else {
+ num_bytes = bn_bn2lebinpad(scalar, g_secret, sizeof(g_secret));
+ }
/* do the multiplication with generator precomputation */
batch_mul(x_out, y_out, z_out,
(const felem_bytearray(*))secrets, num_points,
g_secret,
mixed, (const felem(*)[17][3])pre_comp,
(const felem(*)[3])g_pre_comp);
- } else
+ } else {
/* do the multiplication without generator precomputation */
batch_mul(x_out, y_out, z_out,
(const felem_bytearray(*))secrets, num_points,
NULL, mixed, (const felem(*)[17][3])pre_comp, NULL);
+ }
/* reduce the output to its unique minimal representation */
felem_contract(x_in, x_out);
felem_contract(y_in, y_out);
diff --git a/crypto/opensslv.h b/crypto/opensslv.h
index 8b47569..488e2bc 100644
--- a/crypto/opensslv.h
+++ b/crypto/opensslv.h
@@ -30,11 +30,11 @@ 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 0x1000213fL
+# define OPENSSL_VERSION_NUMBER 0x1000214fL
# ifdef OPENSSL_FIPS
-# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2s-fips 28 May 2019"
+# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2t-fips 10 Sep 2019"
# else
-# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2s 28 May 2019"
+# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2t 10 Sep 2019"
# endif
# define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT
diff --git a/crypto/pem/pvkfmt.c b/crypto/pem/pvkfmt.c
index f376f59..9ea21e3 100644
--- a/crypto/pem/pvkfmt.c
+++ b/crypto/pem/pvkfmt.c
@@ -3,7 +3,7 @@
* 2005.
*/
/* ====================================================================
- * Copyright (c) 2005-2018 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 2005-2019 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -327,6 +327,8 @@ static EVP_PKEY *b2i_dss(const unsigned char **in, unsigned int length,
} else {
if (!read_lebn(&p, 20, &dsa->priv_key))
goto memerr;
+ /* Set constant time flag before public key calculation */
+ BN_set_flags(dsa->priv_key, BN_FLG_CONSTTIME);
/* Calculate public key */
if (!(dsa->pub_key = BN_new()))
goto memerr;
diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c
index 6a46368..63bc882 100644
--- a/crypto/pkcs7/pk7_doit.c
+++ b/crypto/pkcs7/pk7_doit.c
@@ -191,7 +191,8 @@ static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri,
}
static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen,
- PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey)
+ PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey,
+ size_t fixlen)
{
EVP_PKEY_CTX *pctx = NULL;
unsigned char *ek = NULL;
@@ -224,7 +225,9 @@ static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen,
}
if (EVP_PKEY_decrypt(pctx, ek, &eklen,
- ri->enc_key->data, ri->enc_key->length) <= 0) {
+ ri->enc_key->data, ri->enc_key->length) <= 0
+ || eklen == 0
+ || (fixlen != 0 && eklen != fixlen)) {
ret = 0;
PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB);
goto err;
@@ -571,13 +574,14 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
- if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0)
+ if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey,
+ EVP_CIPHER_key_length(evp_cipher)) < 0)
goto err;
ERR_clear_error();
}
} else {
/* Only exit on fatal errors, not decrypt failure */
- if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0)
+ if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey, 0) < 0)
goto err;
ERR_clear_error();
}
diff --git a/crypto/rsa/rsa_chk.c b/crypto/rsa/rsa_chk.c
index 475dfc5..fb62c35 100644
--- a/crypto/rsa/rsa_chk.c
+++ b/crypto/rsa/rsa_chk.c
@@ -1,6 +1,6 @@
/* crypto/rsa/rsa_chk.c */
/* ====================================================================
- * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-2019 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -63,6 +63,10 @@ int RSA_check_key(const RSA *key)
return 0;
}
+ /* Set consant-time flag on private parameters */
+ BN_set_flags(key->p, BN_FLG_CONSTTIME);
+ BN_set_flags(key->q, BN_FLG_CONSTTIME);
+ BN_set_flags(key->d, BN_FLG_CONSTTIME);
i = BN_new();
j = BN_new();
k = BN_new();
@@ -141,6 +145,10 @@ int RSA_check_key(const RSA *key)
}
if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL) {
+ /* Set consant-time flag on CRT parameters */
+ BN_set_flags(key->dmp1, BN_FLG_CONSTTIME);
+ BN_set_flags(key->dmq1, BN_FLG_CONSTTIME);
+ BN_set_flags(key->iqmp, BN_FLG_CONSTTIME);
/* dmp1 = d mod (p-1)? */
if (!BN_sub(i, key->p, BN_value_one())) {
ret = -1;
diff --git a/crypto/x509/x509_cmp.c b/crypto/x509/x509_cmp.c
index 2d82f8f..a7b90e6 100644
--- a/crypto/x509/x509_cmp.c
+++ b/crypto/x509/x509_cmp.c
@@ -490,6 +490,8 @@ STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain)
STACK_OF(X509) *ret;
int i;
ret = sk_X509_dup(chain);
+ if (ret == NULL)
+ return NULL;
for (i = 0; i < sk_X509_num(ret); i++) {
X509 *x = sk_X509_value(ret, i);
CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
diff --git a/crypto/x509v3/v3_alt.c b/crypto/x509v3/v3_alt.c
index d4d024c..a594b07 100644
--- a/crypto/x509v3/v3_alt.c
+++ b/crypto/x509v3/v3_alt.c
@@ -4,7 +4,7 @@
* project.
*/
/* ====================================================================
- * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-2019 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -205,15 +205,18 @@ int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
break;
case GEN_EMAIL:
- BIO_printf(out, "email:%s", gen->d.ia5->data);
+ BIO_printf(out, "email:");
+ ASN1_STRING_print(out, gen->d.ia5);
break;
case GEN_DNS:
- BIO_printf(out, "DNS:%s", gen->d.ia5->data);
+ BIO_printf(out, "DNS:");
+ ASN1_STRING_print(out, gen->d.ia5);
break;
case GEN_URI:
- BIO_printf(out, "URI:%s", gen->d.ia5->data);
+ BIO_printf(out, "URI:");
+ ASN1_STRING_print(out, gen->d.ia5);
break;
case GEN_DIRNAME:
diff --git a/openssl.spec b/openssl.spec
index 7e94a22..475ddcf 100644
--- a/openssl.spec
+++ b/openssl.spec
@@ -7,7 +7,7 @@ Release: 1
Summary: Secure Sockets Layer and cryptography libraries and tools
Name: openssl
-Version: 1.0.2s
+Version: 1.0.2t
Source0: ftp://ftp.openssl.org/source/%{name}-%{version}.tar.gz
License: OpenSSL
Group: System Environment/Libraries
diff --git a/packaging/openssl.spec b/packaging/openssl.spec
index 074e044..41eadc4 100644
--- a/packaging/openssl.spec
+++ b/packaging/openssl.spec
@@ -3,7 +3,7 @@
Summary: Secure Sockets Layer and cryptography libraries and tools
Name: openssl
-Version: 1.0.2s
+Version: 1.0.2t
Release: 0
License: OpenSSL and Apache-2.0 and BSD-3-Clause
Group: Security/Crypto Libraries
diff --git a/util/libeay.num b/util/libeay.num
index 2e52214..3a72e46 100755
--- a/util/libeay.num
+++ b/util/libeay.num
@@ -4432,3 +4432,4 @@ EVP_PKEY_meth_get_cleanup 4786 EXIST::FUNCTION:
EVP_PKEY_meth_get_encrypt 4787 EXIST::FUNCTION:
EVP_PKEY_meth_get_copy 4788 EXIST::FUNCTION:
ossl_safe_getenv 4789 EXIST::FUNCTION:
+OPENSSL_rdtsc 4790 EXIST::FUNCTION: