summaryrefslogtreecommitdiff
path: root/src/crypto
diff options
context:
space:
mode:
authorRobert Sloan <varomodt@google.com>2017-10-30 14:10:28 -0700
committerRobert Sloan <varomodt@google.com>2017-10-30 14:10:51 -0700
commit29c1d2cf8620ad14e06d8e7ff91db8f4de04d481 (patch)
tree40c62dc13cf10cc29eab8e9caf1f6cf7a86ffee4 /src/crypto
parenta7dc4759b5f834b50a9be8dd3ec1abb7ff3e5bc5 (diff)
downloadboringssl-29c1d2cf8620ad14e06d8e7ff91db8f4de04d481.tar.gz
external/boringssl: Sync to ba94746eb2b4b59a0eb72047e4ca2d2d54454c87.
This includes the following changes: https://boringssl.googlesource.com/boringssl/+log/7f8c553d7f4db0a6ce727f2986d41bf8fe8ec4bf..ba94746eb2b4b59a0eb72047e4ca2d2d54454c87 Test: BoringSSL CTS Presubmits Change-Id: I5283ca8ec80f4abbc2543fece2ecf2b33240c6e4
Diffstat (limited to 'src/crypto')
-rw-r--r--src/crypto/asn1/a_enum.c29
-rw-r--r--src/crypto/asn1/a_int.c27
-rw-r--r--src/crypto/asn1/asn1_locl.h3
-rw-r--r--src/crypto/asn1/tasn_fre.c6
-rw-r--r--src/crypto/asn1/tasn_new.c5
-rw-r--r--src/crypto/bn_extra/bn_asn1.c16
-rw-r--r--src/crypto/cpu-intel.c34
-rw-r--r--src/crypto/crypto.c20
-rw-r--r--src/crypto/ecdh/ecdh_test.cc97
-rw-r--r--src/crypto/evp/p_rsa_asn1.c23
-rw-r--r--src/crypto/ex_data.c1
-rw-r--r--src/crypto/fipsmodule/bn/add.c18
-rw-r--r--src/crypto/fipsmodule/bn/bn_test.cc66
-rw-r--r--src/crypto/fipsmodule/bn/bn_test_to_fuzzer.go234
-rw-r--r--src/crypto/fipsmodule/bn/div.c7
-rw-r--r--src/crypto/fipsmodule/bn/exponentiation.c8
-rw-r--r--src/crypto/fipsmodule/bn/generic.c50
-rw-r--r--src/crypto/fipsmodule/bn/internal.h4
-rw-r--r--src/crypto/fipsmodule/bn/montgomery.c4
-rw-r--r--src/crypto/fipsmodule/bn/mul.c33
-rw-r--r--src/crypto/fipsmodule/bn/shift.c35
-rw-r--r--src/crypto/fipsmodule/ec/ec.c167
-rw-r--r--src/crypto/fipsmodule/ec/ec_montgomery.c27
-rw-r--r--src/crypto/fipsmodule/ec/ec_test.cc27
-rw-r--r--src/crypto/fipsmodule/ec/internal.h13
-rw-r--r--src/crypto/fipsmodule/ec/oct.c6
-rw-r--r--src/crypto/fipsmodule/ec/p224-64.c1
-rw-r--r--src/crypto/fipsmodule/ec/p256-64.c1
-rw-r--r--src/crypto/fipsmodule/ec/p256-x86_64.c1
-rw-r--r--src/crypto/fipsmodule/ec/simple.c24
-rw-r--r--src/crypto/fipsmodule/ec/wnaf.c2
-rw-r--r--src/crypto/lhash/lhash.c19
-rw-r--r--src/crypto/pem/pem_lib.c4
-rw-r--r--src/crypto/rsa_extra/rsa_asn1.c25
-rw-r--r--src/crypto/rsa_extra/rsa_test.cc7
-rw-r--r--src/crypto/x509/by_dir.c4
-rw-r--r--src/crypto/x509/by_file.c1
-rw-r--r--src/crypto/x509/x509_lu.c1
-rw-r--r--src/crypto/x509/x509_obj.c4
-rw-r--r--src/crypto/x509/x509_txt.c6
-rw-r--r--src/crypto/x509/x509_vfy.c1
-rw-r--r--src/crypto/x509/x509_vpm.c1
-rw-r--r--src/crypto/x509v3/v3_alt.c7
-rw-r--r--src/crypto/x509v3/v3_genn.c1
-rw-r--r--src/crypto/x509v3/v3_info.c3
45 files changed, 664 insertions, 409 deletions
diff --git a/src/crypto/asn1/a_enum.c b/src/crypto/asn1/a_enum.c
index cc469055..4a779718 100644
--- a/src/crypto/asn1/a_enum.c
+++ b/src/crypto/asn1/a_enum.c
@@ -56,6 +56,7 @@
#include <openssl/asn1.h>
+#include <limits.h>
#include <string.h>
#include <openssl/err.h>
@@ -110,7 +111,6 @@ int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a)
{
int neg = 0, i;
- long r = 0;
if (a == NULL)
return (0L);
@@ -120,20 +120,31 @@ long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a)
else if (i != V_ASN1_ENUMERATED)
return -1;
- if (a->length > (int)sizeof(long)) {
+ OPENSSL_COMPILE_ASSERT(sizeof(uint64_t) >= sizeof(long),
+ long_larger_than_uint64_t);
+
+ if (a->length > (int)sizeof(uint64_t)) {
/* hmm... a bit ugly */
- return (0xffffffffL);
+ return -1;
}
- if (a->data == NULL)
- return 0;
- for (i = 0; i < a->length; i++) {
- r <<= 8;
- r |= (unsigned char)a->data[i];
+ uint64_t r64 = 0;
+ if (a->data != NULL) {
+ for (i = 0; i < a->length; i++) {
+ r64 <<= 8;
+ r64 |= (unsigned char)a->data[i];
+ }
+
+ if (r64 > LONG_MAX) {
+ return -1;
+ }
}
+
+ long r = (long) r64;
if (neg)
r = -r;
- return (r);
+
+ return r;
}
ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
diff --git a/src/crypto/asn1/a_int.c b/src/crypto/asn1/a_int.c
index 617ba962..8a4edd69 100644
--- a/src/crypto/asn1/a_int.c
+++ b/src/crypto/asn1/a_int.c
@@ -57,6 +57,7 @@
#include <openssl/asn1.h>
#include <string.h>
+#include <limits.h>
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -385,7 +386,6 @@ int ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
long ASN1_INTEGER_get(const ASN1_INTEGER *a)
{
int neg = 0, i;
- long r = 0;
if (a == NULL)
return (0L);
@@ -395,20 +395,31 @@ long ASN1_INTEGER_get(const ASN1_INTEGER *a)
else if (i != V_ASN1_INTEGER)
return -1;
- if (a->length > (int)sizeof(long)) {
+ OPENSSL_COMPILE_ASSERT(sizeof(uint64_t) >= sizeof(long),
+ long_larger_than_uint64_t);
+
+ if (a->length > (int)sizeof(uint64_t)) {
/* hmm... a bit ugly, return all ones */
return -1;
}
- if (a->data == NULL)
- return 0;
- for (i = 0; i < a->length; i++) {
- r <<= 8;
- r |= (unsigned char)a->data[i];
+ uint64_t r64 = 0;
+ if (a->data != NULL) {
+ for (i = 0; i < a->length; i++) {
+ r64 <<= 8;
+ r64 |= (unsigned char)a->data[i];
+ }
+
+ if (r64 > LONG_MAX) {
+ return -1;
+ }
}
+
+ long r = (long) r64;
if (neg)
r = -r;
- return (r);
+
+ return r;
}
ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
diff --git a/src/crypto/asn1/asn1_locl.h b/src/crypto/asn1/asn1_locl.h
index fef00acf..10a832cd 100644
--- a/src/crypto/asn1/asn1_locl.h
+++ b/src/crypto/asn1/asn1_locl.h
@@ -90,6 +90,9 @@ int OPENSSL_gmtime_diff(int *out_days, int *out_secs, const struct tm *from,
int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d);
int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d);
+void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
+ int combine);
+
#if defined(__cplusplus)
} /* extern C */
diff --git a/src/crypto/asn1/tasn_fre.c b/src/crypto/asn1/tasn_fre.c
index 609cb9f9..eabc0fb5 100644
--- a/src/crypto/asn1/tasn_fre.c
+++ b/src/crypto/asn1/tasn_fre.c
@@ -59,8 +59,7 @@
#include <openssl/asn1t.h>
#include <openssl/mem.h>
-static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
- int combine);
+#include "asn1_locl.h"
/* Free up an ASN1 structure */
@@ -74,8 +73,7 @@ void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
asn1_item_combine_free(pval, it, 0);
}
-static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
- int combine)
+void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
{
const ASN1_TEMPLATE *tt = NULL, *seqtt;
const ASN1_EXTERN_FUNCS *ef;
diff --git a/src/crypto/asn1/tasn_new.c b/src/crypto/asn1/tasn_new.c
index 10cf954f..5db38bef 100644
--- a/src/crypto/asn1/tasn_new.c
+++ b/src/crypto/asn1/tasn_new.c
@@ -63,6 +63,7 @@
#include <openssl/mem.h>
#include <openssl/obj.h>
+#include "asn1_locl.h"
#include "../internal.h"
@@ -201,7 +202,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
return 1;
memerr2:
- ASN1_item_ex_free(pval, it);
+ asn1_item_combine_free(pval, it, combine);
memerr:
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
#ifdef CRYPTO_MDEBUG
@@ -211,7 +212,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
return 0;
auxerr2:
- ASN1_item_ex_free(pval, it);
+ asn1_item_combine_free(pval, it, combine);
auxerr:
OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
#ifdef CRYPTO_MDEBUG
diff --git a/src/crypto/bn_extra/bn_asn1.c b/src/crypto/bn_extra/bn_asn1.c
index 8b939da5..0d96573a 100644
--- a/src/crypto/bn_extra/bn_asn1.c
+++ b/src/crypto/bn_extra/bn_asn1.c
@@ -42,22 +42,6 @@ int BN_parse_asn1_unsigned(CBS *cbs, BIGNUM *ret) {
return BN_bin2bn(CBS_data(&child), CBS_len(&child), ret) != NULL;
}
-int BN_parse_asn1_unsigned_buggy(CBS *cbs, BIGNUM *ret) {
- CBS child;
- if (!CBS_get_asn1(cbs, &child, CBS_ASN1_INTEGER) ||
- CBS_len(&child) == 0) {
- OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING);
- return 0;
- }
-
- // This function intentionally does not reject negative numbers or non-minimal
- // encodings. Estonian IDs issued between September 2014 to September 2015 are
- // broken. See https://crbug.com/532048 and https://crbug.com/534766.
- //
- // TODO(davidben): Remove this code and callers in March 2016.
- return BN_bin2bn(CBS_data(&child), CBS_len(&child), ret) != NULL;
-}
-
int BN_marshal_asn1(CBB *cbb, const BIGNUM *bn) {
// Negative numbers are unsupported.
if (BN_is_negative(bn)) {
diff --git a/src/crypto/cpu-intel.c b/src/crypto/cpu-intel.c
index 127fa57a..1ac280c8 100644
--- a/src/crypto/cpu-intel.c
+++ b/src/crypto/cpu-intel.c
@@ -164,7 +164,7 @@ void OPENSSL_cpuid_setup(void) {
uint32_t num_extended_ids = eax;
if (num_extended_ids >= 0x80000001) {
OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 0x80000001);
- if (ecx & (1 << 11)) {
+ if (ecx & (1u << 11)) {
has_amd_xop = 1;
}
}
@@ -193,68 +193,68 @@ void OPENSSL_cpuid_setup(void) {
OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 1);
// Adjust the hyper-threading bit.
- if (edx & (1 << 28)) {
+ if (edx & (1u << 28)) {
uint32_t num_logical_cores = (ebx >> 16) & 0xff;
if (cores_per_cache == 1 || num_logical_cores <= 1) {
- edx &= ~(1 << 28);
+ edx &= ~(1u << 28);
}
}
// Reserved bit #20 was historically repurposed to control the in-memory
// representation of RC4 state. Always set it to zero.
- edx &= ~(1 << 20);
+ edx &= ~(1u << 20);
// Reserved bit #30 is repurposed to signal an Intel CPU.
if (is_intel) {
- edx |= (1 << 30);
+ edx |= (1u << 30);
// Clear the XSAVE bit on Knights Landing to mimic Silvermont. This enables
// some Silvermont-specific codepaths which perform better. See OpenSSL
// commit 64d92d74985ebb3d0be58a9718f9e080a14a8e7f.
if ((eax & 0x0fff0ff0) == 0x00050670 /* Knights Landing */ ||
(eax & 0x0fff0ff0) == 0x00080650 /* Knights Mill (per SDE) */) {
- ecx &= ~(1 << 26);
+ ecx &= ~(1u << 26);
}
} else {
- edx &= ~(1 << 30);
+ edx &= ~(1u << 30);
}
// The SDBG bit is repurposed to denote AMD XOP support.
if (has_amd_xop) {
- ecx |= (1 << 11);
+ ecx |= (1u << 11);
} else {
- ecx &= ~(1 << 11);
+ ecx &= ~(1u << 11);
}
uint64_t xcr0 = 0;
- if (ecx & (1 << 27)) {
+ if (ecx & (1u << 27)) {
// XCR0 may only be queried if the OSXSAVE bit is set.
xcr0 = OPENSSL_xgetbv(0);
}
// See Intel manual, volume 1, section 14.3.
if ((xcr0 & 6) != 6) {
// YMM registers cannot be used.
- ecx &= ~(1 << 28); // AVX
- ecx &= ~(1 << 12); // FMA
- ecx &= ~(1 << 11); // AMD XOP
+ ecx &= ~(1u << 28); // AVX
+ ecx &= ~(1u << 12); // FMA
+ ecx &= ~(1u << 11); // AMD XOP
// Clear AVX2 and AVX512* bits.
//
// TODO(davidben): Should bits 17 and 26-28 also be cleared? Upstream
// doesn't clear those.
extended_features &=
- ~((1 << 5) | (1 << 16) | (1 << 21) | (1 << 30) | (1 << 31));
+ ~((1u << 5) | (1u << 16) | (1u << 21) | (1u << 30) | (1u << 31));
}
// See Intel manual, volume 1, section 15.2.
if ((xcr0 & 0xe6) != 0xe6) {
// Clear AVX512F. Note we don't touch other AVX512 extensions because they
// can be used with YMM.
- extended_features &= ~(1 << 16);
+ extended_features &= ~(1u << 16);
}
// Disable ADX instructions on Knights Landing. See OpenSSL commit
// 64d92d74985ebb3d0be58a9718f9e080a14a8e7f.
- if ((ecx & (1 << 26)) == 0) {
- extended_features &= ~(1 << 19);
+ if ((ecx & (1u << 26)) == 0) {
+ extended_features &= ~(1u << 19);
}
OPENSSL_ia32cap_P[0] = edx;
diff --git a/src/crypto/crypto.c b/src/crypto/crypto.c
index 390cd8bb..9f4639f2 100644
--- a/src/crypto/crypto.c
+++ b/src/crypto/crypto.c
@@ -40,6 +40,18 @@
OPENSSL_ARM || OPENSSL_AARCH64) */
+// Our assembly does not use the GOT to reference symbols, which means
+// references to visible symbols will often require a TEXTREL. This is
+// undesirable, so all assembly-referenced symbols should be hidden. CPU
+// capabilities are the only such symbols defined in C. Explicitly hide them,
+// rather than rely on being built with -fvisibility=hidden.
+#if defined(OPENSSL_WINDOWS)
+#define HIDDEN
+#else
+#define HIDDEN __attribute__((visibility("hidden")))
+#endif
+
+
// The capability variables are defined in this file in order to work around a
// linker bug. When linking with a .a, if no symbols in a .o are referenced
// then the .o is discarded, even if it has constructor functions.
@@ -57,11 +69,11 @@
// archive, linking on OS X will fail to resolve common symbols. By
// initialising it to zero, it becomes a "data symbol", which isn't so
// affected.
-uint32_t OPENSSL_ia32cap_P[4] = {0};
+HIDDEN uint32_t OPENSSL_ia32cap_P[4] = {0};
#elif defined(OPENSSL_PPC64LE)
-unsigned long OPENSSL_ppc64le_hwcap2 = 0;
+HIDDEN unsigned long OPENSSL_ppc64le_hwcap2 = 0;
#elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
@@ -69,7 +81,7 @@ unsigned long OPENSSL_ppc64le_hwcap2 = 0;
#if defined(OPENSSL_STATIC_ARMCAP)
-uint32_t OPENSSL_armcap_P =
+HIDDEN uint32_t OPENSSL_armcap_P =
#if defined(OPENSSL_STATIC_ARMCAP_NEON) || defined(__ARM_NEON__)
ARMV7_NEON |
#endif
@@ -88,7 +100,7 @@ uint32_t OPENSSL_armcap_P =
0;
#else
-uint32_t OPENSSL_armcap_P = 0;
+HIDDEN uint32_t OPENSSL_armcap_P = 0;
#endif
#endif
diff --git a/src/crypto/ecdh/ecdh_test.cc b/src/crypto/ecdh/ecdh_test.cc
index b3114453..6d48408b 100644
--- a/src/crypto/ecdh/ecdh_test.cc
+++ b/src/crypto/ecdh/ecdh_test.cc
@@ -14,6 +14,7 @@
#include <stdio.h>
+#include <utility>
#include <vector>
#include <gtest/gtest.h>
@@ -23,6 +24,7 @@
#include <openssl/ec.h>
#include <openssl/ec_key.h>
#include <openssl/ecdh.h>
+#include <openssl/err.h>
#include <openssl/nid.h>
#include "../test/file_test.h"
@@ -112,3 +114,98 @@ TEST(ECDHTest, TestVectors) {
Bytes(actual_z.data(), static_cast<size_t>(ret)));
});
}
+
+// MakeCustomGroup returns an |EC_GROUP| containing a non-standard group. (P-256
+// with the wrong generator.)
+static bssl::UniquePtr<EC_GROUP> MakeCustomGroup() {
+ static const uint8_t kP[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ };
+ static const uint8_t kA[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
+ };
+ static const uint8_t kB[] = {
+ 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, 0xb3, 0xeb, 0xbd,
+ 0x55, 0x76, 0x98, 0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53,
+ 0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b,
+ };
+ static const uint8_t kX[] = {
+ 0xe6, 0x2b, 0x69, 0xe2, 0xbf, 0x65, 0x9f, 0x97, 0xbe, 0x2f, 0x1e,
+ 0x0d, 0x94, 0x8a, 0x4c, 0xd5, 0x97, 0x6b, 0xb7, 0xa9, 0x1e, 0x0d,
+ 0x46, 0xfb, 0xdd, 0xa9, 0xa9, 0x1e, 0x9d, 0xdc, 0xba, 0x5a,
+ };
+ static const uint8_t kY[] = {
+ 0x01, 0xe7, 0xd6, 0x97, 0xa8, 0x0a, 0x18, 0xf9, 0xc3, 0xc4, 0xa3,
+ 0x1e, 0x56, 0xe2, 0x7c, 0x83, 0x48, 0xdb, 0x16, 0x1a, 0x1c, 0xf5,
+ 0x1d, 0x7e, 0xf1, 0x94, 0x2d, 0x4b, 0xcf, 0x72, 0x22, 0xc1,
+ };
+ static const uint8_t kOrder[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17,
+ 0x9e, 0x84, 0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51,
+ };
+ bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
+ bssl::UniquePtr<BIGNUM> p(BN_bin2bn(kP, sizeof(kP), nullptr));
+ bssl::UniquePtr<BIGNUM> a(BN_bin2bn(kA, sizeof(kA), nullptr));
+ bssl::UniquePtr<BIGNUM> b(BN_bin2bn(kB, sizeof(kB), nullptr));
+ bssl::UniquePtr<BIGNUM> x(BN_bin2bn(kX, sizeof(kX), nullptr));
+ bssl::UniquePtr<BIGNUM> y(BN_bin2bn(kY, sizeof(kY), nullptr));
+ bssl::UniquePtr<BIGNUM> order(BN_bin2bn(kOrder, sizeof(kOrder), nullptr));
+ if (!ctx || !p || !a || !b || !x || !y || !order) {
+ return nullptr;
+ }
+ bssl::UniquePtr<EC_GROUP> group(
+ EC_GROUP_new_curve_GFp(p.get(), a.get(), b.get(), ctx.get()));
+ if (!group) {
+ return nullptr;
+ }
+ bssl::UniquePtr<EC_POINT> generator(EC_POINT_new(group.get()));
+ if (!generator ||
+ !EC_POINT_set_affine_coordinates_GFp(group.get(), generator.get(),
+ x.get(), y.get(), ctx.get()) ||
+ !EC_GROUP_set_generator(group.get(), generator.get(), order.get(),
+ BN_value_one())) {
+ return nullptr;
+ }
+ return group;
+}
+
+TEST(ECDHTest, GroupMismatch) {
+ const size_t num_curves = EC_get_builtin_curves(nullptr, 0);
+ std::vector<EC_builtin_curve> curves(num_curves);
+ EC_get_builtin_curves(curves.data(), num_curves);
+
+ // Instantiate all the built-in curves.
+ std::vector<bssl::UniquePtr<EC_GROUP>> groups;
+ for (const auto &curve : curves) {
+ groups.emplace_back(EC_GROUP_new_by_curve_name(curve.nid));
+ ASSERT_TRUE(groups.back());
+ }
+
+ // Also create some arbitrary group. (This is P-256 with the wrong generator.)
+ groups.push_back(MakeCustomGroup());
+ ASSERT_TRUE(groups.back());
+
+ for (const auto &a : groups) {
+ for (const auto &b : groups) {
+ if (a.get() == b.get()) {
+ continue;
+ }
+
+ bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
+ ASSERT_TRUE(EC_KEY_set_group(key.get(), a.get()));
+ ASSERT_TRUE(EC_KEY_generate_key(key.get()));
+
+ // ECDH across the groups should not work.
+ char out[64];
+ const EC_POINT *peer = EC_GROUP_get0_generator(b.get());
+ EXPECT_EQ(-1,
+ ECDH_compute_key(out, sizeof(out), peer, key.get(), nullptr));
+ ERR_clear_error();
+ }
+ }
+}
diff --git a/src/crypto/evp/p_rsa_asn1.c b/src/crypto/evp/p_rsa_asn1.c
index 5157a89d..a1885383 100644
--- a/src/crypto/evp/p_rsa_asn1.c
+++ b/src/crypto/evp/p_rsa_asn1.c
@@ -63,19 +63,9 @@
#include <openssl/rsa.h>
#include "../fipsmodule/rsa/internal.h"
-#include "../internal.h"
#include "internal.h"
-static struct CRYPTO_STATIC_MUTEX g_buggy_lock = CRYPTO_STATIC_MUTEX_INIT;
-static int g_buggy = 0;
-
-void EVP_set_buggy_rsa_parser(int buggy) {
- CRYPTO_STATIC_MUTEX_lock_write(&g_buggy_lock);
- g_buggy = buggy;
- CRYPTO_STATIC_MUTEX_unlock_write(&g_buggy_lock);
-}
-
static int rsa_pub_encode(CBB *out, const EVP_PKEY *key) {
// See RFC 3279, section 2.3.1.
CBB spki, algorithm, oid, null, key_bitstring;
@@ -96,11 +86,6 @@ static int rsa_pub_encode(CBB *out, const EVP_PKEY *key) {
}
static int rsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) {
- int buggy;
- CRYPTO_STATIC_MUTEX_lock_read(&g_buggy_lock);
- buggy = g_buggy;
- CRYPTO_STATIC_MUTEX_unlock_read(&g_buggy_lock);
-
// See RFC 3279, section 2.3.1.
// The parameters must be NULL.
@@ -112,13 +97,7 @@ static int rsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) {
return 0;
}
- // Estonian IDs issued between September 2014 to September 2015 are
- // broken. See https://crbug.com/532048 and https://crbug.com/534766.
- //
- // TODO(davidben): Switch this to the strict version in March 2016 or when
- // Chromium can force client certificates down a different codepath, whichever
- // comes first.
- RSA *rsa = buggy ? RSA_parse_public_key_buggy(key) : RSA_parse_public_key(key);
+ RSA *rsa = RSA_parse_public_key(key);
if (rsa == NULL || CBS_len(key) != 0) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
RSA_free(rsa);
diff --git a/src/crypto/ex_data.c b/src/crypto/ex_data.c
index af7e7e2d..71d60a52 100644
--- a/src/crypto/ex_data.c
+++ b/src/crypto/ex_data.c
@@ -113,7 +113,6 @@
#include <openssl/crypto.h>
#include <openssl/err.h>
-#include <openssl/lhash.h>
#include <openssl/mem.h>
#include <openssl/stack.h>
#include <openssl/thread.h>
diff --git a/src/crypto/fipsmodule/bn/add.c b/src/crypto/fipsmodule/bn/add.c
index bbe275ed..201c526d 100644
--- a/src/crypto/fipsmodule/bn/add.c
+++ b/src/crypto/fipsmodule/bn/add.c
@@ -133,7 +133,7 @@ int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
while (dif) {
dif--;
t1 = *(ap++);
- t2 = (t1 + 1) & BN_MASK2;
+ t2 = t1 + 1;
*(rp++) = t2;
if (t2) {
carry = 0;
@@ -162,8 +162,6 @@ int BN_add_word(BIGNUM *a, BN_ULONG w) {
BN_ULONG l;
int i;
- w &= BN_MASK2;
-
// degenerate case: w is zero
if (!w) {
return 1;
@@ -185,7 +183,7 @@ int BN_add_word(BIGNUM *a, BN_ULONG w) {
}
for (i = 0; w != 0 && i < a->top; i++) {
- a->d[i] = l = (a->d[i] + w) & BN_MASK2;
+ a->d[i] = l = a->d[i] + w;
w = (w > l) ? 1 : 0;
}
@@ -285,12 +283,12 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
t2 = *(bp++);
if (carry) {
carry = (t1 <= t2);
- t1 = (t1 - t2 - 1) & BN_MASK2;
+ t1 -= t2 + 1;
} else {
carry = (t1 < t2);
- t1 = (t1 - t2) & BN_MASK2;
+ t1 -= t2;
}
- *(rp++) = t1 & BN_MASK2;
+ *(rp++) = t1;
}
if (carry) // subtracted
@@ -303,7 +301,7 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
while (dif) {
dif--;
t1 = *(ap++);
- t2 = (t1 - 1) & BN_MASK2;
+ t2 = t1 - 1;
*(rp++) = t2;
if (t1) {
break;
@@ -325,8 +323,6 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
int BN_sub_word(BIGNUM *a, BN_ULONG w) {
int i;
- w &= BN_MASK2;
-
// degenerate case: w is zero
if (!w) {
return 1;
@@ -361,7 +357,7 @@ int BN_sub_word(BIGNUM *a, BN_ULONG w) {
a->d[i] -= w;
break;
} else {
- a->d[i] = (a->d[i] - w) & BN_MASK2;
+ a->d[i] -= w;
i++;
w = 1;
}
diff --git a/src/crypto/fipsmodule/bn/bn_test.cc b/src/crypto/fipsmodule/bn/bn_test.cc
index fe03e5fa..975264e0 100644
--- a/src/crypto/fipsmodule/bn/bn_test.cc
+++ b/src/crypto/fipsmodule/bn/bn_test.cc
@@ -778,27 +778,27 @@ static int DecimalToBIGNUM(bssl::UniquePtr<BIGNUM> *out, const char *in) {
TEST_F(BNTest, Dec2BN) {
bssl::UniquePtr<BIGNUM> bn;
int ret = DecimalToBIGNUM(&bn, "0");
- EXPECT_EQ(1, ret);
+ ASSERT_EQ(1, ret);
EXPECT_TRUE(BN_is_zero(bn.get()));
EXPECT_FALSE(BN_is_negative(bn.get()));
ret = DecimalToBIGNUM(&bn, "256");
- EXPECT_EQ(3, ret);
+ ASSERT_EQ(3, ret);
EXPECT_TRUE(BN_is_word(bn.get(), 256));
EXPECT_FALSE(BN_is_negative(bn.get()));
ret = DecimalToBIGNUM(&bn, "-42");
- EXPECT_EQ(3, ret);
+ ASSERT_EQ(3, ret);
EXPECT_TRUE(BN_abs_is_word(bn.get(), 42));
EXPECT_TRUE(BN_is_negative(bn.get()));
ret = DecimalToBIGNUM(&bn, "-0");
- EXPECT_EQ(2, ret);
+ ASSERT_EQ(2, ret);
EXPECT_TRUE(BN_is_zero(bn.get()));
EXPECT_FALSE(BN_is_negative(bn.get()));
ret = DecimalToBIGNUM(&bn, "42trailing garbage is ignored");
- EXPECT_EQ(2, ret);
+ ASSERT_EQ(2, ret);
EXPECT_TRUE(BN_abs_is_word(bn.get(), 42));
EXPECT_FALSE(BN_is_negative(bn.get()));
}
@@ -806,27 +806,27 @@ TEST_F(BNTest, Dec2BN) {
TEST_F(BNTest, Hex2BN) {
bssl::UniquePtr<BIGNUM> bn;
int ret = HexToBIGNUM(&bn, "0");
- EXPECT_EQ(1, ret);
+ ASSERT_EQ(1, ret);
EXPECT_TRUE(BN_is_zero(bn.get()));
EXPECT_FALSE(BN_is_negative(bn.get()));
ret = HexToBIGNUM(&bn, "256");
- EXPECT_EQ(3, ret);
+ ASSERT_EQ(3, ret);
EXPECT_TRUE(BN_is_word(bn.get(), 0x256));
EXPECT_FALSE(BN_is_negative(bn.get()));
ret = HexToBIGNUM(&bn, "-42");
- EXPECT_EQ(3, ret);
+ ASSERT_EQ(3, ret);
EXPECT_TRUE(BN_abs_is_word(bn.get(), 0x42));
EXPECT_TRUE(BN_is_negative(bn.get()));
ret = HexToBIGNUM(&bn, "-0");
- EXPECT_EQ(2, ret);
+ ASSERT_EQ(2, ret);
EXPECT_TRUE(BN_is_zero(bn.get()));
EXPECT_FALSE(BN_is_negative(bn.get()));
ret = HexToBIGNUM(&bn, "abctrailing garbage is ignored");
- EXPECT_EQ(3, ret);
+ ASSERT_EQ(3, ret);
EXPECT_TRUE(BN_is_word(bn.get(), 0xabc));
EXPECT_FALSE(BN_is_negative(bn.get()));
}
@@ -1000,16 +1000,11 @@ static const ASN1InvalidTest kASN1InvalidTests[] = {
{"\x03\x01\x00", 3},
// Empty contents.
{"\x02\x00", 2},
-};
-
-// kASN1BuggyTests contains incorrect encodings and the corresponding, expected
-// results of |BN_parse_asn1_unsigned_buggy| given that input.
-static const ASN1Test kASN1BuggyTests[] = {
// Negative numbers.
- {"128", "\x02\x01\x80", 3},
- {"255", "\x02\x01\xff", 3},
+ {"\x02\x01\x80", 3},
+ {"\x02\x01\xff", 3},
// Unnecessary leading zeros.
- {"1", "\x02\x02\x00\x01", 4},
+ {"\x02\x02\x00\x01", 4},
};
TEST_F(BNTest, ASN1) {
@@ -1036,12 +1031,6 @@ TEST_F(BNTest, ASN1) {
ASSERT_TRUE(CBB_finish(cbb.get(), &der, &der_len));
bssl::UniquePtr<uint8_t> delete_der(der);
EXPECT_EQ(Bytes(test.der, test.der_len), Bytes(der, der_len));
-
- // |BN_parse_asn1_unsigned_buggy| parses all valid input.
- CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
- ASSERT_TRUE(BN_parse_asn1_unsigned_buggy(&cbs, bn2.get()));
- EXPECT_EQ(0u, CBS_len(&cbs));
- EXPECT_BIGNUMS_EQUAL("decode ASN.1 buggy", bn.get(), bn2.get());
}
for (const ASN1InvalidTest &test : kASN1InvalidTests) {
@@ -1053,35 +1042,6 @@ TEST_F(BNTest, ASN1) {
EXPECT_FALSE(BN_parse_asn1_unsigned(&cbs, bn.get()))
<< "Parsed invalid input.";
ERR_clear_error();
-
- // All tests in kASN1InvalidTests are also rejected by
- // |BN_parse_asn1_unsigned_buggy|.
- CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
- EXPECT_FALSE(BN_parse_asn1_unsigned_buggy(&cbs, bn.get()))
- << "Parsed invalid input.";
- ERR_clear_error();
- }
-
- for (const ASN1Test &test : kASN1BuggyTests) {
- SCOPED_TRACE(Bytes(test.der, test.der_len));
-
- // These broken encodings are rejected by |BN_parse_asn1_unsigned|.
- bssl::UniquePtr<BIGNUM> bn(BN_new());
- ASSERT_TRUE(bn);
- CBS cbs;
- CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
- EXPECT_FALSE(BN_parse_asn1_unsigned(&cbs, bn.get()))
- << "Parsed invalid input.";
- ERR_clear_error();
-
- // However |BN_parse_asn1_unsigned_buggy| accepts them.
- bssl::UniquePtr<BIGNUM> bn2 = ASCIIToBIGNUM(test.value_ascii);
- ASSERT_TRUE(bn2);
-
- CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
- ASSERT_TRUE(BN_parse_asn1_unsigned_buggy(&cbs, bn.get()));
- EXPECT_EQ(0u, CBS_len(&cbs));
- EXPECT_BIGNUMS_EQUAL("decode ASN.1 buggy", bn2.get(), bn.get());
}
// Serializing negative numbers is not supported.
diff --git a/src/crypto/fipsmodule/bn/bn_test_to_fuzzer.go b/src/crypto/fipsmodule/bn/bn_test_to_fuzzer.go
new file mode 100644
index 00000000..d1ee734c
--- /dev/null
+++ b/src/crypto/fipsmodule/bn/bn_test_to_fuzzer.go
@@ -0,0 +1,234 @@
+// Copyright (c) 2017, Google Inc.
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+package main
+
+import (
+ "bufio"
+ "crypto/sha1"
+ "encoding/hex"
+ "errors"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "math/big"
+ "os"
+ "path/filepath"
+ "strings"
+)
+
+type test struct {
+ LineNumber int
+ Type string
+ Values map[string]*big.Int
+}
+
+type testScanner struct {
+ scanner *bufio.Scanner
+ lineNo int
+ err error
+ test test
+}
+
+func newTestScanner(r io.Reader) *testScanner {
+ return &testScanner{scanner: bufio.NewScanner(r)}
+}
+
+func (s *testScanner) scanLine() bool {
+ if !s.scanner.Scan() {
+ return false
+ }
+ s.lineNo++
+ return true
+}
+
+func (s *testScanner) addAttribute(line string) (key string, ok bool) {
+ fields := strings.SplitN(line, "=", 2)
+ if len(fields) != 2 {
+ s.setError(errors.New("invalid syntax"))
+ return "", false
+ }
+
+ key = strings.TrimSpace(fields[0])
+ value := strings.TrimSpace(fields[1])
+
+ valueInt, ok := new(big.Int).SetString(value, 16)
+ if !ok {
+ s.setError(fmt.Errorf("could not parse %q", value))
+ return "", false
+ }
+ if _, dup := s.test.Values[key]; dup {
+ s.setError(fmt.Errorf("duplicate key %q", key))
+ return "", false
+ }
+ s.test.Values[key] = valueInt
+ return key, true
+}
+
+func (s *testScanner) Scan() bool {
+ s.test = test{
+ Values: make(map[string]*big.Int),
+ }
+
+ // Scan until the first attribute.
+ for {
+ if !s.scanLine() {
+ return false
+ }
+ if len(s.scanner.Text()) != 0 && s.scanner.Text()[0] != '#' {
+ break
+ }
+ }
+
+ var ok bool
+ s.test.Type, ok = s.addAttribute(s.scanner.Text())
+ if !ok {
+ return false
+ }
+ s.test.LineNumber = s.lineNo
+
+ for s.scanLine() {
+ if len(s.scanner.Text()) == 0 {
+ break
+ }
+
+ if s.scanner.Text()[0] == '#' {
+ continue
+ }
+
+ if _, ok := s.addAttribute(s.scanner.Text()); !ok {
+ return false
+ }
+ }
+ return s.scanner.Err() == nil
+}
+
+func (s *testScanner) Test() test {
+ return s.test
+}
+
+func (s *testScanner) Err() error {
+ if s.err != nil {
+ return s.err
+ }
+ return s.scanner.Err()
+}
+
+func (s *testScanner) setError(err error) {
+ s.err = fmt.Errorf("line %d: %s", s.lineNo, err)
+}
+
+func checkKeys(t test, keys ...string) bool {
+ var foundErrors bool
+
+ for _, k := range keys {
+ if _, ok := t.Values[k]; !ok {
+ fmt.Fprintf(os.Stderr, "Line %d: missing key %q.\n", t.LineNumber, k)
+ foundErrors = true
+ }
+ }
+
+ for k, _ := range t.Values {
+ var found bool
+ for _, k2 := range keys {
+ if k == k2 {
+ found = true
+ break
+ }
+ }
+ if !found {
+ fmt.Fprintf(os.Stderr, "Line %d: unexpected key %q.\n", t.LineNumber, k)
+ foundErrors = true
+ }
+ }
+
+ return !foundErrors
+}
+
+func appendLengthPrefixed(ret, b []byte) []byte {
+ ret = append(ret, byte(len(b)>>8), byte(len(b)))
+ ret = append(ret, b...)
+ return ret
+}
+
+func appendUnsigned(ret []byte, n *big.Int) []byte {
+ b := n.Bytes()
+ if n.Sign() == 0 {
+ b = []byte{0}
+ }
+ return appendLengthPrefixed(ret, b)
+}
+
+func appendSigned(ret []byte, n *big.Int) []byte {
+ var sign byte
+ if n.Sign() < 0 {
+ sign = 1
+ }
+ b := []byte{sign}
+ b = append(b, n.Bytes()...)
+ if n.Sign() == 0 {
+ b = append(b, 0)
+ }
+ return appendLengthPrefixed(ret, b)
+}
+
+func main() {
+ if len(os.Args) != 3 {
+ fmt.Fprintf(os.Stderr, "Usage: %s TESTS FUZZ_DIR\n", os.Args[0])
+ os.Exit(1)
+ }
+
+ in, err := os.Open(os.Args[1])
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Error opening %s: %s.\n", os.Args[0], err)
+ os.Exit(1)
+ }
+ defer in.Close()
+
+ fuzzerDir := os.Args[2]
+
+ scanner := newTestScanner(in)
+ for scanner.Scan() {
+ var fuzzer string
+ var b []byte
+ test := scanner.Test()
+ switch test.Type {
+ case "Quotient":
+ if checkKeys(test, "A", "B", "Quotient", "Remainder") {
+ fuzzer = "bn_div"
+ b = appendSigned(b, test.Values["A"])
+ b = appendSigned(b, test.Values["B"])
+ }
+ case "ModExp":
+ if checkKeys(test, "A", "E", "M", "ModExp") {
+ fuzzer = "bn_mod_exp"
+ b = appendSigned(b, test.Values["A"])
+ b = appendUnsigned(b, test.Values["E"])
+ b = appendUnsigned(b, test.Values["M"])
+ }
+ }
+
+ if len(fuzzer) != 0 {
+ hash := sha1.Sum(b)
+ path := filepath.Join(fuzzerDir, fuzzer + "_corpus", hex.EncodeToString(hash[:]))
+ if err := ioutil.WriteFile(path, b, 0666); err != nil {
+ fmt.Fprintf(os.Stderr, "Error writing to %s: %s.\n", path, err)
+ os.Exit(1)
+ }
+ }
+ }
+ if scanner.Err() != nil {
+ fmt.Fprintf(os.Stderr, "Error reading tests: %s.\n", scanner.Err())
+ }
+}
diff --git a/src/crypto/fipsmodule/bn/div.c b/src/crypto/fipsmodule/bn/div.c
index 1bcff507..0b8b9b9d 100644
--- a/src/crypto/fipsmodule/bn/div.c
+++ b/src/crypto/fipsmodule/bn/div.c
@@ -128,7 +128,7 @@ static BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) {
}
ret = q << BN_BITS4;
- h = ((h << BN_BITS4) | (l >> BN_BITS4)) & BN_MASK2;
+ h = (h << BN_BITS4) | (l >> BN_BITS4);
l = (l & BN_MASK2l) << BN_BITS4;
}
@@ -569,8 +569,6 @@ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) {
BN_ULONG ret = 0;
int i, j;
- w &= BN_MASK2;
-
if (!w) {
// actually this an error (division by zero)
return (BN_ULONG) - 1;
@@ -592,7 +590,7 @@ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) {
BN_ULONG d;
BN_ULONG unused_rem;
bn_div_rem_words(&d, &unused_rem, ret, l, w);
- ret = (l - ((d * w) & BN_MASK2)) & BN_MASK2;
+ ret = l - (d * w);
a->d[i] = d;
}
@@ -634,7 +632,6 @@ BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w) {
}
#endif
- w &= BN_MASK2;
for (i = a->top - 1; i >= 0; i--) {
#ifndef BN_ULLONG
ret = ((ret << BN_BITS4) | ((a->d[i] >> BN_BITS4) & BN_MASK2l)) % w;
diff --git a/src/crypto/fipsmodule/bn/exponentiation.c b/src/crypto/fipsmodule/bn/exponentiation.c
index f4e028b2..b6b7fa9e 100644
--- a/src/crypto/fipsmodule/bn/exponentiation.c
+++ b/src/crypto/fipsmodule/bn/exponentiation.c
@@ -655,9 +655,9 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
goto err;
}
// 2^(top*BN_BITS2) - m
- r->d[0] = (0 - m->d[0]) & BN_MASK2;
+ r->d[0] = 0 - m->d[0];
for (i = 1; i < j; i++) {
- r->d[i] = (~m->d[i]) & BN_MASK2;
+ r->d[i] = ~m->d[i];
}
r->top = j;
// Upper words will be zero if the corresponding words of 'm'
@@ -963,9 +963,9 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
// by Shay Gueron's suggestion
if (m->d[top - 1] & (((BN_ULONG)1) << (BN_BITS2 - 1))) {
// 2^(top*BN_BITS2) - m
- tmp.d[0] = (0 - m->d[0]) & BN_MASK2;
+ tmp.d[0] = 0 - m->d[0];
for (i = 1; i < top; i++) {
- tmp.d[i] = (~m->d[i]) & BN_MASK2;
+ tmp.d[i] = ~m->d[i];
}
tmp.top = top;
} else if (!BN_to_montgomery(&tmp, BN_value_one(), mont, ctx)) {
diff --git a/src/crypto/fipsmodule/bn/generic.c b/src/crypto/fipsmodule/bn/generic.c
index b70080f0..11c377ca 100644
--- a/src/crypto/fipsmodule/bn/generic.c
+++ b/src/crypto/fipsmodule/bn/generic.c
@@ -209,21 +209,21 @@ BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
assert(n >= 0);
if (n <= 0) {
- return (BN_ULONG)0;
+ return 0;
}
while (n & ~3) {
ll += (BN_ULLONG)a[0] + b[0];
- r[0] = (BN_ULONG)ll & BN_MASK2;
+ r[0] = (BN_ULONG)ll;
ll >>= BN_BITS2;
ll += (BN_ULLONG)a[1] + b[1];
- r[1] = (BN_ULONG)ll & BN_MASK2;
+ r[1] = (BN_ULONG)ll;
ll >>= BN_BITS2;
ll += (BN_ULLONG)a[2] + b[2];
- r[2] = (BN_ULONG)ll & BN_MASK2;
+ r[2] = (BN_ULONG)ll;
ll >>= BN_BITS2;
ll += (BN_ULLONG)a[3] + b[3];
- r[3] = (BN_ULONG)ll & BN_MASK2;
+ r[3] = (BN_ULONG)ll;
ll >>= BN_BITS2;
a += 4;
b += 4;
@@ -232,7 +232,7 @@ BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
}
while (n) {
ll += (BN_ULLONG)a[0] + b[0];
- r[0] = (BN_ULONG)ll & BN_MASK2;
+ r[0] = (BN_ULONG)ll;
ll >>= BN_BITS2;
a++;
b++;
@@ -256,27 +256,27 @@ BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
c = 0;
while (n & ~3) {
t = a[0];
- t = (t + c) & BN_MASK2;
+ t += c;
c = (t < c);
- l = (t + b[0]) & BN_MASK2;
+ l = t + b[0];
c += (l < t);
r[0] = l;
t = a[1];
- t = (t + c) & BN_MASK2;
+ t += c;
c = (t < c);
- l = (t + b[1]) & BN_MASK2;
+ l = t + b[1];
c += (l < t);
r[1] = l;
t = a[2];
- t = (t + c) & BN_MASK2;
+ t += c;
c = (t < c);
- l = (t + b[2]) & BN_MASK2;
+ l = t + b[2];
c += (l < t);
r[2] = l;
t = a[3];
- t = (t + c) & BN_MASK2;
+ t += c;
c = (t < c);
- l = (t + b[3]) & BN_MASK2;
+ l = t + b[3];
c += (l < t);
r[3] = l;
a += 4;
@@ -286,9 +286,9 @@ BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
}
while (n) {
t = a[0];
- t = (t + c) & BN_MASK2;
+ t += c;
c = (t < c);
- l = (t + b[0]) & BN_MASK2;
+ l = t + b[0];
c += (l < t);
r[0] = l;
a++;
@@ -314,25 +314,25 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
while (n & ~3) {
t1 = a[0];
t2 = b[0];
- r[0] = (t1 - t2 - c) & BN_MASK2;
+ r[0] = t1 - t2 - c;
if (t1 != t2) {
c = (t1 < t2);
}
t1 = a[1];
t2 = b[1];
- r[1] = (t1 - t2 - c) & BN_MASK2;
+ r[1] = t1 - t2 - c;
if (t1 != t2) {
c = (t1 < t2);
}
t1 = a[2];
t2 = b[2];
- r[2] = (t1 - t2 - c) & BN_MASK2;
+ r[2] = t1 - t2 - c;
if (t1 != t2) {
c = (t1 < t2);
}
t1 = a[3];
t2 = b[3];
- r[3] = (t1 - t2 - c) & BN_MASK2;
+ r[3] = t1 - t2 - c;
if (t1 != t2) {
c = (t1 < t2);
}
@@ -344,7 +344,7 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
while (n) {
t1 = a[0];
t2 = b[0];
- r[0] = (t1 - t2 - c) & BN_MASK2;
+ r[0] = t1 - t2 - c;
if (t1 != t2) {
c = (t1 < t2);
}
@@ -372,7 +372,7 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
t += (c0); /* no carry */ \
(c0) = (BN_ULONG)Lw(t); \
hi = (BN_ULONG)Hw(t); \
- (c1) = ((c1) + (hi)) & BN_MASK2; \
+ (c1) += (hi); \
if ((c1) < hi) { \
(c2)++; \
} \
@@ -385,14 +385,14 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
BN_ULLONG tt = t + (c0); /* no carry */ \
(c0) = (BN_ULONG)Lw(tt); \
hi = (BN_ULONG)Hw(tt); \
- (c1) = ((c1) + hi) & BN_MASK2; \
+ (c1) += hi; \
if ((c1) < hi) { \
(c2)++; \
} \
t += (c0); /* no carry */ \
(c0) = (BN_ULONG)Lw(t); \
hi = (BN_ULONG)Hw(t); \
- (c1) = ((c1) + hi) & BN_MASK2; \
+ (c1) += hi; \
if ((c1) < hi) { \
(c2)++; \
} \
@@ -405,7 +405,7 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
t += (c0); /* no carry */ \
(c0) = (BN_ULONG)Lw(t); \
hi = (BN_ULONG)Hw(t); \
- (c1) = ((c1) + hi) & BN_MASK2; \
+ (c1) += hi; \
if ((c1) < hi) { \
(c2)++; \
} \
diff --git a/src/crypto/fipsmodule/bn/internal.h b/src/crypto/fipsmodule/bn/internal.h
index ecd7d6cb..b1e0b0de 100644
--- a/src/crypto/fipsmodule/bn/internal.h
+++ b/src/crypto/fipsmodule/bn/internal.h
@@ -191,8 +191,8 @@ extern "C" {
}
#if defined(BN_ULLONG)
-#define Lw(t) (((BN_ULONG)(t))&BN_MASK2)
-#define Hw(t) (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2)
+#define Lw(t) ((BN_ULONG)(t))
+#define Hw(t) ((BN_ULONG)((t) >> BN_BITS2))
#endif
// bn_correct_top decrements |bn->top| until |bn->d[top-1]| is non-zero or
diff --git a/src/crypto/fipsmodule/bn/montgomery.c b/src/crypto/fipsmodule/bn/montgomery.c
index 8024e276..5219187d 100644
--- a/src/crypto/fipsmodule/bn/montgomery.c
+++ b/src/crypto/fipsmodule/bn/montgomery.c
@@ -290,8 +290,8 @@ static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r,
n0 = mont->n0[0];
for (carry = 0, i = 0; i < nl; i++, rp++) {
- v = bn_mul_add_words(rp, np, nl, (rp[0] * n0) & BN_MASK2);
- v = (v + carry + rp[nl]) & BN_MASK2;
+ v = bn_mul_add_words(rp, np, nl, rp[0] * n0);
+ v += carry + rp[nl];
carry |= (v != rp[nl]);
carry &= (v <= rp[nl]);
rp[nl] = v;
diff --git a/src/crypto/fipsmodule/bn/mul.c b/src/crypto/fipsmodule/bn/mul.c
index a4e27f2a..b6f3ff18 100644
--- a/src/crypto/fipsmodule/bn/mul.c
+++ b/src/crypto/fipsmodule/bn/mul.c
@@ -141,7 +141,7 @@ static BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a,
if (dl < 0) {
for (;;) {
t = b[0];
- r[0] = (0 - t - c) & BN_MASK2;
+ r[0] = 0 - t - c;
if (t != 0) {
c = 1;
}
@@ -150,7 +150,7 @@ static BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a,
}
t = b[1];
- r[1] = (0 - t - c) & BN_MASK2;
+ r[1] = 0 - t - c;
if (t != 0) {
c = 1;
}
@@ -159,7 +159,7 @@ static BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a,
}
t = b[2];
- r[2] = (0 - t - c) & BN_MASK2;
+ r[2] = 0 - t - c;
if (t != 0) {
c = 1;
}
@@ -168,7 +168,7 @@ static BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a,
}
t = b[3];
- r[3] = (0 - t - c) & BN_MASK2;
+ r[3] = 0 - t - c;
if (t != 0) {
c = 1;
}
@@ -183,7 +183,7 @@ static BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a,
int save_dl = dl;
while (c) {
t = a[0];
- r[0] = (t - c) & BN_MASK2;
+ r[0] = t - c;
if (t != 0) {
c = 0;
}
@@ -192,7 +192,7 @@ static BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a,
}
t = a[1];
- r[1] = (t - c) & BN_MASK2;
+ r[1] = t - c;
if (t != 0) {
c = 0;
}
@@ -201,7 +201,7 @@ static BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a,
}
t = a[2];
- r[2] = (t - c) & BN_MASK2;
+ r[2] = t - c;
if (t != 0) {
c = 0;
}
@@ -210,7 +210,7 @@ static BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a,
}
t = a[3];
- r[3] = (t - c) & BN_MASK2;
+ r[3] = t - c;
if (t != 0) {
c = 0;
}
@@ -407,7 +407,7 @@ static void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
if (c1) {
p = &(r[n + n2]);
lo = *p;
- ln = (lo + c1) & BN_MASK2;
+ ln = lo + c1;
*p = ln;
// The overflow will stop before we over write
@@ -416,7 +416,7 @@ static void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
do {
p++;
lo = *p;
- ln = (lo + 1) & BN_MASK2;
+ ln = lo + 1;
*p = ln;
} while (ln == 0);
}
@@ -544,7 +544,7 @@ static void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n,
if (c1) {
p = &(r[n + n2]);
lo = *p;
- ln = (lo + c1) & BN_MASK2;
+ ln = lo + c1;
*p = ln;
// The overflow will stop before we over write
@@ -553,7 +553,7 @@ static void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n,
do {
p++;
lo = *p;
- ln = (lo + 1) & BN_MASK2;
+ ln = lo + 1;
*p = ln;
} while (ln == 0);
}
@@ -757,7 +757,7 @@ static void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t
if (c1) {
p = &(r[n + n2]);
lo = *p;
- ln = (lo + c1) & BN_MASK2;
+ ln = lo + c1;
*p = ln;
// The overflow will stop before we over write
@@ -766,7 +766,7 @@ static void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t
do {
p++;
lo = *p;
- ln = (lo + 1) & BN_MASK2;
+ ln = lo + 1;
*p = ln;
} while (ln == 0);
}
@@ -774,9 +774,6 @@ static void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t
}
int BN_mul_word(BIGNUM *bn, BN_ULONG w) {
- BN_ULONG ll;
-
- w &= BN_MASK2;
if (!bn->top) {
return 1;
}
@@ -786,7 +783,7 @@ int BN_mul_word(BIGNUM *bn, BN_ULONG w) {
return 1;
}
- ll = bn_mul_words(bn->d, bn->d, bn->top, w);
+ BN_ULONG ll = bn_mul_words(bn->d, bn->d, bn->top, w);
if (ll) {
if (!bn_wexpand(bn, bn->top + 1)) {
return 0;
diff --git a/src/crypto/fipsmodule/bn/shift.c b/src/crypto/fipsmodule/bn/shift.c
index d3fcf395..64afa782 100644
--- a/src/crypto/fipsmodule/bn/shift.c
+++ b/src/crypto/fipsmodule/bn/shift.c
@@ -90,8 +90,8 @@ int BN_lshift(BIGNUM *r, const BIGNUM *a, int n) {
} else {
for (i = a->top - 1; i >= 0; i--) {
l = f[i];
- t[nw + i + 1] |= (l >> rb) & BN_MASK2;
- t[nw + i] = (l << lb) & BN_MASK2;
+ t[nw + i + 1] |= l >> rb;
+ t[nw + i] = l << lb;
}
}
OPENSSL_memset(t, 0, nw * sizeof(t[0]));
@@ -121,7 +121,7 @@ int BN_lshift1(BIGNUM *r, const BIGNUM *a) {
c = 0;
for (i = 0; i < a->top; i++) {
t = *(ap++);
- *(rp++) = ((t << 1) | c) & BN_MASK2;
+ *(rp++) = (t << 1) | c;
c = (t & BN_TBIT) ? 1 : 0;
}
if (c) {
@@ -173,11 +173,12 @@ int BN_rshift(BIGNUM *r, const BIGNUM *a, int n) {
} else {
l = *(f++);
for (i = j - 1; i != 0; i--) {
- tmp = (l >> rb) & BN_MASK2;
+ tmp = l >> rb;
l = *(f++);
- *(t++) = (tmp | (l << lb)) & BN_MASK2;
+ *(t++) = tmp | (l << lb);
}
- if ((l = (l >> rb) & BN_MASK2)) {
+ l >>= rb;
+ if (l) {
*(t) = l;
}
}
@@ -214,7 +215,7 @@ int BN_rshift1(BIGNUM *r, const BIGNUM *a) {
}
while (i > 0) {
t = ap[--i];
- rp[i] = ((t >> 1) & BN_MASK2) | c;
+ rp[i] = (t >> 1) | c;
c = (t & 1) ? BN_TBIT : 0;
}
r->top = j;
@@ -227,19 +228,17 @@ int BN_rshift1(BIGNUM *r, const BIGNUM *a) {
}
int BN_set_bit(BIGNUM *a, int n) {
- int i, j, k;
-
if (n < 0) {
return 0;
}
- i = n / BN_BITS2;
- j = n % BN_BITS2;
+ int i = n / BN_BITS2;
+ int j = n % BN_BITS2;
if (a->top <= i) {
if (!bn_wexpand(a, i + 1)) {
return 0;
}
- for (k = a->top; k < i + 1; k++) {
+ for (int k = a->top; k < i + 1; k++) {
a->d[k] = 0;
}
a->top = i + 1;
@@ -269,13 +268,11 @@ int BN_clear_bit(BIGNUM *a, int n) {
}
int BN_is_bit_set(const BIGNUM *a, int n) {
- int i, j;
-
if (n < 0) {
return 0;
}
- i = n / BN_BITS2;
- j = n % BN_BITS2;
+ int i = n / BN_BITS2;
+ int j = n % BN_BITS2;
if (a->top <= i) {
return 0;
}
@@ -284,14 +281,12 @@ int BN_is_bit_set(const BIGNUM *a, int n) {
}
int BN_mask_bits(BIGNUM *a, int n) {
- int b, w;
-
if (n < 0) {
return 0;
}
- w = n / BN_BITS2;
- b = n % BN_BITS2;
+ int w = n / BN_BITS2;
+ int b = n % BN_BITS2;
if (w >= a->top) {
return 0;
}
diff --git a/src/crypto/fipsmodule/ec/ec.c b/src/crypto/fipsmodule/ec/ec.c
index a39ca599..600aedc8 100644
--- a/src/crypto/fipsmodule/ec/ec.c
+++ b/src/crypto/fipsmodule/ec/ec.c
@@ -80,6 +80,8 @@
#include "../delocate.h"
+static void ec_point_free(EC_POINT *point, int free_group);
+
static const uint8_t kP224Params[6 * 28] = {
// p
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
@@ -354,6 +356,7 @@ EC_GROUP *ec_group_new(const EC_METHOD *meth) {
}
OPENSSL_memset(ret, 0, sizeof(EC_GROUP));
+ ret->references = 1;
ret->meth = meth;
BN_init(&ret->order);
@@ -365,6 +368,19 @@ EC_GROUP *ec_group_new(const EC_METHOD *meth) {
return ret;
}
+static void ec_group_set0_generator(EC_GROUP *group, EC_POINT *generator) {
+ assert(group->generator == NULL);
+ assert(group == generator->group);
+
+ // Avoid a reference cycle. |group->generator| does not maintain an owning
+ // pointer to |group|.
+ group->generator = generator;
+ int is_zero = CRYPTO_refcount_dec_and_test_zero(&group->references);
+
+ assert(!is_zero);
+ (void)is_zero;
+}
+
EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
const BIGNUM *b, BN_CTX *ctx) {
EC_GROUP *ret = ec_group_new(EC_GFp_mont_method());
@@ -372,9 +388,10 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
return NULL;
}
- if (ret->meth->group_set_curve == 0) {
+ if (ret->meth->group_set_curve == NULL) {
OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
+ EC_GROUP_free(ret);
+ return NULL;
}
if (!ret->meth->group_set_curve(ret, p, a, b, ctx)) {
EC_GROUP_free(ret);
@@ -385,9 +402,13 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
const BIGNUM *order, const BIGNUM *cofactor) {
- if (group->curve_name != NID_undef || group->generator != NULL) {
+ if (group->curve_name != NID_undef || group->generator != NULL ||
+ generator->group != group) {
// |EC_GROUP_set_generator| may only be used with |EC_GROUP|s returned by
// |EC_GROUP_new_curve_GFp| and may only used once on each group.
+ // Additionally, |generator| must been created from
+ // |EC_GROUP_new_curve_GFp|, not a copy, so that
+ // |generator->group->generator| is set correctly.
return 0;
}
@@ -397,10 +418,16 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
return 0;
}
- group->generator = EC_POINT_new(group);
- return group->generator != NULL &&
- EC_POINT_copy(group->generator, generator) &&
- BN_copy(&group->order, order);
+ EC_POINT *copy = EC_POINT_new(group);
+ if (copy == NULL ||
+ !EC_POINT_copy(copy, generator) ||
+ !BN_copy(&group->order, order)) {
+ EC_POINT_free(copy);
+ return 0;
+ }
+
+ ec_group_set0_generator(group, copy);
+ return 1;
}
static EC_GROUP *ec_group_new_from_data(unsigned built_in_index) {
@@ -459,7 +486,7 @@ static EC_GROUP *ec_group_new_from_data(unsigned built_in_index) {
group->order_mont = monts[built_in_index];
}
- group->generator = P;
+ ec_group_set0_generator(group, P);
P = NULL;
ok = 1;
@@ -500,15 +527,16 @@ EC_GROUP *EC_GROUP_new_by_curve_name(int nid) {
}
void EC_GROUP_free(EC_GROUP *group) {
- if (!group) {
+ if (group == NULL ||
+ !CRYPTO_refcount_dec_and_test_zero(&group->references)) {
return;
}
- if (group->meth->group_finish != 0) {
+ if (group->meth->group_finish != NULL) {
group->meth->group_finish(group);
}
- EC_POINT_free(group->generator);
+ ec_point_free(group->generator, 0 /* don't free group */);
BN_free(&group->order);
OPENSSL_free(group);
@@ -523,42 +551,37 @@ EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) {
return NULL;
}
- if (a->meth->group_copy == NULL) {
- OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return NULL;
- }
+ // Groups are logically immutable (but for |EC_GROUP_set_generator| which must
+ // be called early on), so we simply take a reference.
+ EC_GROUP *group = (EC_GROUP *)a;
+ CRYPTO_refcount_inc(&group->references);
+ return group;
+}
- EC_GROUP *ret = ec_group_new(a->meth);
- if (ret == NULL) {
- return NULL;
+int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ignored) {
+ // Note this function returns 0 if equal and non-zero otherwise.
+ if (a == b) {
+ return 0;
}
-
- ret->order_mont = a->order_mont;
- ret->curve_name = a->curve_name;
-
- if (a->generator != NULL) {
- ret->generator = EC_POINT_dup(a->generator, ret);
- if (ret->generator == NULL) {
- goto err;
- }
+ if (a->curve_name != b->curve_name) {
+ return 1;
}
-
- if (!BN_copy(&ret->order, &a->order) ||
- !ret->meth->group_copy(ret, a)) {
- goto err;
+ if (a->curve_name != NID_undef) {
+ // Built-in curves may be compared by curve name alone.
+ return 0;
}
- return ret;
-
-err:
- EC_GROUP_free(ret);
- return NULL;
-}
-
-int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ignored) {
- return a->curve_name == NID_undef ||
- b->curve_name == NID_undef ||
- a->curve_name != b->curve_name;
+ // |a| and |b| are both custom curves. We compare the entire curve
+ // structure. If |a| or |b| is incomplete (due to legacy OpenSSL mistakes,
+ // custom curve construction is sadly done in two parts) but otherwise not the
+ // same object, we consider them always unequal.
+ return a->generator == NULL ||
+ b->generator == NULL ||
+ BN_cmp(&a->order, &b->order) != 0 ||
+ BN_cmp(&a->field, &b->field) != 0 ||
+ BN_cmp(&a->a, &b->a) != 0 ||
+ BN_cmp(&a->b, &b->b) != 0 ||
+ ec_GFp_simple_cmp(a, a->generator, b->generator, NULL) != 0;
}
const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) {
@@ -608,9 +631,9 @@ EC_POINT *EC_POINT_new(const EC_GROUP *group) {
return NULL;
}
- ret->meth = group->meth;
-
- if (!ec_GFp_simple_point_init(ret)) {
+ ret->group = EC_GROUP_dup(group);
+ if (ret->group == NULL ||
+ !ec_GFp_simple_point_init(ret)) {
OPENSSL_free(ret);
return NULL;
}
@@ -618,28 +641,25 @@ EC_POINT *EC_POINT_new(const EC_GROUP *group) {
return ret;
}
-void EC_POINT_free(EC_POINT *point) {
+static void ec_point_free(EC_POINT *point, int free_group) {
if (!point) {
return;
}
-
ec_GFp_simple_point_finish(point);
-
+ if (free_group) {
+ EC_GROUP_free(point->group);
+ }
OPENSSL_free(point);
}
-void EC_POINT_clear_free(EC_POINT *point) {
- if (!point) {
- return;
- }
-
- ec_GFp_simple_point_clear_finish(point);
-
- OPENSSL_free(point);
+void EC_POINT_free(EC_POINT *point) {
+ ec_point_free(point, 1 /* free group */);
}
+void EC_POINT_clear_free(EC_POINT *point) { EC_POINT_free(point); }
+
int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) {
- if (dest->meth != src->meth) {
+ if (EC_GROUP_cmp(dest->group, src->group, NULL) != 0) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
@@ -665,7 +685,7 @@ EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) {
}
int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) {
- if (group->meth != point->meth) {
+ if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
@@ -673,7 +693,7 @@ int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) {
}
int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
- if (group->meth != point->meth) {
+ if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
@@ -682,7 +702,7 @@ int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
BN_CTX *ctx) {
- if (group->meth != point->meth) {
+ if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
@@ -691,7 +711,8 @@ int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
BN_CTX *ctx) {
- if ((group->meth != a->meth) || (a->meth != b->meth)) {
+ if (EC_GROUP_cmp(group, a->group, NULL) != 0 ||
+ EC_GROUP_cmp(group, b->group, NULL) != 0) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return -1;
}
@@ -699,7 +720,7 @@ int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
}
int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) {
- if (group->meth != point->meth) {
+ if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
@@ -709,7 +730,7 @@ int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) {
int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
BN_CTX *ctx) {
for (size_t i = 0; i < num; i++) {
- if (group->meth != points[i]->meth) {
+ if (EC_GROUP_cmp(group, points[i]->group, NULL) != 0) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
@@ -724,7 +745,7 @@ int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
- if (group->meth != point->meth) {
+ if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
@@ -734,7 +755,7 @@ int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
const BIGNUM *x, const BIGNUM *y,
BN_CTX *ctx) {
- if (group->meth != point->meth) {
+ if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
@@ -752,8 +773,9 @@ int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
const EC_POINT *b, BN_CTX *ctx) {
- if ((group->meth != r->meth) || (r->meth != a->meth) ||
- (a->meth != b->meth)) {
+ if (EC_GROUP_cmp(group, r->group, NULL) != 0 ||
+ EC_GROUP_cmp(group, a->group, NULL) != 0 ||
+ EC_GROUP_cmp(group, b->group, NULL) != 0) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
@@ -763,7 +785,8 @@ int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
BN_CTX *ctx) {
- if ((group->meth != r->meth) || (r->meth != a->meth)) {
+ if (EC_GROUP_cmp(group, r->group, NULL) != 0 ||
+ EC_GROUP_cmp(group, a->group, NULL) != 0) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
@@ -772,7 +795,7 @@ int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) {
- if (group->meth != a->meth) {
+ if (EC_GROUP_cmp(group, a->group, NULL) != 0) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
@@ -790,8 +813,8 @@ int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
return 0;
}
- if (group->meth != r->meth ||
- (p != NULL && group->meth != p->meth)) {
+ if (EC_GROUP_cmp(group, r->group, NULL) != 0 ||
+ (p != NULL && EC_GROUP_cmp(group, p->group, NULL) != 0)) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
@@ -803,7 +826,7 @@ int ec_point_set_Jprojective_coordinates_GFp(const EC_GROUP *group,
EC_POINT *point, const BIGNUM *x,
const BIGNUM *y, const BIGNUM *z,
BN_CTX *ctx) {
- if (group->meth != point->meth) {
+ if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
diff --git a/src/crypto/fipsmodule/ec/ec_montgomery.c b/src/crypto/fipsmodule/ec/ec_montgomery.c
index c5f240bf..6670b84e 100644
--- a/src/crypto/fipsmodule/ec/ec_montgomery.c
+++ b/src/crypto/fipsmodule/ec/ec_montgomery.c
@@ -90,32 +90,6 @@ void ec_GFp_mont_group_finish(EC_GROUP *group) {
ec_GFp_simple_group_finish(group);
}
-int ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src) {
- BN_MONT_CTX_free(dest->mont);
- dest->mont = NULL;
-
- if (!ec_GFp_simple_group_copy(dest, src)) {
- return 0;
- }
-
- if (src->mont != NULL) {
- dest->mont = BN_MONT_CTX_new();
- if (dest->mont == NULL) {
- return 0;
- }
- if (!BN_MONT_CTX_copy(dest->mont, src->mont)) {
- goto err;
- }
- }
-
- return 1;
-
-err:
- BN_MONT_CTX_free(dest->mont);
- dest->mont = NULL;
- return 0;
-}
-
int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p,
const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) {
BN_CTX *new_ctx = NULL;
@@ -293,7 +267,6 @@ err:
DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_mont_method) {
out->group_init = ec_GFp_mont_group_init;
out->group_finish = ec_GFp_mont_group_finish;
- out->group_copy = ec_GFp_mont_group_copy;
out->group_set_curve = ec_GFp_mont_group_set_curve;
out->point_get_affine_coordinates = ec_GFp_mont_point_get_affine_coordinates;
out->mul = ec_wNAF_mul /* XXX: Not constant time. */;
diff --git a/src/crypto/fipsmodule/ec/ec_test.cc b/src/crypto/fipsmodule/ec/ec_test.cc
index 48b60ee9..0ee73787 100644
--- a/src/crypto/fipsmodule/ec/ec_test.cc
+++ b/src/crypto/fipsmodule/ec/ec_test.cc
@@ -276,6 +276,33 @@ TEST(ECTest, ArbitraryCurve) {
// The key must be valid according to the new group too.
EXPECT_TRUE(EC_KEY_check_key(key2.get()));
+
+ // Make a second instance of |group|.
+ bssl::UniquePtr<EC_GROUP> group2(
+ EC_GROUP_new_curve_GFp(p.get(), a.get(), b.get(), ctx.get()));
+ ASSERT_TRUE(group2);
+ bssl::UniquePtr<EC_POINT> generator2(EC_POINT_new(group2.get()));
+ ASSERT_TRUE(generator2);
+ ASSERT_TRUE(EC_POINT_set_affine_coordinates_GFp(
+ group2.get(), generator2.get(), gx.get(), gy.get(), ctx.get()));
+ ASSERT_TRUE(EC_GROUP_set_generator(group2.get(), generator2.get(),
+ order.get(), BN_value_one()));
+
+ EXPECT_EQ(0, EC_GROUP_cmp(group.get(), group.get(), NULL));
+ EXPECT_EQ(0, EC_GROUP_cmp(group2.get(), group.get(), NULL));
+
+ // group3 uses the wrong generator.
+ bssl::UniquePtr<EC_GROUP> group3(
+ EC_GROUP_new_curve_GFp(p.get(), a.get(), b.get(), ctx.get()));
+ ASSERT_TRUE(group3);
+ bssl::UniquePtr<EC_POINT> generator3(EC_POINT_new(group3.get()));
+ ASSERT_TRUE(generator3);
+ ASSERT_TRUE(EC_POINT_set_affine_coordinates_GFp(
+ group3.get(), generator3.get(), x.get(), y.get(), ctx.get()));
+ ASSERT_TRUE(EC_GROUP_set_generator(group3.get(), generator3.get(),
+ order.get(), BN_value_one()));
+
+ EXPECT_NE(0, EC_GROUP_cmp(group.get(), group3.get(), NULL));
}
class ECCurveTest : public testing::TestWithParam<EC_builtin_curve> {};
diff --git a/src/crypto/fipsmodule/ec/internal.h b/src/crypto/fipsmodule/ec/internal.h
index 39c9349a..f0657445 100644
--- a/src/crypto/fipsmodule/ec/internal.h
+++ b/src/crypto/fipsmodule/ec/internal.h
@@ -82,7 +82,6 @@ extern "C" {
struct ec_method_st {
int (*group_init)(EC_GROUP *);
void (*group_finish)(EC_GROUP *);
- int (*group_copy)(EC_GROUP *, const EC_GROUP *);
int (*group_set_curve)(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
const BIGNUM *b, BN_CTX *);
int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_POINT *,
@@ -114,6 +113,8 @@ const EC_METHOD *EC_GFp_mont_method(void);
struct ec_group_st {
const EC_METHOD *meth;
+ // Unlike all other |EC_POINT|s, |generator| does not own |generator->group|
+ // to avoid a reference cycle.
EC_POINT *generator;
BIGNUM order;
@@ -130,13 +131,17 @@ struct ec_group_st {
int a_is_minus3; // enable optimized point arithmetics for special case
+ CRYPTO_refcount_t references;
+
BN_MONT_CTX *mont; // Montgomery structure.
BIGNUM one; // The value one.
} /* EC_GROUP */;
struct ec_point_st {
- const EC_METHOD *meth;
+ // group is an owning reference to |group|, unless this is
+ // |group->generator|.
+ EC_GROUP *group;
BIGNUM X;
BIGNUM Y;
@@ -145,7 +150,6 @@ struct ec_point_st {
} /* EC_POINT */;
EC_GROUP *ec_group_new(const EC_METHOD *meth);
-int ec_group_copy(EC_GROUP *dest, const EC_GROUP *src);
// ec_group_get_order_mont returns a Montgomery context for operations modulo
// |group|'s order. It may return NULL in the case that |group| is not a
@@ -158,7 +162,6 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
// method functions in simple.c
int ec_GFp_simple_group_init(EC_GROUP *);
void ec_GFp_simple_group_finish(EC_GROUP *);
-int ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *);
int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
const BIGNUM *b, BN_CTX *);
int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a,
@@ -166,7 +169,6 @@ int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a,
unsigned ec_GFp_simple_group_get_degree(const EC_GROUP *);
int ec_GFp_simple_point_init(EC_POINT *);
void ec_GFp_simple_point_finish(EC_POINT *);
-void ec_GFp_simple_point_clear_finish(EC_POINT *);
int ec_GFp_simple_point_copy(EC_POINT *, const EC_POINT *);
int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *, EC_POINT *,
@@ -205,7 +207,6 @@ int ec_GFp_mont_group_init(EC_GROUP *);
int ec_GFp_mont_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
const BIGNUM *b, BN_CTX *);
void ec_GFp_mont_group_finish(EC_GROUP *);
-int ec_GFp_mont_group_copy(EC_GROUP *, const EC_GROUP *);
int ec_GFp_mont_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
const BIGNUM *b, BN_CTX *);
int ec_GFp_mont_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
diff --git a/src/crypto/fipsmodule/ec/oct.c b/src/crypto/fipsmodule/ec/oct.c
index cf51e4bc..7d623956 100644
--- a/src/crypto/fipsmodule/ec/oct.c
+++ b/src/crypto/fipsmodule/ec/oct.c
@@ -251,7 +251,7 @@ err:
int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
const uint8_t *buf, size_t len, BN_CTX *ctx) {
- if (group->meth != point->meth) {
+ if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
@@ -261,7 +261,7 @@ int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point,
point_conversion_form_t form, uint8_t *buf,
size_t len, BN_CTX *ctx) {
- if (group->meth != point->meth) {
+ if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
@@ -396,7 +396,7 @@ err:
int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group,
EC_POINT *point, const BIGNUM *x,
int y_bit, BN_CTX *ctx) {
- if (group->meth != point->meth) {
+ if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
diff --git a/src/crypto/fipsmodule/ec/p224-64.c b/src/crypto/fipsmodule/ec/p224-64.c
index ec5a93d2..26a94b9e 100644
--- a/src/crypto/fipsmodule/ec/p224-64.c
+++ b/src/crypto/fipsmodule/ec/p224-64.c
@@ -1151,7 +1151,6 @@ err:
DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_nistp224_method) {
out->group_init = ec_GFp_simple_group_init;
out->group_finish = ec_GFp_simple_group_finish;
- out->group_copy = ec_GFp_simple_group_copy;
out->group_set_curve = ec_GFp_simple_group_set_curve;
out->point_get_affine_coordinates =
ec_GFp_nistp224_point_get_affine_coordinates;
diff --git a/src/crypto/fipsmodule/ec/p256-64.c b/src/crypto/fipsmodule/ec/p256-64.c
index f7d1ff11..04ae56ba 100644
--- a/src/crypto/fipsmodule/ec/p256-64.c
+++ b/src/crypto/fipsmodule/ec/p256-64.c
@@ -1694,7 +1694,6 @@ err:
DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_nistp256_method) {
out->group_init = ec_GFp_simple_group_init;
out->group_finish = ec_GFp_simple_group_finish;
- out->group_copy = ec_GFp_simple_group_copy;
out->group_set_curve = ec_GFp_simple_group_set_curve;
out->point_get_affine_coordinates =
ec_GFp_nistp256_point_get_affine_coordinates;
diff --git a/src/crypto/fipsmodule/ec/p256-x86_64.c b/src/crypto/fipsmodule/ec/p256-x86_64.c
index 8b516773..0004add8 100644
--- a/src/crypto/fipsmodule/ec/p256-x86_64.c
+++ b/src/crypto/fipsmodule/ec/p256-x86_64.c
@@ -547,7 +547,6 @@ static int ecp_nistz256_get_affine(const EC_GROUP *group, const EC_POINT *point,
DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_nistz256_method) {
out->group_init = ec_GFp_mont_group_init;
out->group_finish = ec_GFp_mont_group_finish;
- out->group_copy = ec_GFp_mont_group_copy;
out->group_set_curve = ec_GFp_mont_group_set_curve;
out->point_get_affine_coordinates = ecp_nistz256_get_affine;
out->mul = ecp_nistz256_points_mul;
diff --git a/src/crypto/fipsmodule/ec/simple.c b/src/crypto/fipsmodule/ec/simple.c
index 75c06da1..f7faa45c 100644
--- a/src/crypto/fipsmodule/ec/simple.c
+++ b/src/crypto/fipsmodule/ec/simple.c
@@ -104,18 +104,6 @@ void ec_GFp_simple_group_finish(EC_GROUP *group) {
BN_free(&group->one);
}
-int ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src) {
- if (!BN_copy(&dest->field, &src->field) ||
- !BN_copy(&dest->a, &src->a) ||
- !BN_copy(&dest->b, &src->b) ||
- !BN_copy(&dest->one, &src->one)) {
- return 0;
- }
-
- dest->a_is_minus3 = src->a_is_minus3;
- return 1;
-}
-
int ec_GFp_simple_group_set_curve(EC_GROUP *group, const BIGNUM *p,
const BIGNUM *a, const BIGNUM *b,
BN_CTX *ctx) {
@@ -249,12 +237,6 @@ void ec_GFp_simple_point_finish(EC_POINT *point) {
BN_free(&point->Z);
}
-void ec_GFp_simple_point_clear_finish(EC_POINT *point) {
- BN_clear_free(&point->X);
- BN_clear_free(&point->Y);
- BN_clear_free(&point->Z);
-}
-
int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src) {
if (!BN_copy(&dest->X, &src->X) ||
!BN_copy(&dest->Y, &src->Y) ||
@@ -814,11 +796,11 @@ int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
const BIGNUM *tmp1_, *tmp2_;
int ret = -1;
- if (EC_POINT_is_at_infinity(group, a)) {
- return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
+ if (ec_GFp_simple_is_at_infinity(group, a)) {
+ return ec_GFp_simple_is_at_infinity(group, b) ? 0 : 1;
}
- if (EC_POINT_is_at_infinity(group, b)) {
+ if (ec_GFp_simple_is_at_infinity(group, b)) {
return 1;
}
diff --git a/src/crypto/fipsmodule/ec/wnaf.c b/src/crypto/fipsmodule/ec/wnaf.c
index 0e3ee13a..842a8fb6 100644
--- a/src/crypto/fipsmodule/ec/wnaf.c
+++ b/src/crypto/fipsmodule/ec/wnaf.c
@@ -446,7 +446,7 @@ err:
}
if (val != NULL) {
for (i = 0; i < num_val; i++) {
- EC_POINT_clear_free(val[i]);
+ EC_POINT_free(val[i]);
}
OPENSSL_free(val);
diff --git a/src/crypto/lhash/lhash.c b/src/crypto/lhash/lhash.c
index 50545291..7bfd2897 100644
--- a/src/crypto/lhash/lhash.c
+++ b/src/crypto/lhash/lhash.c
@@ -73,6 +73,25 @@ static const size_t kMinNumBuckets = 16;
static const size_t kMaxAverageChainLength = 2;
static const size_t kMinAverageChainLength = 1;
+struct lhash_st {
+ // num_items contains the total number of items in the hash table.
+ size_t num_items;
+ // buckets is an array of |num_buckets| pointers. Each points to the head of
+ // a chain of LHASH_ITEM objects that have the same hash value, mod
+ // |num_buckets|.
+ LHASH_ITEM **buckets;
+ // num_buckets contains the length of |buckets|. This value is always >=
+ // kMinNumBuckets.
+ size_t num_buckets;
+ // callback_depth contains the current depth of |lh_doall| or |lh_doall_arg|
+ // calls. If non-zero then this suppresses resizing of the |buckets| array,
+ // which would otherwise disrupt the iteration.
+ unsigned callback_depth;
+
+ lhash_cmp_func comp;
+ lhash_hash_func hash;
+};
+
_LHASH *lh_new(lhash_hash_func hash, lhash_cmp_func comp) {
_LHASH *ret = OPENSSL_malloc(sizeof(_LHASH));
if (ret == NULL) {
diff --git a/src/crypto/pem/pem_lib.c b/src/crypto/pem/pem_lib.c
index afa39d78..8f890961 100644
--- a/src/crypto/pem/pem_lib.c
+++ b/src/crypto/pem/pem_lib.c
@@ -764,13 +764,13 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
int PEM_def_callback(char *buf, int size, int rwflag, void *userdata)
{
- if (!buf || !userdata) {
+ if (!buf || !userdata || size < 0) {
return 0;
}
size_t len = strlen((char *)userdata);
if (len >= (size_t)size) {
return 0;
}
- strcpy(buf, (char *)userdata);
+ BUF_strlcpy(buf, userdata, (size_t)size);
return len;
}
diff --git a/src/crypto/rsa_extra/rsa_asn1.c b/src/crypto/rsa_extra/rsa_asn1.c
index 23c91bd9..3cc6a9c3 100644
--- a/src/crypto/rsa_extra/rsa_asn1.c
+++ b/src/crypto/rsa_extra/rsa_asn1.c
@@ -69,22 +69,15 @@
#include "../internal.h"
-static int parse_integer_buggy(CBS *cbs, BIGNUM **out, int buggy) {
+static int parse_integer(CBS *cbs, BIGNUM **out) {
assert(*out == NULL);
*out = BN_new();
if (*out == NULL) {
return 0;
}
- if (buggy) {
- return BN_parse_asn1_unsigned_buggy(cbs, *out);
- }
return BN_parse_asn1_unsigned(cbs, *out);
}
-static int parse_integer(CBS *cbs, BIGNUM **out) {
- return parse_integer_buggy(cbs, out, 0 /* not buggy */);
-}
-
static int marshal_integer(CBB *cbb, BIGNUM *bn) {
if (bn == NULL) {
// An RSA object may be missing some components.
@@ -94,14 +87,14 @@ static int marshal_integer(CBB *cbb, BIGNUM *bn) {
return BN_marshal_asn1(cbb, bn);
}
-static RSA *parse_public_key(CBS *cbs, int buggy) {
+RSA *RSA_parse_public_key(CBS *cbs) {
RSA *ret = RSA_new();
if (ret == NULL) {
return NULL;
}
CBS child;
if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
- !parse_integer_buggy(&child, &ret->n, buggy) ||
+ !parse_integer(&child, &ret->n) ||
!parse_integer(&child, &ret->e) ||
CBS_len(&child) != 0) {
OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING);
@@ -119,18 +112,6 @@ static RSA *parse_public_key(CBS *cbs, int buggy) {
return ret;
}
-RSA *RSA_parse_public_key(CBS *cbs) {
- return parse_public_key(cbs, 0 /* not buggy */);
-}
-
-RSA *RSA_parse_public_key_buggy(CBS *cbs) {
- // Estonian IDs issued between September 2014 to September 2015 are
- // broken. See https://crbug.com/532048 and https://crbug.com/534766.
- //
- // TODO(davidben): Remove this code and callers in March 2016.
- return parse_public_key(cbs, 1 /* buggy */);
-}
-
RSA *RSA_public_key_from_bytes(const uint8_t *in, size_t in_len) {
CBS cbs;
CBS_init(&cbs, in, in_len);
diff --git a/src/crypto/rsa_extra/rsa_test.cc b/src/crypto/rsa_extra/rsa_test.cc
index 1cc71eab..23e8c67c 100644
--- a/src/crypto/rsa_extra/rsa_test.cc
+++ b/src/crypto/rsa_extra/rsa_test.cc
@@ -622,13 +622,6 @@ TEST(RSATest, ASN1) {
sizeof(kEstonianRSAKey)));
EXPECT_FALSE(rsa);
ERR_clear_error();
-
- // But |RSA_parse_public_key_buggy| will accept it.
- CBS cbs;
- CBS_init(&cbs, kEstonianRSAKey, sizeof(kEstonianRSAKey));
- rsa.reset(RSA_parse_public_key_buggy(&cbs));
- EXPECT_TRUE(rsa);
- EXPECT_EQ(0u, CBS_len(&cbs));
}
TEST(RSATest, BadExponent) {
diff --git a/src/crypto/x509/by_dir.c b/src/crypto/x509/by_dir.c
index d72f9ec2..635b851f 100644
--- a/src/crypto/x509/by_dir.c
+++ b/src/crypto/x509/by_dir.c
@@ -61,7 +61,6 @@
#include <openssl/buf.h>
#include <openssl/err.h>
-#include <openssl/lhash.h>
#include <openssl/mem.h>
#include <openssl/thread.h>
#include <openssl/x509.h>
@@ -235,8 +234,7 @@ static int add_cert_dir(BY_DIR *ctx, const char *dir, int type)
by_dir_entry_free(ent);
return 0;
}
- strncpy(ent->dir, ss, len);
- ent->dir[len] = '\0';
+ BUF_strlcpy(ent->dir, ss, len + 1);
if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent)) {
by_dir_entry_free(ent);
return 0;
diff --git a/src/crypto/x509/by_file.c b/src/crypto/x509/by_file.c
index 2bec572c..555cb854 100644
--- a/src/crypto/x509/by_file.c
+++ b/src/crypto/x509/by_file.c
@@ -59,7 +59,6 @@
#include <openssl/buf.h>
#include <openssl/err.h>
-#include <openssl/lhash.h>
#include <openssl/pem.h>
#include <openssl/thread.h>
diff --git a/src/crypto/x509/x509_lu.c b/src/crypto/x509/x509_lu.c
index 1014a05c..1a841dbe 100644
--- a/src/crypto/x509/x509_lu.c
+++ b/src/crypto/x509/x509_lu.c
@@ -58,7 +58,6 @@
#include <string.h>
#include <openssl/err.h>
-#include <openssl/lhash.h>
#include <openssl/mem.h>
#include <openssl/thread.h>
#include <openssl/x509.h>
diff --git a/src/crypto/x509/x509_obj.c b/src/crypto/x509/x509_obj.c
index 33eafc42..65b1bfb5 100644
--- a/src/crypto/x509/x509_obj.c
+++ b/src/crypto/x509/x509_obj.c
@@ -59,7 +59,6 @@
#include <openssl/buf.h>
#include <openssl/err.h>
-#include <openssl/lhash.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/x509.h>
@@ -102,8 +101,7 @@ char *X509_NAME_oneline(X509_NAME *a, char *buf, int len)
buf = b->data;
OPENSSL_free(b);
}
- strncpy(buf, "NO X509_NAME", len);
- buf[len - 1] = '\0';
+ BUF_strlcpy(buf, "NO X509_NAME", len);
return buf;
}
diff --git a/src/crypto/x509/x509_txt.c b/src/crypto/x509/x509_txt.c
index 17e6cdb9..753e7202 100644
--- a/src/crypto/x509/x509_txt.c
+++ b/src/crypto/x509/x509_txt.c
@@ -54,13 +54,7 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
-#include <openssl/asn1.h>
-#include <openssl/buf.h>
-#include <openssl/cipher.h>
-#include <openssl/evp.h>
-#include <openssl/lhash.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
#include <openssl/x509.h>
const char *X509_verify_cert_error_string(long n)
diff --git a/src/crypto/x509/x509_vfy.c b/src/crypto/x509/x509_vfy.c
index 8e258fef..aff2ee95 100644
--- a/src/crypto/x509/x509_vfy.c
+++ b/src/crypto/x509/x509_vfy.c
@@ -61,7 +61,6 @@
#include <openssl/buf.h>
#include <openssl/err.h>
#include <openssl/evp.h>
-#include <openssl/lhash.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/thread.h>
diff --git a/src/crypto/x509/x509_vpm.c b/src/crypto/x509/x509_vpm.c
index 2317214c..d0f8f794 100644
--- a/src/crypto/x509/x509_vpm.c
+++ b/src/crypto/x509/x509_vpm.c
@@ -57,7 +57,6 @@
#include <string.h>
#include <openssl/buf.h>
-#include <openssl/lhash.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/stack.h>
diff --git a/src/crypto/x509v3/v3_alt.c b/src/crypto/x509v3/v3_alt.c
index 62806519..b78a4105 100644
--- a/src/crypto/x509v3/v3_alt.c
+++ b/src/crypto/x509v3/v3_alt.c
@@ -166,9 +166,9 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
for (i = 0; i < 8; i++) {
BIO_snprintf(htmp, sizeof htmp, "%X", p[0] << 8 | p[1]);
p += 2;
- strcat(oline, htmp);
+ BUF_strlcat(oline, htmp, sizeof(oline));
if (i != 7)
- strcat(oline, ":");
+ BUF_strlcat(oline, ":", sizeof(oline));
}
} else {
if (!X509V3_add_value("IP Address", "<invalid>", &ret))
@@ -588,8 +588,7 @@ static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
objtmp = OPENSSL_malloc(objlen + 1);
if (objtmp == NULL)
return 0;
- strncpy(objtmp, value, objlen);
- objtmp[objlen] = 0;
+ BUF_strlcpy(objtmp, value, objlen + 1);
gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0);
OPENSSL_free(objtmp);
if (!gen->d.otherName->type_id)
diff --git a/src/crypto/x509v3/v3_genn.c b/src/crypto/x509v3/v3_genn.c
index 2331cd49..8c926879 100644
--- a/src/crypto/x509v3/v3_genn.c
+++ b/src/crypto/x509v3/v3_genn.c
@@ -231,6 +231,7 @@ int GENERAL_NAME_set0_othername(GENERAL_NAME *gen,
oth = OTHERNAME_new();
if (!oth)
return 0;
+ ASN1_TYPE_free(oth->value);
oth->type_id = oid;
oth->value = value;
GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth);
diff --git a/src/crypto/x509v3/v3_info.c b/src/crypto/x509v3/v3_info.c
index 40f451fe..ff96489e 100644
--- a/src/crypto/x509v3/v3_info.c
+++ b/src/crypto/x509v3/v3_info.c
@@ -192,8 +192,7 @@ static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD
OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
- strncpy(objtmp, cnf->name, objlen);
- objtmp[objlen] = 0;
+ BUF_strlcpy(objtmp, cnf->name, objlen + 1);
acc->method = OBJ_txt2obj(objtmp, 0);
if (!acc->method) {
OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_OBJECT);