Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

deps: float b18162a7c from openssl (CVE-2018-5407) (8.x and 6.x only) #24352

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions deps/openssl/openssl/crypto/bn/bn_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -889,6 +889,38 @@ void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords)
a->top ^= t;
b->top ^= t;

t = (a->neg ^ b->neg) & condition;
a->neg ^= t;
b->neg ^= t;

/*-
* BN_FLG_STATIC_DATA: indicates that data may not be written to. Intention
* is actually to treat it as it's read-only data, and some (if not most)
* of it does reside in read-only segment. In other words observation of
* BN_FLG_STATIC_DATA in BN_consttime_swap should be treated as fatal
* condition. It would either cause SEGV or effectively cause data
* corruption.
*
* BN_FLG_MALLOCED: refers to BN structure itself, and hence must be
* preserved.
*
* BN_FLG_SECURE: must be preserved, because it determines how x->d was
* allocated and hence how to free it.
*
* BN_FLG_CONSTTIME: sufficient to mask and swap
*
* BN_FLG_FIXED_TOP: indicates that we haven't called bn_correct_top() on
* the data, so the d array may be padded with additional 0 values (i.e.
* top could be greater than the minimal value that it could be). We should
* be swapping it
*/

#define BN_CONSTTIME_SWAP_FLAGS (BN_FLG_CONSTTIME | BN_FLG_FIXED_TOP)

t = ((a->flags ^ b->flags) & BN_CONSTTIME_SWAP_FLAGS) & condition;
a->flags ^= t;
b->flags ^= t;

#define BN_CONSTTIME_SWAP(ind) \
do { \
t = (a->d[ind] ^ b->d[ind]) & condition; \
Expand Down
246 changes: 246 additions & 0 deletions deps/openssl/openssl/crypto/ec/ec_mult.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,224 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len)
return r;
}

#define EC_POINT_BN_set_flags(P, flags) do { \
BN_set_flags(&(P)->X, (flags)); \
BN_set_flags(&(P)->Y, (flags)); \
BN_set_flags(&(P)->Z, (flags)); \
} while(0)

/*-
* This functions computes (in constant time) a point multiplication over the
* EC group.
*
* At a high level, it is Montgomery ladder with conditional swaps.
*
* It performs either a fixed scalar point multiplication
* (scalar * generator)
* when point is NULL, or a generic scalar point multiplication
* (scalar * point)
* when point is not NULL.
*
* scalar should be in the range [0,n) otherwise all constant time bets are off.
*
* NB: This says nothing about EC_POINT_add and EC_POINT_dbl,
* which of course are not constant time themselves.
*
* The product is stored in r.
*
* Returns 1 on success, 0 otherwise.
*/
static int ec_mul_consttime(const EC_GROUP *group, EC_POINT *r,
const BIGNUM *scalar, const EC_POINT *point,
BN_CTX *ctx)
{
int i, cardinality_bits, group_top, kbit, pbit, Z_is_one;
EC_POINT *s = NULL;
BIGNUM *k = NULL;
BIGNUM *lambda = NULL;
BIGNUM *cardinality = NULL;
BN_CTX *new_ctx = NULL;
int ret = 0;

if (ctx == NULL && (ctx = new_ctx = BN_CTX_new()) == NULL)
return 0;

BN_CTX_start(ctx);

s = EC_POINT_new(group);
if (s == NULL)
goto err;

if (point == NULL) {
if (!EC_POINT_copy(s, group->generator))
goto err;
} else {
if (!EC_POINT_copy(s, point))
goto err;
}

EC_POINT_BN_set_flags(s, BN_FLG_CONSTTIME);

cardinality = BN_CTX_get(ctx);
lambda = BN_CTX_get(ctx);
k = BN_CTX_get(ctx);
if (k == NULL || !BN_mul(cardinality, &group->order, &group->cofactor, ctx))
goto err;

/*
* Group cardinalities are often on a word boundary.
* So when we pad the scalar, some timing diff might
* pop if it needs to be expanded due to carries.
* So expand ahead of time.
*/
cardinality_bits = BN_num_bits(cardinality);
group_top = cardinality->top;
if ((bn_wexpand(k, group_top + 2) == NULL)
|| (bn_wexpand(lambda, group_top + 2) == NULL))
goto err;

if (!BN_copy(k, scalar))
goto err;

BN_set_flags(k, BN_FLG_CONSTTIME);

if ((BN_num_bits(k) > cardinality_bits) || (BN_is_negative(k))) {
/*-
* this is an unusual input, and we don't guarantee
* constant-timeness
*/
if (!BN_nnmod(k, k, cardinality, ctx))
goto err;
}

if (!BN_add(lambda, k, cardinality))
goto err;
BN_set_flags(lambda, BN_FLG_CONSTTIME);
if (!BN_add(k, lambda, cardinality))
goto err;
/*
* lambda := scalar + cardinality
* k := scalar + 2*cardinality
*/
kbit = BN_is_bit_set(lambda, cardinality_bits);
BN_consttime_swap(kbit, k, lambda, group_top + 2);

group_top = group->field.top;
if ((bn_wexpand(&s->X, group_top) == NULL)
|| (bn_wexpand(&s->Y, group_top) == NULL)
|| (bn_wexpand(&s->Z, group_top) == NULL)
|| (bn_wexpand(&r->X, group_top) == NULL)
|| (bn_wexpand(&r->Y, group_top) == NULL)
|| (bn_wexpand(&r->Z, group_top) == NULL))
goto err;

/* top bit is a 1, in a fixed pos */
if (!EC_POINT_copy(r, s))
goto err;

EC_POINT_BN_set_flags(r, BN_FLG_CONSTTIME);

if (!EC_POINT_dbl(group, s, s, ctx))
goto err;

pbit = 0;

#define EC_POINT_CSWAP(c, a, b, w, t) do { \
BN_consttime_swap(c, &(a)->X, &(b)->X, w); \
BN_consttime_swap(c, &(a)->Y, &(b)->Y, w); \
BN_consttime_swap(c, &(a)->Z, &(b)->Z, w); \
t = ((a)->Z_is_one ^ (b)->Z_is_one) & (c); \
(a)->Z_is_one ^= (t); \
(b)->Z_is_one ^= (t); \
} while(0)

/*-
* The ladder step, with branches, is
*
* k[i] == 0: S = add(R, S), R = dbl(R)
* k[i] == 1: R = add(S, R), S = dbl(S)
*
* Swapping R, S conditionally on k[i] leaves you with state
*
* k[i] == 0: T, U = R, S
* k[i] == 1: T, U = S, R
*
* Then perform the ECC ops.
*
* U = add(T, U)
* T = dbl(T)
*
* Which leaves you with state
*
* k[i] == 0: U = add(R, S), T = dbl(R)
* k[i] == 1: U = add(S, R), T = dbl(S)
*
* Swapping T, U conditionally on k[i] leaves you with state
*
* k[i] == 0: R, S = T, U
* k[i] == 1: R, S = U, T
*
* Which leaves you with state
*
* k[i] == 0: S = add(R, S), R = dbl(R)
* k[i] == 1: R = add(S, R), S = dbl(S)
*
* So we get the same logic, but instead of a branch it's a
* conditional swap, followed by ECC ops, then another conditional swap.
*
* Optimization: The end of iteration i and start of i-1 looks like
*
* ...
* CSWAP(k[i], R, S)
* ECC
* CSWAP(k[i], R, S)
* (next iteration)
* CSWAP(k[i-1], R, S)
* ECC
* CSWAP(k[i-1], R, S)
* ...
*
* So instead of two contiguous swaps, you can merge the condition
* bits and do a single swap.
*
* k[i] k[i-1] Outcome
* 0 0 No Swap
* 0 1 Swap
* 1 0 Swap
* 1 1 No Swap
*
* This is XOR. pbit tracks the previous bit of k.
*/

for (i = cardinality_bits - 1; i >= 0; i--) {
kbit = BN_is_bit_set(k, i) ^ pbit;
EC_POINT_CSWAP(kbit, r, s, group_top, Z_is_one);
if (!EC_POINT_add(group, s, r, s, ctx))
goto err;
if (!EC_POINT_dbl(group, r, r, ctx))
goto err;
/*
* pbit logic merges this cswap with that of the
* next iteration
*/
pbit ^= kbit;
}
/* one final cswap to move the right value into r */
EC_POINT_CSWAP(pbit, r, s, group_top, Z_is_one);
#undef EC_POINT_CSWAP

ret = 1;

err:
EC_POINT_free(s);
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);

return ret;
}

#undef EC_POINT_BN_set_flags

/*
* TODO: table should be optimised for the wNAF-based implementation,
* sometimes smaller windows will give better performance (thus the
Expand Down Expand Up @@ -369,6 +587,34 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
return EC_POINT_set_to_infinity(group, r);
}

if (!BN_is_zero(&group->order) && !BN_is_zero(&group->cofactor)) {
/*-
* Handle the common cases where the scalar is secret, enforcing a constant
* time scalar multiplication algorithm.
*/
if ((scalar != NULL) && (num == 0)) {
/*-
* In this case we want to compute scalar * GeneratorPoint: this
* codepath is reached most prominently by (ephemeral) key generation
* of EC cryptosystems (i.e. ECDSA keygen and sign setup, ECDH
* keygen/first half), where the scalar is always secret. This is why
* we ignore if BN_FLG_CONSTTIME is actually set and we always call the
* constant time version.
*/
return ec_mul_consttime(group, r, scalar, NULL, ctx);
}
if ((scalar == NULL) && (num == 1)) {
/*-
* In this case we want to compute scalar * GenericPoint: this codepath
* is reached most prominently by the second half of ECDH, where the
* secret scalar is multiplied by the peer's public point. To protect
* the secret scalar, we ignore if BN_FLG_CONSTTIME is actually set and
* we always call the constant time version.
*/
return ec_mul_consttime(group, r, scalars[0], points[0], ctx);
}
}

for (i = 0; i < num; i++) {
if (group->meth != points[i]->meth) {
ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS);
Expand Down
2 changes: 1 addition & 1 deletion deps/v8/include/v8-version.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#define V8_MAJOR_VERSION 6
#define V8_MINOR_VERSION 2
#define V8_BUILD_NUMBER 414
#define V8_PATCH_LEVEL 70
#define V8_PATCH_LEVEL 73

// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
Expand Down
7 changes: 3 additions & 4 deletions deps/v8/src/base/debug/stack_trace_posix.cc
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ const char kMangledSymbolPrefix[] = "_Z";
const char kSymbolCharacters[] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";

#if HAVE_EXECINFO_H
// Demangles C++ symbols in the given text. Example:
//
// "out/Debug/base_unittests(_ZN10StackTraceC1Ev+0x20) [0x817778c]"
Expand All @@ -81,7 +82,6 @@ void DemangleSymbols(std::string* text) {
// Note: code in this function is NOT async-signal safe (std::string uses
// malloc internally).

#if HAVE_EXECINFO_H

std::string::size_type search_from = 0;
while (search_from < text->size()) {
Expand Down Expand Up @@ -117,9 +117,8 @@ void DemangleSymbols(std::string* text) {
search_from = mangled_start + 2;
}
}

#endif // HAVE_EXECINFO_H
}
#endif // HAVE_EXECINFO_H

class BacktraceOutputHandler {
public:
Expand All @@ -129,6 +128,7 @@ class BacktraceOutputHandler {
virtual ~BacktraceOutputHandler() {}
};

#if HAVE_EXECINFO_H
void OutputPointer(void* pointer, BacktraceOutputHandler* handler) {
// This should be more than enough to store a 64-bit number in hex:
// 16 hex digits + 1 for null-terminator.
Expand All @@ -139,7 +139,6 @@ void OutputPointer(void* pointer, BacktraceOutputHandler* handler) {
handler->HandleOutput(buf);
}

#if HAVE_EXECINFO_H
void ProcessBacktrace(void* const* trace, size_t size,
BacktraceOutputHandler* handler) {
// NOTE: This code MUST be async-signal safe (it's used by in-process
Expand Down
2 changes: 1 addition & 1 deletion deps/v8/src/compiler/bytecode-graph-builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ Node* BytecodeGraphBuilder::Environment::Checkpoint(
BytecodeGraphBuilder::BytecodeGraphBuilder(
Zone* local_zone, Handle<SharedFunctionInfo> shared_info,
Handle<FeedbackVector> feedback_vector, BailoutId osr_offset,
JSGraph* jsgraph, CallFrequency invocation_frequency,
JSGraph* jsgraph, CallFrequency& invocation_frequency,
SourcePositionTable* source_positions, int inlining_id,
JSTypeHintLowering::Flags flags, bool stack_check)
: local_zone_(local_zone),
Expand Down
2 changes: 1 addition & 1 deletion deps/v8/src/compiler/bytecode-graph-builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class BytecodeGraphBuilder {
BytecodeGraphBuilder(
Zone* local_zone, Handle<SharedFunctionInfo> shared,
Handle<FeedbackVector> feedback_vector, BailoutId osr_offset,
JSGraph* jsgraph, CallFrequency invocation_frequency,
JSGraph* jsgraph, CallFrequency& invocation_frequency,
SourcePositionTable* source_positions,
int inlining_id = SourcePosition::kNotInlined,
JSTypeHintLowering::Flags flags = JSTypeHintLowering::kNoFlags,
Expand Down
3 changes: 2 additions & 1 deletion deps/v8/src/compiler/js-inlining.cc
Original file line number Diff line number Diff line change
Expand Up @@ -539,9 +539,10 @@ Reduction JSInliner::ReduceJSCall(Node* node) {
if (info_->is_bailout_on_uninitialized()) {
flags |= JSTypeHintLowering::kBailoutOnUninitialized;
}
CallFrequency frequency = call.frequency();
BytecodeGraphBuilder graph_builder(
zone(), shared_info, feedback_vector, BailoutId::None(), jsgraph(),
call.frequency(), source_positions_, inlining_id, flags, false);
frequency, source_positions_, inlining_id, flags, false);
graph_builder.CreateGraph();

// Extract the inlinee start/end nodes.
Expand Down
Loading