Import OpenSSL 1.0.2q
This commit is contained in:
@@ -36,9 +36,11 @@ TEST=constant_time_test.c
|
||||
LIB= $(TOP)/libcrypto.a
|
||||
SHARED_LIB= libcrypto$(SHLIB_EXT)
|
||||
LIBSRC= cryptlib.c mem.c mem_clr.c mem_dbg.c cversion.c ex_data.c cpt_err.c \
|
||||
ebcdic.c uid.c o_time.c o_str.c o_dir.c o_fips.c o_init.c fips_ers.c
|
||||
ebcdic.c uid.c o_time.c o_str.c o_dir.c o_fips.c o_init.c fips_ers.c \
|
||||
getenv.c
|
||||
LIBOBJ= cryptlib.o mem.o mem_dbg.o cversion.o ex_data.o cpt_err.o ebcdic.o \
|
||||
uid.o o_time.o o_str.o o_dir.o o_fips.o o_init.o fips_ers.o $(CPUID_OBJ)
|
||||
uid.o o_time.o o_str.o o_dir.o o_fips.o o_init.o fips_ers.o getenv.o \
|
||||
$(CPUID_OBJ)
|
||||
|
||||
SRC= $(LIBSRC)
|
||||
|
||||
@@ -178,6 +180,13 @@ ex_data.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
|
||||
ex_data.o: ../include/openssl/stack.h ../include/openssl/symhacks.h cryptlib.h
|
||||
ex_data.o: ex_data.c
|
||||
fips_ers.o: ../include/openssl/opensslconf.h fips_ers.c
|
||||
getenv.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h
|
||||
getenv.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
|
||||
getenv.o: ../include/openssl/err.h ../include/openssl/lhash.h
|
||||
getenv.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
|
||||
getenv.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
|
||||
getenv.o: ../include/openssl/stack.h ../include/openssl/symhacks.h cryptlib.h
|
||||
getenv.o: getenv.c
|
||||
mem.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h
|
||||
mem.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
|
||||
mem.o: ../include/openssl/err.h ../include/openssl/lhash.h
|
||||
|
||||
@@ -56,6 +56,9 @@
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#define _DEFAULT_SOURCE
|
||||
#define _BSD_SOURCE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
@@ -83,6 +86,11 @@ NETDB_DEFINE_CONTEXT
|
||||
static int wsa_init_done = 0;
|
||||
# endif
|
||||
|
||||
# if defined(__GLIBC__)
|
||||
# define HAVE_GETHOSTBYNAME_R
|
||||
# define GETHOSTNAME_R_BUF (2 * 1024)
|
||||
# endif
|
||||
|
||||
/*
|
||||
* WSAAPI specifier is required to make indirect calls to run-time
|
||||
* linked WinSock 2 functions used in this module, to be specific
|
||||
@@ -116,7 +124,12 @@ int BIO_get_host_ip(const char *str, unsigned char *ip)
|
||||
int i;
|
||||
int err = 1;
|
||||
int locked = 0;
|
||||
struct hostent *he;
|
||||
struct hostent *he = NULL;
|
||||
# ifdef HAVE_GETHOSTBYNAME_R
|
||||
char buf[GETHOSTNAME_R_BUF];
|
||||
struct hostent hostent;
|
||||
int h_errnop;
|
||||
# endif
|
||||
|
||||
i = get_ip(str, ip);
|
||||
if (i < 0) {
|
||||
@@ -138,10 +151,18 @@ int BIO_get_host_ip(const char *str, unsigned char *ip)
|
||||
if (i > 0)
|
||||
return (1);
|
||||
|
||||
/* if gethostbyname_r is supported, use it. */
|
||||
# ifdef HAVE_GETHOSTBYNAME_R
|
||||
memset(&hostent, 0x00, sizeof(hostent));
|
||||
/* gethostbyname_r() sets |he| to NULL on error, we check it further down */
|
||||
gethostbyname_r(str, &hostent, buf, sizeof(buf), &he, &h_errnop);
|
||||
# else
|
||||
/* do a gethostbyname */
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
|
||||
locked = 1;
|
||||
he = BIO_gethostbyname(str);
|
||||
# endif
|
||||
|
||||
if (he == NULL) {
|
||||
BIOerr(BIO_F_BIO_GET_HOST_IP, BIO_R_BAD_HOSTNAME_LOOKUP);
|
||||
goto err;
|
||||
|
||||
@@ -55,12 +55,6 @@
|
||||
* machine.
|
||||
*/
|
||||
|
||||
# if defined(_WIN64) || !defined(__LP64__)
|
||||
# define BN_ULONG unsigned long long
|
||||
# else
|
||||
# define BN_ULONG unsigned long
|
||||
# endif
|
||||
|
||||
# undef mul
|
||||
# undef mul_add
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* crypto/bn/bn_blind.c */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
|
||||
* Copyright (c) 1998-2018 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
|
||||
@@ -206,10 +206,15 @@ int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx)
|
||||
if (!BN_BLINDING_create_param(b, NULL, NULL, ctx, NULL, NULL))
|
||||
goto err;
|
||||
} else if (!(b->flags & BN_BLINDING_NO_UPDATE)) {
|
||||
if (!BN_mod_mul(b->A, b->A, b->A, b->mod, ctx))
|
||||
goto err;
|
||||
if (!BN_mod_mul(b->Ai, b->Ai, b->Ai, b->mod, ctx))
|
||||
goto err;
|
||||
if (b->m_ctx != NULL) {
|
||||
if (!bn_mul_mont_fixed_top(b->Ai, b->Ai, b->Ai, b->m_ctx, ctx)
|
||||
|| !bn_mul_mont_fixed_top(b->A, b->A, b->A, b->m_ctx, ctx))
|
||||
goto err;
|
||||
} else {
|
||||
if (!BN_mod_mul(b->Ai, b->Ai, b->Ai, b->mod, ctx)
|
||||
|| !BN_mod_mul(b->A, b->A, b->A, b->mod, ctx))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
@@ -241,13 +246,13 @@ int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx)
|
||||
else if (!BN_BLINDING_update(b, ctx))
|
||||
return (0);
|
||||
|
||||
if (r != NULL) {
|
||||
if (!BN_copy(r, b->Ai))
|
||||
ret = 0;
|
||||
}
|
||||
if (r != NULL && (BN_copy(r, b->Ai) == NULL))
|
||||
return 0;
|
||||
|
||||
if (!BN_mod_mul(n, n, b->A, b->mod, ctx))
|
||||
ret = 0;
|
||||
if (b->m_ctx != NULL)
|
||||
ret = BN_mod_mul_montgomery(n, n, b->A, b->m_ctx, ctx);
|
||||
else
|
||||
ret = BN_mod_mul(n, n, b->A, b->mod, ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -264,14 +269,29 @@ int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b,
|
||||
|
||||
bn_check_top(n);
|
||||
|
||||
if (r != NULL)
|
||||
ret = BN_mod_mul(n, n, r, b->mod, ctx);
|
||||
else {
|
||||
if (b->Ai == NULL) {
|
||||
BNerr(BN_F_BN_BLINDING_INVERT_EX, BN_R_NOT_INITIALIZED);
|
||||
return (0);
|
||||
if (r == NULL && (r = b->Ai) == NULL) {
|
||||
BNerr(BN_F_BN_BLINDING_INVERT_EX, BN_R_NOT_INITIALIZED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (b->m_ctx != NULL) {
|
||||
/* ensure that BN_mod_mul_montgomery takes pre-defined path */
|
||||
if (n->dmax >= r->top) {
|
||||
size_t i, rtop = r->top, ntop = n->top;
|
||||
BN_ULONG mask;
|
||||
|
||||
for (i = 0; i < rtop; i++) {
|
||||
mask = (BN_ULONG)0 - ((i - ntop) >> (8 * sizeof(i) - 1));
|
||||
n->d[i] &= mask;
|
||||
}
|
||||
mask = (BN_ULONG)0 - ((rtop - ntop) >> (8 * sizeof(ntop) - 1));
|
||||
/* always true, if (rtop >= ntop) n->top = r->top; */
|
||||
n->top = (int)(rtop & ~mask) | (ntop & mask);
|
||||
n->flags |= (BN_FLG_FIXED_TOP & ~mask);
|
||||
}
|
||||
ret = BN_mod_mul(n, n, b->Ai, b->mod, ctx);
|
||||
ret = BN_mod_mul_montgomery(n, n, r, b->m_ctx, ctx);
|
||||
} else {
|
||||
ret = BN_mod_mul(n, n, r, b->mod, ctx);
|
||||
}
|
||||
|
||||
bn_check_top(n);
|
||||
@@ -366,14 +386,19 @@ BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
|
||||
} while (1);
|
||||
|
||||
if (ret->bn_mod_exp != NULL && ret->m_ctx != NULL) {
|
||||
if (!ret->bn_mod_exp
|
||||
(ret->A, ret->A, ret->e, ret->mod, ctx, ret->m_ctx))
|
||||
if (!ret->bn_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx, ret->m_ctx))
|
||||
goto err;
|
||||
} else {
|
||||
if (!BN_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ret->m_ctx != NULL) {
|
||||
if (!bn_to_mont_fixed_top(ret->Ai, ret->Ai, ret->m_ctx, ctx)
|
||||
|| !bn_to_mont_fixed_top(ret->A, ret->A, ret->m_ctx, ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
return ret;
|
||||
err:
|
||||
if (b == NULL && ret != NULL) {
|
||||
|
||||
@@ -617,26 +617,40 @@ BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
|
||||
static int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
|
||||
{
|
||||
int n;
|
||||
size_t i, inc, lasti, j;
|
||||
size_t i, lasti, j, atop, mask;
|
||||
BN_ULONG l;
|
||||
|
||||
/*
|
||||
* In case |a| is fixed-top, BN_num_bytes can return bogus length,
|
||||
* but it's assumed that fixed-top inputs ought to be "nominated"
|
||||
* even for padded output, so it works out...
|
||||
*/
|
||||
n = BN_num_bytes(a);
|
||||
if (tolen == -1)
|
||||
if (tolen == -1) {
|
||||
tolen = n;
|
||||
else if (tolen < n)
|
||||
return -1;
|
||||
} else if (tolen < n) { /* uncommon/unlike case */
|
||||
BIGNUM temp = *a;
|
||||
|
||||
if (n == 0) {
|
||||
bn_correct_top(&temp);
|
||||
n = BN_num_bytes(&temp);
|
||||
if (tolen < n)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Swipe through whole available data and don't give away padded zero. */
|
||||
atop = a->dmax * BN_BYTES;
|
||||
if (atop == 0) {
|
||||
OPENSSL_cleanse(to, tolen);
|
||||
return tolen;
|
||||
}
|
||||
|
||||
lasti = n - 1;
|
||||
for (i = 0, inc = 1, j = tolen; j > 0;) {
|
||||
lasti = atop - 1;
|
||||
atop = a->top * BN_BYTES;
|
||||
for (i = 0, j = 0, to += tolen; j < (size_t)tolen; j++) {
|
||||
l = a->d[i / BN_BYTES];
|
||||
to[--j] = (unsigned char)(l >> (8 * (i % BN_BYTES)) & (0 - inc));
|
||||
inc = (i - lasti) >> (8 * sizeof(i) - 1);
|
||||
i += inc; /* stay on top limb */
|
||||
mask = 0 - ((j - atop) >> (8 * sizeof(i) - 1));
|
||||
*--to = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask);
|
||||
i += (i - lasti) >> (8 * sizeof(i) - 1); /* stay on last limb */
|
||||
}
|
||||
|
||||
return tolen;
|
||||
@@ -889,6 +903,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; \
|
||||
|
||||
@@ -172,7 +172,7 @@ int bn_mod_add_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
|
||||
|
||||
if (mtop > sizeof(storage) / sizeof(storage[0])
|
||||
&& (tp = OPENSSL_malloc(mtop * sizeof(BN_ULONG))) == NULL)
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
ap = a->d != NULL ? a->d : tp;
|
||||
bp = b->d != NULL ? b->d : tp;
|
||||
@@ -197,6 +197,7 @@ int bn_mod_add_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
|
||||
((volatile BN_ULONG *)tp)[i] = 0;
|
||||
}
|
||||
r->top = mtop;
|
||||
r->flags |= BN_FLG_FIXED_TOP;
|
||||
r->neg = 0;
|
||||
|
||||
if (tp != storage)
|
||||
@@ -224,6 +225,70 @@ int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
|
||||
return BN_nnmod(r, r, m, ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* BN_mod_sub variant that may be used if both a and b are non-negative,
|
||||
* a is less than m, while b is of same bit width as m. It's implemented
|
||||
* as subtraction followed by two conditional additions.
|
||||
*
|
||||
* 0 <= a < m
|
||||
* 0 <= b < 2^w < 2*m
|
||||
*
|
||||
* after subtraction
|
||||
*
|
||||
* -2*m < r = a - b < m
|
||||
*
|
||||
* Thus it takes up to two conditional additions to make |r| positive.
|
||||
*/
|
||||
int bn_mod_sub_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
|
||||
const BIGNUM *m)
|
||||
{
|
||||
size_t i, ai, bi, mtop = m->top;
|
||||
BN_ULONG borrow, carry, ta, tb, mask, *rp;
|
||||
const BN_ULONG *ap, *bp;
|
||||
|
||||
if (bn_wexpand(r, m->top) == NULL)
|
||||
return 0;
|
||||
|
||||
rp = r->d;
|
||||
ap = a->d != NULL ? a->d : rp;
|
||||
bp = b->d != NULL ? b->d : rp;
|
||||
|
||||
for (i = 0, ai = 0, bi = 0, borrow = 0; i < mtop;) {
|
||||
mask = (BN_ULONG)0 - ((i - a->top) >> (8 * sizeof(i) - 1));
|
||||
ta = ap[ai] & mask;
|
||||
|
||||
mask = (BN_ULONG)0 - ((i - b->top) >> (8 * sizeof(i) - 1));
|
||||
tb = bp[bi] & mask;
|
||||
rp[i] = ta - tb - borrow;
|
||||
if (ta != tb)
|
||||
borrow = (ta < tb);
|
||||
|
||||
i++;
|
||||
ai += (i - a->dmax) >> (8 * sizeof(i) - 1);
|
||||
bi += (i - b->dmax) >> (8 * sizeof(i) - 1);
|
||||
}
|
||||
ap = m->d;
|
||||
for (i = 0, mask = 0 - borrow, carry = 0; i < mtop; i++) {
|
||||
ta = ((ap[i] & mask) + carry) & BN_MASK2;
|
||||
carry = (ta < carry);
|
||||
rp[i] = (rp[i] + ta) & BN_MASK2;
|
||||
carry += (rp[i] < ta);
|
||||
}
|
||||
borrow -= carry;
|
||||
for (i = 0, mask = 0 - borrow, carry = 0; i < mtop; i++) {
|
||||
ta = ((ap[i] & mask) + carry) & BN_MASK2;
|
||||
carry = (ta < carry);
|
||||
rp[i] = (rp[i] + ta) & BN_MASK2;
|
||||
carry += (rp[i] < ta);
|
||||
}
|
||||
|
||||
r->top = mtop;
|
||||
r->flags |= BN_FLG_FIXED_TOP;
|
||||
r->neg = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* BN_mod_sub variant that may be used if both a and b are non-negative and
|
||||
* less than m
|
||||
|
||||
@@ -164,10 +164,10 @@ int bn_mul_mont_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
|
||||
|
||||
bn_check_top(tmp);
|
||||
if (a == b) {
|
||||
if (!BN_sqr(tmp, a, ctx))
|
||||
if (!bn_sqr_fixed_top(tmp, a, ctx))
|
||||
goto err;
|
||||
} else {
|
||||
if (!BN_mul(tmp, a, b, ctx))
|
||||
if (!bn_mul_fixed_top(tmp, a, b, ctx))
|
||||
goto err;
|
||||
}
|
||||
/* reduce from aRR to aR */
|
||||
@@ -190,6 +190,7 @@ static int bn_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
|
||||
BIGNUM *n;
|
||||
BN_ULONG *ap, *np, *rp, n0, v, carry;
|
||||
int nl, max, i;
|
||||
unsigned int rtop;
|
||||
|
||||
n = &(mont->N);
|
||||
nl = n->top;
|
||||
@@ -207,12 +208,10 @@ static int bn_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
|
||||
rp = r->d;
|
||||
|
||||
/* clear the top words of T */
|
||||
# if 1
|
||||
for (i = r->top; i < max; i++) /* memset? XXX */
|
||||
rp[i] = 0;
|
||||
# else
|
||||
memset(&(rp[r->top]), 0, (max - r->top) * sizeof(BN_ULONG));
|
||||
# endif
|
||||
for (rtop = r->top, i = 0; i < max; i++) {
|
||||
v = (BN_ULONG)0 - ((i - rtop) >> (8 * sizeof(rtop) - 1));
|
||||
rp[i] &= v;
|
||||
}
|
||||
|
||||
r->top = max;
|
||||
r->flags |= BN_FLG_FIXED_TOP;
|
||||
@@ -262,6 +261,18 @@ static int bn_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
|
||||
|
||||
int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
int retn;
|
||||
|
||||
retn = bn_from_mont_fixed_top(ret, a, mont, ctx);
|
||||
bn_correct_top(ret);
|
||||
bn_check_top(ret);
|
||||
|
||||
return retn;
|
||||
}
|
||||
|
||||
int bn_from_mont_fixed_top(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
int retn = 0;
|
||||
#ifdef MONT_WORD
|
||||
@@ -270,8 +281,6 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
|
||||
BN_CTX_start(ctx);
|
||||
if ((t = BN_CTX_get(ctx)) && BN_copy(t, a)) {
|
||||
retn = bn_from_montgomery_word(ret, t, mont);
|
||||
bn_correct_top(ret);
|
||||
bn_check_top(ret);
|
||||
}
|
||||
BN_CTX_end(ctx);
|
||||
#else /* !MONT_WORD */
|
||||
|
||||
@@ -935,6 +935,16 @@ void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
|
||||
#endif /* BN_RECURSION */
|
||||
|
||||
int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
|
||||
{
|
||||
int ret = bn_mul_fixed_top(r, a, b, ctx);
|
||||
|
||||
bn_correct_top(r);
|
||||
bn_check_top(r);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int bn_mul_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
int top, al, bl;
|
||||
@@ -1042,7 +1052,7 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
|
||||
#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
|
||||
end:
|
||||
#endif
|
||||
bn_correct_top(rr);
|
||||
rr->flags |= BN_FLG_FIXED_TOP;
|
||||
if (r != rr && BN_copy(r, rr) == NULL)
|
||||
goto err;
|
||||
|
||||
|
||||
@@ -65,6 +65,16 @@
|
||||
* I've just gone over this and it is now %20 faster on x86 - eay - 27 Jun 96
|
||||
*/
|
||||
int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
|
||||
{
|
||||
int ret = bn_sqr_fixed_top(r, a, ctx);
|
||||
|
||||
bn_correct_top(r);
|
||||
bn_check_top(r);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int bn_sqr_fixed_top(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
|
||||
{
|
||||
int max, al;
|
||||
int ret = 0;
|
||||
@@ -136,7 +146,7 @@ int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
|
||||
|
||||
rr->neg = 0;
|
||||
rr->top = max;
|
||||
bn_correct_top(rr);
|
||||
rr->flags |= BN_FLG_FIXED_TOP;
|
||||
if (r != rr && BN_copy(r, rr) == NULL)
|
||||
goto err;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* 2005.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2005 The OpenSSL Project. All rights reserved.
|
||||
* Copyright (c) 2005-2018 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
|
||||
@@ -223,8 +223,10 @@ int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx)
|
||||
for (i = 0; i < 1000; i++) {
|
||||
if (!BN_rand(Xq, nbits, 1, 0))
|
||||
goto err;
|
||||
|
||||
/* Check that |Xp - Xq| > 2^(nbits - 100) */
|
||||
BN_sub(t, Xp, Xq);
|
||||
if (!BN_sub(t, Xp, Xq))
|
||||
goto err;
|
||||
if (BN_num_bits(t) > (nbits - 100))
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -7,9 +7,15 @@
|
||||
*/
|
||||
int bn_mul_mont_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
|
||||
BN_MONT_CTX *mont, BN_CTX *ctx);
|
||||
int bn_from_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont,
|
||||
BN_CTX *ctx);
|
||||
int bn_to_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont,
|
||||
BN_CTX *ctx);
|
||||
int bn_mod_add_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
|
||||
const BIGNUM *m);
|
||||
int bn_mod_sub_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
|
||||
const BIGNUM *m);
|
||||
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);
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
/* auto-generated/updated by util/mk1mf.pl for crypto/cversion.c */
|
||||
#define CFLAGS "compiler: cl /MD /Ox /O2 /Ob2 -DOPENSSL_THREADS -DDSO_WIN32 -W3 -WX -Gs0 -GF -Gy -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -D_CRT_SECURE_NO_DEPRECATE -D_WINSOCK_DEPRECATED_NO_WARNINGS -DOPENSSL_BN_ASM_PART_WORDS -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_GF2m -DRC4_ASM -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DRMD160_ASM -DAES_ASM -DVPAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -DOPENSSL_USE_APPLINK -I. -DOPENSSL_NO_IDEA -DOPENSSL_NO_RC5 -DOPENSSL_NO_MD2 -DOPENSSL_NO_MDC2 -DOPENSSL_NO_SSL2 -DOPENSSL_NO_KRB5 -DOPENSSL_NO_JPAKE -DOPENSSL_NO_WEAK_SSL_CIPHERS -DOPENSSL_NO_STATIC_ENGINE "
|
||||
#define PLATFORM "VC-WIN32"
|
||||
#define DATE "Tue Aug 14 16:04:24 2018"
|
||||
#define DATE "Fri Dec 7 19:08:23 2018"
|
||||
#endif
|
||||
#ifdef MK1MF_PLATFORM_BC_NT
|
||||
/* auto-generated/updated by util/mk1mf.pl for crypto/cversion.c */
|
||||
#define CFLAGS "compiler: bcc32 -DWIN32_LEAN_AND_MEAN -q -w-ccc -w-rch -w-pia -w-aus -w-par -w-inl -c -tWC -tWM -DOPENSSL_SYSNAME_WIN32 -DL_ENDIAN -DDSO_WIN32 -D_stricmp=stricmp -D_strnicmp=strnicmp -O2 -ff -fp -DBN_ASM -DMD5_ASM -DSHA1_ASM -DRMD160_ASM -DOPENSSL_NO_IDEA -DOPENSSL_NO_RC5 -DOPENSSL_NO_MD2 -DOPENSSL_NO_MDC2 -DOPENSSL_NO_SSL2 -DOPENSSL_NO_KRB5 -DOPENSSL_NO_JPAKE -DOPENSSL_NO_WEAK_SSL_CIPHERS -DOPENSSL_NO_DYNAMIC_ENGINE "
|
||||
#define PLATFORM "BC-NT"
|
||||
#define DATE "Tue Aug 14 16:04:24 2018"
|
||||
#define DATE "Fri Dec 7 19:08:23 2018"
|
||||
#endif
|
||||
|
||||
@@ -80,12 +80,13 @@ clean:
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
|
||||
conf_api.o: ../../e_os.h ../../include/openssl/bio.h
|
||||
conf_api.o: ../../include/openssl/conf.h ../../include/openssl/conf_api.h
|
||||
conf_api.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
|
||||
conf_api.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
|
||||
conf_api.o: ../../include/openssl/conf_api.h ../../include/openssl/crypto.h
|
||||
conf_api.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
|
||||
conf_api.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
|
||||
conf_api.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
conf_api.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
|
||||
conf_api.o: ../../include/openssl/symhacks.h conf_api.c
|
||||
conf_api.o: ../../include/openssl/symhacks.h ../cryptlib.h conf_api.c
|
||||
conf_def.o: ../../e_os.h ../../include/openssl/bio.h
|
||||
conf_def.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
|
||||
conf_def.o: ../../include/openssl/conf_api.h ../../include/openssl/crypto.h
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "cryptlib.h"
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/conf_api.h>
|
||||
#include "e_os.h"
|
||||
@@ -141,7 +142,7 @@ char *_CONF_get_string(const CONF *conf, const char *section,
|
||||
if (v != NULL)
|
||||
return (v->value);
|
||||
if (strcmp(section, "ENV") == 0) {
|
||||
p = getenv(name);
|
||||
p = ossl_safe_getenv(name);
|
||||
if (p != NULL)
|
||||
return (p);
|
||||
}
|
||||
@@ -154,7 +155,7 @@ char *_CONF_get_string(const CONF *conf, const char *section,
|
||||
else
|
||||
return (NULL);
|
||||
} else
|
||||
return (getenv(name));
|
||||
return (ossl_safe_getenv(name));
|
||||
}
|
||||
|
||||
#if 0 /* There's no way to provide error checking
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* 2001.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2001 The OpenSSL Project. All rights reserved.
|
||||
* Copyright (c) 2001-2018 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
|
||||
@@ -530,7 +530,7 @@ char *CONF_get1_default_config_file(void)
|
||||
char *file;
|
||||
int len;
|
||||
|
||||
file = getenv("OPENSSL_CONF");
|
||||
file = ossl_safe_getenv("OPENSSL_CONF");
|
||||
if (file)
|
||||
return BUF_strdup(file);
|
||||
|
||||
|
||||
@@ -104,6 +104,8 @@ void OPENSSL_showfatal(const char *fmta, ...);
|
||||
void *OPENSSL_stderr(void);
|
||||
extern int OPENSSL_NONPIC_relocated;
|
||||
|
||||
char *ossl_safe_getenv(const char *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -214,7 +214,8 @@ $! The contents of these variables are copied from the LIBOBJ variable in the
|
||||
$! corresponding Makefile from each corresponding subdirectory, with .o stripped
|
||||
$! and spaces replaced with commas.
|
||||
$ LIB_ = "cryptlib,mem,mem_dbg,cversion,ex_data,cpt_err,ebcdic,"+ -
|
||||
"uid,o_time,o_str,o_dir,o_fips,o_init,fips_ers,mem_clr"
|
||||
"uid,o_time,o_str,o_dir,o_fips,o_init,fips_ers,mem_clr,"+ -
|
||||
"getenv"
|
||||
$ LIB_OBJECTS = "o_names,obj_dat,obj_lib,obj_err,obj_xref"
|
||||
$ LIB_MD2 = "md2_dgst,md2_one"
|
||||
$ LIB_MD4 = "md4_dgst,md4_one"
|
||||
|
||||
@@ -435,6 +435,12 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
|
||||
|
||||
EVP_MD_CTX_init(&mctx);
|
||||
|
||||
/* make sure L > N, otherwise we'll get trapped in an infinite loop */
|
||||
if (L <= N) {
|
||||
DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_INVALID_PARAMETERS);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (evpmd == NULL) {
|
||||
if (N == 160)
|
||||
evpmd = EVP_sha1();
|
||||
|
||||
@@ -73,6 +73,8 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len,
|
||||
DSA_SIG *sig, DSA *dsa);
|
||||
static int dsa_init(DSA *dsa);
|
||||
static int dsa_finish(DSA *dsa);
|
||||
static BIGNUM *dsa_mod_inverse_fermat(const BIGNUM *k, const BIGNUM *q,
|
||||
BN_CTX *ctx);
|
||||
|
||||
static DSA_METHOD openssl_dsa_meth = {
|
||||
"OpenSSL DSA method",
|
||||
@@ -279,7 +281,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
|
||||
goto err;
|
||||
|
||||
/* Preallocate space */
|
||||
q_bits = BN_num_bits(dsa->q);
|
||||
q_bits = BN_num_bits(dsa->q) + sizeof(dsa->q->d[0]) * 16;
|
||||
if (!BN_set_bit(&k, q_bits)
|
||||
|| !BN_set_bit(&l, q_bits)
|
||||
|| !BN_set_bit(&m, q_bits))
|
||||
@@ -293,9 +295,9 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
|
||||
|
||||
if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) {
|
||||
BN_set_flags(&k, BN_FLG_CONSTTIME);
|
||||
BN_set_flags(&l, BN_FLG_CONSTTIME);
|
||||
}
|
||||
|
||||
|
||||
if (dsa->flags & DSA_FLAG_CACHE_MONT_P) {
|
||||
if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p,
|
||||
CRYPTO_LOCK_DSA, dsa->p, ctx))
|
||||
@@ -333,8 +335,8 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
|
||||
if (!BN_mod(r, r, dsa->q, ctx))
|
||||
goto err;
|
||||
|
||||
/* Compute part of 's = inv(k) (m + xr) mod q' */
|
||||
if ((kinv = BN_mod_inverse(NULL, &k, dsa->q, ctx)) == NULL)
|
||||
/* Compute part of 's = inv(k) (m + xr) mod q' */
|
||||
if ((kinv = dsa_mod_inverse_fermat(&k, dsa->q, ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (*kinvp != NULL)
|
||||
@@ -468,3 +470,31 @@ static int dsa_finish(DSA *dsa)
|
||||
BN_MONT_CTX_free(dsa->method_mont_p);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the inverse of k modulo q.
|
||||
* Since q is prime, Fermat's Little Theorem applies, which reduces this to
|
||||
* mod-exp operation. Both the exponent and modulus are public information
|
||||
* so a mod-exp that doesn't leak the base is sufficient. A newly allocated
|
||||
* BIGNUM is returned which the caller must free.
|
||||
*/
|
||||
static BIGNUM *dsa_mod_inverse_fermat(const BIGNUM *k, const BIGNUM *q,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *res = NULL;
|
||||
BIGNUM *r, e;
|
||||
|
||||
if ((r = BN_new()) == NULL)
|
||||
return NULL;
|
||||
|
||||
BN_init(&e);
|
||||
|
||||
if (BN_set_word(r, 2)
|
||||
&& BN_sub(&e, q, r)
|
||||
&& BN_mod_exp_mont(r, k, &e, q, ctx, NULL))
|
||||
res = r;
|
||||
else
|
||||
BN_free(r);
|
||||
BN_free(&e);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Originally written by Bodo Moeller for the OpenSSL project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2010 The OpenSSL Project. All rights reserved.
|
||||
* Copyright (c) 1998-2018 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
|
||||
@@ -214,7 +214,7 @@ struct ec_group_st {
|
||||
int asn1_flag; /* flag to control the asn1 encoding */
|
||||
/*
|
||||
* Kludge: upper bit of ans1_flag is used to denote structure
|
||||
* version. Is set, then last field is present. This is done
|
||||
* version. If set, then last field is present. This is done
|
||||
* for interoperation with FIPS code.
|
||||
*/
|
||||
#define EC_GROUP_ASN1_FLAG_MASK 0x7fffffff
|
||||
@@ -549,7 +549,6 @@ void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
|
||||
void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign,
|
||||
unsigned char *digit, unsigned char in);
|
||||
#endif
|
||||
int ec_precompute_mont_data(EC_GROUP *);
|
||||
|
||||
#ifdef ECP_NISTZ256_ASM
|
||||
/** Returns GFp methods using montgomery multiplication, with x86-64 optimized
|
||||
|
||||
@@ -70,6 +70,10 @@
|
||||
|
||||
const char EC_version[] = "EC" OPENSSL_VERSION_PTEXT;
|
||||
|
||||
/* local function prototypes */
|
||||
|
||||
static int ec_precompute_mont_data(EC_GROUP *group);
|
||||
|
||||
/* functions for EC_GROUP objects */
|
||||
|
||||
EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
|
||||
@@ -318,17 +322,25 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
|
||||
} else
|
||||
BN_zero(&group->cofactor);
|
||||
|
||||
/*
|
||||
* Some groups have an order with
|
||||
* factors of two, which makes the Montgomery setup fail.
|
||||
* |group->mont_data| will be NULL in this case.
|
||||
/*-
|
||||
* Access to the `mont_data` field of an EC_GROUP struct should always be
|
||||
* guarded by an EC_GROUP_VERSION(group) check to avoid OOB accesses, as the
|
||||
* group might come from the FIPS module, which does not define the
|
||||
* `mont_data` field inside the EC_GROUP structure.
|
||||
*/
|
||||
if (BN_is_odd(&group->order)) {
|
||||
return ec_precompute_mont_data(group);
|
||||
if (EC_GROUP_VERSION(group)) {
|
||||
/*-
|
||||
* Some groups have an order with
|
||||
* factors of two, which makes the Montgomery setup fail.
|
||||
* |group->mont_data| will be NULL in this case.
|
||||
*/
|
||||
if (BN_is_odd(&group->order))
|
||||
return ec_precompute_mont_data(group);
|
||||
|
||||
BN_MONT_CTX_free(group->mont_data);
|
||||
group->mont_data = NULL;
|
||||
}
|
||||
|
||||
BN_MONT_CTX_free(group->mont_data);
|
||||
group->mont_data = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1098,18 +1110,23 @@ int EC_GROUP_have_precompute_mult(const EC_GROUP *group)
|
||||
* been performed */
|
||||
}
|
||||
|
||||
/*
|
||||
/*-
|
||||
* ec_precompute_mont_data sets |group->mont_data| from |group->order| and
|
||||
* returns one on success. On error it returns zero.
|
||||
*
|
||||
* Note: this function must be called only after verifying that
|
||||
* EC_GROUP_VERSION(group) returns true.
|
||||
* The reason for this is that access to the `mont_data` field of an EC_GROUP
|
||||
* struct should always be guarded by an EC_GROUP_VERSION(group) check to avoid
|
||||
* OOB accesses, as the group might come from the FIPS module, which does not
|
||||
* define the `mont_data` field inside the EC_GROUP structure.
|
||||
*/
|
||||
static
|
||||
int ec_precompute_mont_data(EC_GROUP *group)
|
||||
{
|
||||
BN_CTX *ctx = BN_CTX_new();
|
||||
int ret = 0;
|
||||
|
||||
if (!EC_GROUP_VERSION(group))
|
||||
goto err;
|
||||
|
||||
if (group->mont_data) {
|
||||
BN_MONT_CTX_free(group->mont_data);
|
||||
group->mont_data = NULL;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved.
|
||||
* Copyright (c) 1998-2018 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,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
|
||||
@@ -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);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* 2000.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
|
||||
* Copyright (c) 1999-2018 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
|
||||
@@ -62,6 +62,7 @@
|
||||
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
|
||||
*/
|
||||
|
||||
#include "cryptlib.h"
|
||||
#include "eng_int.h"
|
||||
|
||||
/*
|
||||
@@ -369,10 +370,10 @@ ENGINE *ENGINE_by_id(const char *id)
|
||||
*/
|
||||
if (strcmp(id, "dynamic")) {
|
||||
# ifdef OPENSSL_SYS_VMS
|
||||
if ((load_dir = getenv("OPENSSL_ENGINES")) == 0)
|
||||
if ((load_dir = ossl_safe_getenv("OPENSSL_ENGINES")) == 0)
|
||||
load_dir = "SSLROOT:[ENGINES]";
|
||||
# else
|
||||
if ((load_dir = getenv("OPENSSL_ENGINES")) == 0)
|
||||
if ((load_dir = ossl_safe_getenv("OPENSSL_ENGINES")) == 0)
|
||||
load_dir = ENGINESDIR;
|
||||
# endif
|
||||
iterator = ENGINE_by_id("dynamic");
|
||||
|
||||
31
crypto/getenv.c
Normal file
31
crypto/getenv.c
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "cryptlib.h"
|
||||
|
||||
char *ossl_safe_getenv(const char *name)
|
||||
{
|
||||
#if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
|
||||
# if __GLIBC_PREREQ(2, 17)
|
||||
# define SECURE_GETENV
|
||||
return secure_getenv(name);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef SECURE_GETENV
|
||||
if (OPENSSL_issetugid())
|
||||
return NULL;
|
||||
return getenv(name);
|
||||
#endif
|
||||
}
|
||||
@@ -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 0x1000210fL
|
||||
# define OPENSSL_VERSION_NUMBER 0x1000211fL
|
||||
# ifdef OPENSSL_FIPS
|
||||
# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2p-fips 14 Aug 2018"
|
||||
# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2q-fips 20 Nov 2018"
|
||||
# else
|
||||
# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2p 14 Aug 2018"
|
||||
# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2q 20 Nov 2018"
|
||||
# endif
|
||||
# define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
* Copyright (c) 1999-2018 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
|
||||
@@ -70,7 +70,8 @@ PKCS12 *PKCS12_init(int mode)
|
||||
PKCS12err(PKCS12_F_PKCS12_INIT, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
ASN1_INTEGER_set(pkcs12->version, 3);
|
||||
if (!ASN1_INTEGER_set(pkcs12->version, 3))
|
||||
goto err;
|
||||
pkcs12->authsafes->type = OBJ_nid2obj(mode);
|
||||
switch (mode) {
|
||||
case NID_pkcs7_data:
|
||||
|
||||
@@ -185,7 +185,6 @@ int PKCS7_set_type(PKCS7 *p7, int type)
|
||||
if ((p7->d.signed_and_enveloped = PKCS7_SIGN_ENVELOPE_new())
|
||||
== NULL)
|
||||
goto err;
|
||||
ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1);
|
||||
if (!ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1))
|
||||
goto err;
|
||||
p7->d.signed_and_enveloped->enc_data->content_type
|
||||
|
||||
@@ -157,10 +157,11 @@ rand_win.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
|
||||
rand_win.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
|
||||
rand_win.o: ../../include/openssl/symhacks.h ../cryptlib.h rand_lcl.h
|
||||
rand_win.o: rand_win.c
|
||||
randfile.o: ../../e_os.h ../../include/openssl/buffer.h
|
||||
randfile.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
|
||||
randfile.o: ../../include/openssl/opensslconf.h
|
||||
randfile.o: ../../e_os.h ../../include/openssl/bio.h
|
||||
randfile.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
|
||||
randfile.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
|
||||
randfile.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
|
||||
randfile.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
randfile.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
|
||||
randfile.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
|
||||
randfile.o: randfile.c
|
||||
randfile.o: ../cryptlib.h randfile.c
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
|
||||
* Copyright (c) 1998-2018 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
|
||||
@@ -345,7 +345,6 @@ int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock)
|
||||
static volatile int stirred_pool = 0;
|
||||
int i, j, k;
|
||||
size_t num_ceil, st_idx, st_num;
|
||||
int ok;
|
||||
long md_c[2];
|
||||
unsigned char local_md[MD_DIGEST_LENGTH];
|
||||
EVP_MD_CTX m;
|
||||
@@ -400,14 +399,13 @@ int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock)
|
||||
|
||||
if (!initialized) {
|
||||
RAND_poll();
|
||||
initialized = 1;
|
||||
initialized = (entropy >= ENTROPY_NEEDED);
|
||||
}
|
||||
|
||||
if (!stirred_pool)
|
||||
do_stir_pool = 1;
|
||||
|
||||
ok = (entropy >= ENTROPY_NEEDED);
|
||||
if (!ok) {
|
||||
if (!initialized) {
|
||||
/*
|
||||
* If the PRNG state is not yet unpredictable, then seeing the PRNG
|
||||
* output may help attackers to determine the new state; thus we have
|
||||
@@ -446,7 +444,7 @@ int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock)
|
||||
ssleay_rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0);
|
||||
n -= MD_DIGEST_LENGTH;
|
||||
}
|
||||
if (ok)
|
||||
if (initialized)
|
||||
stirred_pool = 1;
|
||||
}
|
||||
|
||||
@@ -539,7 +537,7 @@ int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock)
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
|
||||
|
||||
EVP_MD_CTX_cleanup(&m);
|
||||
if (ok)
|
||||
if (initialized)
|
||||
return (1);
|
||||
else if (pseudo)
|
||||
return 0;
|
||||
@@ -555,6 +553,18 @@ int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns ssleay_rand_bytes(), enforcing a reseeding from the
|
||||
* system entropy sources using RAND_poll() before generating
|
||||
`* the random bytes.
|
||||
*/
|
||||
|
||||
int ssleay_rand_bytes_from_system(unsigned char *buf, int num)
|
||||
{
|
||||
initialized = 0;
|
||||
return ssleay_rand_bytes(buf, num, 0, 0);
|
||||
}
|
||||
|
||||
static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num)
|
||||
{
|
||||
return ssleay_rand_bytes(buf, num, 0, 1);
|
||||
@@ -600,10 +610,10 @@ static int ssleay_rand_status(void)
|
||||
|
||||
if (!initialized) {
|
||||
RAND_poll();
|
||||
initialized = 1;
|
||||
initialized = (entropy >= ENTROPY_NEEDED);
|
||||
}
|
||||
|
||||
ret = entropy >= ENTROPY_NEEDED;
|
||||
ret = initialized;
|
||||
|
||||
if (!do_not_lock) {
|
||||
/* before unlocking, we must clear 'crypto_lock_rand' */
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
|
||||
* Copyright (c) 1998-2018 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
|
||||
@@ -154,5 +154,5 @@
|
||||
# endif
|
||||
|
||||
int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock);
|
||||
|
||||
int ssleay_rand_bytes_from_system(unsigned char *buf, int num);
|
||||
#endif
|
||||
|
||||
@@ -185,11 +185,29 @@ int RAND_status(void)
|
||||
|
||||
/*
|
||||
* Entropy gatherer: use standard OpenSSL PRNG to seed (this will gather
|
||||
* entropy internally through RAND_poll().
|
||||
* entropy internally through RAND_poll()).
|
||||
*/
|
||||
|
||||
static size_t drbg_get_entropy(DRBG_CTX *ctx, unsigned char **pout,
|
||||
int entropy, size_t min_len, size_t max_len)
|
||||
{
|
||||
/* Round up request to multiple of block size */
|
||||
min_len = ((min_len + 19) / 20) * 20;
|
||||
*pout = OPENSSL_malloc(min_len);
|
||||
if (!*pout)
|
||||
return 0;
|
||||
|
||||
/* Enforces a reseed of the SSLEAY PRNG before generating random bytes */
|
||||
if (ssleay_rand_bytes_from_system(*pout, min_len) <= 0) {
|
||||
OPENSSL_free(*pout);
|
||||
*pout = NULL;
|
||||
return 0;
|
||||
}
|
||||
return min_len;
|
||||
}
|
||||
|
||||
static size_t drbg_get_nonce(DRBG_CTX *ctx, unsigned char **pout,
|
||||
int entropy, size_t min_len, size_t max_len)
|
||||
{
|
||||
/* Round up request to multiple of block size */
|
||||
min_len = ((min_len + 19) / 20) * 20;
|
||||
@@ -281,7 +299,7 @@ int RAND_init_fips(void)
|
||||
|
||||
FIPS_drbg_set_callbacks(dctx,
|
||||
drbg_get_entropy, drbg_free_entropy, 20,
|
||||
drbg_get_entropy, drbg_free_entropy);
|
||||
drbg_get_nonce, drbg_free_entropy);
|
||||
FIPS_drbg_set_rand_callbacks(dctx, drbg_get_adin, 0,
|
||||
drbg_rand_seed, drbg_rand_add);
|
||||
/* Personalisation string: a string followed by date time vector */
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cryptlib.h"
|
||||
#include "e_os.h"
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/rand.h>
|
||||
@@ -327,14 +328,12 @@ const char *RAND_file_name(char *buf, size_t size)
|
||||
struct stat sb;
|
||||
#endif
|
||||
|
||||
if (OPENSSL_issetugid() == 0)
|
||||
s = getenv("RANDFILE");
|
||||
s = ossl_safe_getenv("RANDFILE");
|
||||
if (s != NULL && *s && strlen(s) + 1 < size) {
|
||||
if (BUF_strlcpy(buf, s, size) >= size)
|
||||
return NULL;
|
||||
} else {
|
||||
if (OPENSSL_issetugid() == 0)
|
||||
s = getenv("HOME");
|
||||
s = ossl_safe_getenv("HOME");
|
||||
#ifdef DEFAULT_HOME
|
||||
if (s == NULL) {
|
||||
s = DEFAULT_HOME;
|
||||
|
||||
@@ -224,8 +224,8 @@ static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
|
||||
}
|
||||
|
||||
if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
|
||||
if (!BN_MONT_CTX_set_locked
|
||||
(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
|
||||
if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA,
|
||||
rsa->n, ctx))
|
||||
goto err;
|
||||
|
||||
if (!rsa->meth->bn_mod_exp(ret, f, rsa->e, rsa->n, ctx,
|
||||
@@ -432,8 +432,8 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
|
||||
d = rsa->d;
|
||||
|
||||
if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
|
||||
if (!BN_MONT_CTX_set_locked
|
||||
(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
|
||||
if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA,
|
||||
rsa->n, ctx))
|
||||
goto err;
|
||||
|
||||
if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx,
|
||||
@@ -554,8 +554,8 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
|
||||
d = rsa->d;
|
||||
|
||||
if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
|
||||
if (!BN_MONT_CTX_set_locked
|
||||
(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
|
||||
if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA,
|
||||
rsa->n, ctx))
|
||||
goto err;
|
||||
if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx,
|
||||
rsa->_method_mod_n))
|
||||
@@ -660,8 +660,8 @@ static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
|
||||
}
|
||||
|
||||
if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
|
||||
if (!BN_MONT_CTX_set_locked
|
||||
(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
|
||||
if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA,
|
||||
rsa->n, ctx))
|
||||
goto err;
|
||||
|
||||
if (!rsa->meth->bn_mod_exp(ret, f, rsa->e, rsa->n, ctx,
|
||||
@@ -708,7 +708,7 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
|
||||
BIGNUM *r1, *m1, *vrfy;
|
||||
BIGNUM local_dmp1, local_dmq1, local_c, local_r1;
|
||||
BIGNUM *dmp1, *dmq1, *c, *pr1;
|
||||
int ret = 0;
|
||||
int ret = 0, smooth = 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
r1 = BN_CTX_get(ctx);
|
||||
@@ -737,20 +737,64 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
|
||||
}
|
||||
|
||||
if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) {
|
||||
if (!BN_MONT_CTX_set_locked
|
||||
(&rsa->_method_mod_p, CRYPTO_LOCK_RSA, p, ctx))
|
||||
if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_p, CRYPTO_LOCK_RSA,
|
||||
p, ctx))
|
||||
goto err;
|
||||
if (!BN_MONT_CTX_set_locked
|
||||
(&rsa->_method_mod_q, CRYPTO_LOCK_RSA, q, ctx))
|
||||
if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_q, CRYPTO_LOCK_RSA,
|
||||
q, ctx))
|
||||
goto err;
|
||||
|
||||
smooth = (rsa->meth->bn_mod_exp == BN_mod_exp_mont)
|
||||
&& (BN_num_bits(q) == BN_num_bits(p));
|
||||
}
|
||||
}
|
||||
|
||||
if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
|
||||
if (!BN_MONT_CTX_set_locked
|
||||
(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
|
||||
if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA,
|
||||
rsa->n, ctx))
|
||||
goto err;
|
||||
|
||||
if (smooth) {
|
||||
/*
|
||||
* Conversion from Montgomery domain, a.k.a. Montgomery reduction,
|
||||
* accepts values in [0-m*2^w) range. w is m's bit width rounded up
|
||||
* to limb width. So that at the very least if |I| is fully reduced,
|
||||
* i.e. less than p*q, we can count on from-to round to perform
|
||||
* below modulo operations on |I|. Unlike BN_mod it's constant time.
|
||||
*/
|
||||
if (/* m1 = I moq q */
|
||||
!bn_from_mont_fixed_top(m1, I, rsa->_method_mod_q, ctx)
|
||||
|| !bn_to_mont_fixed_top(m1, m1, rsa->_method_mod_q, ctx)
|
||||
/* m1 = m1^dmq1 mod q */
|
||||
|| !BN_mod_exp_mont_consttime(m1, m1, rsa->dmq1, rsa->q, ctx,
|
||||
rsa->_method_mod_q)
|
||||
/* r1 = I mod p */
|
||||
|| !bn_from_mont_fixed_top(r1, I, rsa->_method_mod_p, ctx)
|
||||
|| !bn_to_mont_fixed_top(r1, r1, rsa->_method_mod_p, ctx)
|
||||
/* r1 = r1^dmp1 mod p */
|
||||
|| !BN_mod_exp_mont_consttime(r1, r1, rsa->dmp1, rsa->p, ctx,
|
||||
rsa->_method_mod_p)
|
||||
/* r1 = (r1 - m1) mod p */
|
||||
/*
|
||||
* bn_mod_sub_fixed_top is not regular modular subtraction,
|
||||
* it can tolerate subtrahend to be larger than modulus, but
|
||||
* not bit-wise wider. This makes up for uncommon q>p case,
|
||||
* when |m1| can be larger than |rsa->p|.
|
||||
*/
|
||||
|| !bn_mod_sub_fixed_top(r1, r1, m1, rsa->p)
|
||||
|
||||
/* r1 = r1 * iqmp mod p */
|
||||
|| !bn_to_mont_fixed_top(r1, r1, rsa->_method_mod_p, ctx)
|
||||
|| !bn_mul_mont_fixed_top(r1, r1, rsa->iqmp, rsa->_method_mod_p,
|
||||
ctx)
|
||||
/* r0 = r1 * q + m1 */
|
||||
|| !bn_mul_fixed_top(r0, r1, rsa->q, ctx)
|
||||
|| !bn_mod_add_fixed_top(r0, r0, m1, rsa->n))
|
||||
goto err;
|
||||
|
||||
goto tail;
|
||||
}
|
||||
|
||||
/* compute I mod q */
|
||||
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) {
|
||||
c = &local_c;
|
||||
@@ -828,10 +872,18 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
|
||||
if (!BN_add(r0, r1, m1))
|
||||
goto err;
|
||||
|
||||
tail:
|
||||
if (rsa->e && rsa->n) {
|
||||
if (!rsa->meth->bn_mod_exp(vrfy, r0, rsa->e, rsa->n, ctx,
|
||||
rsa->_method_mod_n))
|
||||
goto err;
|
||||
if (rsa->meth->bn_mod_exp == BN_mod_exp_mont) {
|
||||
if (!BN_mod_exp_mont(vrfy, r0, rsa->e, rsa->n, ctx,
|
||||
rsa->_method_mod_n))
|
||||
goto err;
|
||||
} else {
|
||||
bn_correct_top(r0);
|
||||
if (!rsa->meth->bn_mod_exp(vrfy, r0, rsa->e, rsa->n, ctx,
|
||||
rsa->_method_mod_n))
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
* If 'I' was greater than (or equal to) rsa->n, the operation will
|
||||
* be equivalent to using 'I mod n'. However, the result of the
|
||||
@@ -840,6 +892,11 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
|
||||
*/
|
||||
if (!BN_sub(vrfy, vrfy, I))
|
||||
goto err;
|
||||
if (BN_is_zero(vrfy)) {
|
||||
bn_correct_top(r0);
|
||||
ret = 1;
|
||||
goto err; /* not actually error */
|
||||
}
|
||||
if (!BN_mod(vrfy, vrfy, rsa->n, ctx))
|
||||
goto err;
|
||||
if (BN_is_negative(vrfy))
|
||||
@@ -865,6 +922,15 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* It's unfortunate that we have to bn_correct_top(r0). What hopefully
|
||||
* saves the day is that correction is highly unlike, and private key
|
||||
* operations are customarily performed on blinded message. Which means
|
||||
* that attacker won't observe correlation with chosen plaintext.
|
||||
* Secondly, remaining code would still handle it in same computational
|
||||
* time and even conceal memory access pattern around corrected top.
|
||||
*/
|
||||
bn_correct_top(r0);
|
||||
ret = 1;
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
@@ -509,6 +509,24 @@ static int open_console(UI *ui)
|
||||
is_a_tty = 0;
|
||||
else
|
||||
# endif
|
||||
# ifdef ENXIO
|
||||
/*
|
||||
* Solaris can return ENXIO.
|
||||
* This should be ok
|
||||
*/
|
||||
if (errno == ENXIO)
|
||||
is_a_tty = 0;
|
||||
else
|
||||
# endif
|
||||
# ifdef EIO
|
||||
/*
|
||||
* Linux can return EIO.
|
||||
* This should be ok
|
||||
*/
|
||||
if (errno == EIO)
|
||||
is_a_tty = 0;
|
||||
else
|
||||
# endif
|
||||
# ifdef ENODEV
|
||||
/*
|
||||
* MacOS X returns ENODEV (Operation not supported by device),
|
||||
|
||||
@@ -128,7 +128,7 @@ static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
|
||||
switch (cmd) {
|
||||
case X509_L_ADD_DIR:
|
||||
if (argl == X509_FILETYPE_DEFAULT) {
|
||||
dir = (char *)getenv(X509_get_default_cert_dir_env());
|
||||
dir = (char *)ossl_safe_getenv(X509_get_default_cert_dir_env());
|
||||
if (dir)
|
||||
ret = add_cert_dir(ld, dir, X509_FILETYPE_PEM);
|
||||
else
|
||||
|
||||
@@ -97,7 +97,8 @@ static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp,
|
||||
switch (cmd) {
|
||||
case X509_L_FILE_LOAD:
|
||||
if (argl == X509_FILETYPE_DEFAULT) {
|
||||
file = getenv(X509_get_default_cert_file_env());
|
||||
file = ossl_safe_getenv(X509_get_default_cert_file_env());
|
||||
|
||||
if (file)
|
||||
ok = (X509_load_cert_crl_file(ctx, file,
|
||||
X509_FILETYPE_PEM) != 0);
|
||||
|
||||
@@ -621,7 +621,7 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
|
||||
* A hack to keep people who don't want to modify their software
|
||||
* happy
|
||||
*/
|
||||
if (getenv("OPENSSL_ALLOW_PROXY_CERTS"))
|
||||
if (ossl_safe_getenv("OPENSSL_ALLOW_PROXY_CERTS"))
|
||||
allow_proxy_certs = 1;
|
||||
purpose = ctx->param->purpose;
|
||||
}
|
||||
@@ -694,10 +694,9 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
/* Check pathlen if not self issued */
|
||||
if ((i > 1) && !(x->ex_flags & EXFLAG_SI)
|
||||
&& (x->ex_pathlen != -1)
|
||||
&& (plen > (x->ex_pathlen + proxy_path_length + 1))) {
|
||||
/* Check pathlen */
|
||||
if ((i > 1) && (x->ex_pathlen != -1)
|
||||
&& (plen > (x->ex_pathlen + proxy_path_length))) {
|
||||
ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
|
||||
ctx->error_depth = i;
|
||||
ctx->current_cert = x;
|
||||
@@ -705,8 +704,8 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
|
||||
if (!ok)
|
||||
goto end;
|
||||
}
|
||||
/* Increment path length if not self issued */
|
||||
if (!(x->ex_flags & EXFLAG_SI))
|
||||
/* Increment path length if not a self issued intermediate CA */
|
||||
if (i > 0 && (x->ex_flags & EXFLAG_SI) == 0)
|
||||
plen++;
|
||||
/*
|
||||
* If this certificate is a proxy certificate, the next certificate
|
||||
|
||||
@@ -396,12 +396,8 @@ static void x509v3_cache_extensions(X509 *x)
|
||||
ASN1_BIT_STRING *ns;
|
||||
EXTENDED_KEY_USAGE *extusage;
|
||||
X509_EXTENSION *ex;
|
||||
|
||||
int i;
|
||||
|
||||
if (x->ex_flags & EXFLAG_SET)
|
||||
return;
|
||||
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_X509);
|
||||
if (x->ex_flags & EXFLAG_SET) {
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_X509);
|
||||
|
||||
Reference in New Issue
Block a user