Update pre9

This commit is contained in:
2018-07-19 21:47:35 +09:00
parent 1914ae9055
commit 46f6b5e2fe
84 changed files with 2388 additions and 962 deletions
+1
View File
@@ -234,6 +234,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
wnum.neg = 0;
wnum.d = &(snum->d[loop]);
wnum.top = div_n;
wnum.flags = BN_FLG_STATIC_DATA;
/*
* only needed when BN_ucmp messes up the values between top and max
*/
+26 -21
View File
@@ -361,17 +361,17 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
ret = 1;
goto err;
}
if (!BN_to_montgomery(val[0], aa, mont, ctx))
if (!bn_to_mont_fixed_top(val[0], aa, mont, ctx))
goto err; /* 1 */
window = BN_window_bits_for_exponent_size(bits);
if (window > 1) {
if (!BN_mod_mul_montgomery(d, val[0], val[0], mont, ctx))
if (!bn_mul_mont_fixed_top(d, val[0], val[0], mont, ctx))
goto err; /* 2 */
j = 1 << (window - 1);
for (i = 1; i < j; i++) {
if (((val[i] = BN_CTX_get(ctx)) == NULL) ||
!BN_mod_mul_montgomery(val[i], val[i - 1], d, mont, ctx))
!bn_mul_mont_fixed_top(val[i], val[i - 1], d, mont, ctx))
goto err;
}
}
@@ -393,19 +393,15 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
for (i = 1; i < j; i++)
r->d[i] = (~m->d[i]) & BN_MASK2;
r->top = j;
/*
* Upper words will be zero if the corresponding words of 'm' were
* 0xfff[...], so decrement r->top accordingly.
*/
bn_correct_top(r);
r->flags |= BN_FLG_FIXED_TOP;
} else
#endif
if (!BN_to_montgomery(r, BN_value_one(), mont, ctx))
if (!bn_to_mont_fixed_top(r, BN_value_one(), mont, ctx))
goto err;
for (;;) {
if (BN_is_bit_set(p, wstart) == 0) {
if (!start) {
if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
if (!bn_mul_mont_fixed_top(r, r, r, mont, ctx))
goto err;
}
if (wstart == 0)
@@ -436,12 +432,12 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
/* add the 'bytes above' */
if (!start)
for (i = 0; i < j; i++) {
if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
if (!bn_mul_mont_fixed_top(r, r, r, mont, ctx))
goto err;
}
/* wvalue will be an odd number < 2^window */
if (!BN_mod_mul_montgomery(r, r, val[wvalue >> 1], mont, ctx))
if (!bn_mul_mont_fixed_top(r, r, val[wvalue >> 1], mont, ctx))
goto err;
/* move the 'window' down further */
@@ -451,6 +447,11 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
if (wstart < 0)
break;
}
/*
* Done with zero-padded intermediate BIGNUMs. Final BN_from_montgomery
* removes padding [if any] and makes return value suitable for public
* API consumer.
*/
#if defined(SPARC_T4_MONT)
if (OPENSSL_sparcv9cap_P[0] & (SPARCV9_VIS3 | SPARCV9_PREFER_FPU)) {
j = mont->N.top; /* borrow j */
@@ -575,7 +576,7 @@ static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top,
}
b->top = top;
bn_correct_top(b);
b->flags |= BN_FLG_FIXED_TOP;
return 1;
}
@@ -747,16 +748,16 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
tmp.top = top;
} else
#endif
if (!BN_to_montgomery(&tmp, BN_value_one(), mont, ctx))
if (!bn_to_mont_fixed_top(&tmp, BN_value_one(), mont, ctx))
goto err;
/* prepare a^1 in Montgomery domain */
if (a->neg || BN_ucmp(a, m) >= 0) {
if (!BN_nnmod(&am, a, m, ctx))
goto err;
if (!BN_to_montgomery(&am, &am, mont, ctx))
if (!bn_to_mont_fixed_top(&am, &am, mont, ctx))
goto err;
} else if (!BN_to_montgomery(&am, a, mont, ctx))
} else if (!bn_to_mont_fixed_top(&am, a, mont, ctx))
goto err;
#if defined(SPARC_T4_MONT)
@@ -1034,14 +1035,14 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
* performance advantage of sqr over mul).
*/
if (window > 1) {
if (!BN_mod_mul_montgomery(&tmp, &am, &am, mont, ctx))
if (!bn_mul_mont_fixed_top(&tmp, &am, &am, mont, ctx))
goto err;
if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 2,
window))
goto err;
for (i = 3; i < numPowers; i++) {
/* Calculate a^i = a^(i-1) * a */
if (!BN_mod_mul_montgomery(&tmp, &am, &tmp, mont, ctx))
if (!bn_mul_mont_fixed_top(&tmp, &am, &tmp, mont, ctx))
goto err;
if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, i,
window))
@@ -1072,7 +1073,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
/* Square the result window-size times */
for (i = 0; i < window; i++)
if (!BN_mod_mul_montgomery(&tmp, &tmp, &tmp, mont, ctx))
if (!bn_mul_mont_fixed_top(&tmp, &tmp, &tmp, mont, ctx))
goto err;
/*
@@ -1095,12 +1096,16 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
goto err;
/* Multiply the result into the intermediate result */
if (!BN_mod_mul_montgomery(&tmp, &tmp, &am, mont, ctx))
if (!bn_mul_mont_fixed_top(&tmp, &tmp, &am, mont, ctx))
goto err;
}
}
/* Convert the final result from montgomery to standard format */
/*
* Done with zero-padded intermediate BIGNUMs. Final BN_from_montgomery
* removes padding [if any] and makes return value suitable for public
* API consumer.
*/
#if defined(SPARC_T4_MONT)
if (OPENSSL_sparcv9cap_P[0] & (SPARCV9_VIS3 | SPARCV9_PREFER_FPU)) {
am.d[0] = 1; /* borrow am */
+17 -4
View File
@@ -141,7 +141,16 @@
*/
# ifdef BN_DEBUG
# include <assert.h>
/*
* The new BN_FLG_FIXED_TOP flag marks vectors that were not treated with
* bn_correct_top, in other words such vectors are permitted to have zeros
* in most significant limbs. Such vectors are used internally to achieve
* execution time invariance for critical operations with private keys.
* It's BN_DEBUG-only flag, because user application is not supposed to
* observe it anyway. Moreover, optimizing compiler would actually remove
* all operations manipulating the bit in question in non-BN_DEBUG build.
*/
# define BN_FLG_FIXED_TOP 0x10000
# ifdef BN_DEBUG_RAND
# define bn_pollute(a) \
do { \
@@ -165,8 +174,10 @@
do { \
const BIGNUM *_bnum2 = (a); \
if (_bnum2 != NULL) { \
assert(((_bnum2->top == 0) && !_bnum2->neg) || \
(_bnum2->top && (_bnum2->d[_bnum2->top - 1] != 0))); \
int _top = _bnum2->top; \
(void)ossl_assert((_top == 0 && !_bnum2->neg) || \
(_top && ((_bnum2->flags & BN_FLG_FIXED_TOP) \
|| _bnum2->d[_top - 1] != 0))); \
bn_pollute(_bnum2); \
} \
} while(0)
@@ -185,6 +196,7 @@
# else /* !BN_DEBUG */
# define BN_FLG_FIXED_TOP 0
# define bn_pollute(a)
# define bn_check_top(a)
# define bn_fix_top(a) bn_correct_top(a)
@@ -216,7 +228,8 @@ struct bignum_st {
/* Used for montgomery multiplication */
struct bn_mont_ctx_st {
int ri; /* number of bits in R */
BIGNUM RR; /* used to convert to montgomery form */
BIGNUM RR; /* used to convert to montgomery form,
possibly zero-padded */
BIGNUM N; /* The modulus */
BIGNUM Ni; /* R*(1/R mod N) - N*Ni = 1 (Ni is only
* stored for bignum algorithm) */
+28 -20
View File
@@ -12,6 +12,7 @@
#include "internal/cryptlib.h"
#include "bn_lcl.h"
#include <openssl/opensslconf.h>
#include "internal/constant_time_locl.h"
/* This stuff appears to be completely unused, so is deprecated */
#if OPENSSL_API_COMPAT < 0x00908000L
@@ -209,8 +210,6 @@ static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
{
BN_ULONG *a = NULL;
bn_check_top(b);
if (words > (INT_MAX / (4 * BN_BITS2))) {
BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_BIGNUM_TOO_LONG);
return NULL;
@@ -245,8 +244,6 @@ static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
BIGNUM *bn_expand2(BIGNUM *b, int words)
{
bn_check_top(b);
if (words > b->dmax) {
BN_ULONG *a = bn_expand_internal(b, words);
if (!a)
@@ -259,7 +256,6 @@ BIGNUM *bn_expand2(BIGNUM *b, int words)
b->dmax = words;
}
bn_check_top(b);
return b;
}
@@ -294,15 +290,17 @@ BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
if (b->top > 0)
memcpy(a->d, b->d, sizeof(b->d[0]) * b->top);
a->top = b->top;
a->neg = b->neg;
a->top = b->top;
a->flags |= b->flags & BN_FLG_FIXED_TOP;
bn_check_top(a);
return a;
}
#define FLAGS_DATA(flags) ((flags) & (BN_FLG_STATIC_DATA \
| BN_FLG_CONSTTIME \
| BN_FLG_SECURE))
| BN_FLG_SECURE \
| BN_FLG_FIXED_TOP))
#define FLAGS_STRUCT(flags) ((flags) & (BN_FLG_MALLOCED))
void BN_swap(BIGNUM *a, BIGNUM *b)
@@ -343,8 +341,9 @@ void BN_clear(BIGNUM *a)
bn_check_top(a);
if (a->d != NULL)
OPENSSL_cleanse(a->d, sizeof(*a->d) * a->dmax);
a->top = 0;
a->neg = 0;
a->top = 0;
a->flags &= ~BN_FLG_FIXED_TOP;
}
BN_ULONG BN_get_word(const BIGNUM *a)
@@ -365,6 +364,7 @@ int BN_set_word(BIGNUM *a, BN_ULONG w)
a->neg = 0;
a->d[0] = w;
a->top = (w ? 1 : 0);
a->flags &= ~BN_FLG_FIXED_TOP;
bn_check_top(a);
return 1;
}
@@ -417,24 +417,29 @@ BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
/* ignore negative */
static int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
{
int i;
int n;
size_t i, inc, lasti, j;
BN_ULONG l;
bn_check_top(a);
i = BN_num_bytes(a);
n = BN_num_bytes(a);
if (tolen == -1)
tolen = i;
else if (tolen < i)
tolen = n;
else if (tolen < n)
return -1;
/* Add leading zeroes if necessary */
if (tolen > i) {
memset(to, 0, tolen - i);
to += tolen - i;
if (n == 0) {
OPENSSL_cleanse(to, tolen);
return tolen;
}
while (i--) {
lasti = n - 1;
for (i = 0, inc = 1, j = tolen; j > 0;) {
l = a->d[i / BN_BYTES];
*(to++) = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff;
to[--j] = (unsigned char)(l >> (8 * (i % BN_BYTES)) & (0 - inc));
inc = (i - lasti) >> (8 * sizeof(i) - 1);
i += inc; /* stay on top limb */
}
return tolen;
}
@@ -601,6 +606,7 @@ int BN_set_bit(BIGNUM *a, int n)
for (k = a->top; k < i + 1; k++)
a->d[k] = 0;
a->top = i + 1;
a->flags &= ~BN_FLG_FIXED_TOP;
}
a->d[i] |= (((BN_ULONG)1) << j);
@@ -833,8 +839,9 @@ int BN_security_bits(int L, int N)
void BN_zero_ex(BIGNUM *a)
{
a->top = 0;
a->neg = 0;
a->top = 0;
a->flags &= ~BN_FLG_FIXED_TOP;
}
int BN_abs_is_word(const BIGNUM *a, const BN_ULONG w)
@@ -958,5 +965,6 @@ void bn_correct_top(BIGNUM *a)
}
if (a->top == 0)
a->neg = 0;
a->flags &= ~BN_FLG_FIXED_TOP;
bn_pollute(a);
}
+60 -6
View File
@@ -35,16 +35,70 @@ int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
/*
* BN_mod_add variant that may be used if both a and b are non-negative and
* less than m
* less than m. The original algorithm was
*
* if (!BN_uadd(r, a, b))
* return 0;
* if (BN_ucmp(r, m) >= 0)
* return BN_usub(r, r, m);
*
* which is replaced with addition, subtracting modulus, and conditional
* move depending on whether or not subtraction borrowed.
*/
int bn_mod_add_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
const BIGNUM *m)
{
size_t i, ai, bi, mtop = m->top;
BN_ULONG storage[1024 / BN_BITS2];
BN_ULONG carry, temp, mask, *rp, *tp = storage;
const BN_ULONG *ap, *bp;
if (bn_wexpand(r, mtop) == NULL)
return 0;
if (mtop > sizeof(storage) / sizeof(storage[0])
&& (tp = OPENSSL_malloc(mtop * sizeof(BN_ULONG))) == NULL)
return 0;
ap = a->d != NULL ? a->d : tp;
bp = b->d != NULL ? b->d : tp;
for (i = 0, ai = 0, bi = 0, carry = 0; i < mtop;) {
mask = (BN_ULONG)0 - ((i - a->top) >> (8 * sizeof(i) - 1));
temp = ((ap[ai] & mask) + carry) & BN_MASK2;
carry = (temp < carry);
mask = (BN_ULONG)0 - ((i - b->top) >> (8 * sizeof(i) - 1));
tp[i] = ((bp[bi] & mask) + temp) & BN_MASK2;
carry += (tp[i] < temp);
i++;
ai += (i - a->dmax) >> (8 * sizeof(i) - 1);
bi += (i - b->dmax) >> (8 * sizeof(i) - 1);
}
rp = r->d;
carry -= bn_sub_words(rp, tp, m->d, mtop);
for (i = 0; i < mtop; i++) {
rp[i] = (carry & tp[i]) | (~carry & rp[i]);
((volatile BN_ULONG *)tp)[i] = 0;
}
r->top = mtop;
if (tp != storage)
OPENSSL_free(tp);
return 1;
}
int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
const BIGNUM *m)
{
if (!BN_uadd(r, a, b))
return 0;
if (BN_ucmp(r, m) >= 0)
return BN_usub(r, r, m);
return 1;
int ret = bn_mod_add_fixed_top(r, a, b, m);
if (ret)
bn_correct_top(r);
return ret;
}
int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
+43 -20
View File
@@ -20,29 +20,43 @@
#define MONT_WORD /* use the faster word-based algorithm */
#ifdef MONT_WORD
static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont);
static int bn_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont);
#endif
int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
BN_MONT_CTX *mont, BN_CTX *ctx)
{
int ret = bn_mul_mont_fixed_top(r, a, b, mont, ctx);
bn_correct_top(r);
bn_check_top(r);
return ret;
}
int bn_mul_mont_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
BN_MONT_CTX *mont, BN_CTX *ctx)
{
BIGNUM *tmp;
int ret = 0;
#if defined(OPENSSL_BN_ASM_MONT) && defined(MONT_WORD)
int num = mont->N.top;
#if defined(OPENSSL_BN_ASM_MONT) && defined(MONT_WORD)
if (num > 1 && a->top == num && b->top == num) {
if (bn_wexpand(r, num) == NULL)
return 0;
if (bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) {
r->neg = a->neg ^ b->neg;
r->top = num;
bn_correct_top(r);
r->flags |= BN_FLG_FIXED_TOP;
return 1;
}
}
#endif
if ((a->top + b->top) > 2 * num)
return 0;
BN_CTX_start(ctx);
tmp = BN_CTX_get(ctx);
if (tmp == NULL)
@@ -58,13 +72,12 @@ int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
}
/* reduce from aRR to aR */
#ifdef MONT_WORD
if (!BN_from_montgomery_word(r, tmp, mont))
if (!bn_from_montgomery_word(r, tmp, mont))
goto err;
#else
if (!BN_from_montgomery(r, tmp, mont, ctx))
goto err;
#endif
bn_check_top(r);
ret = 1;
err:
BN_CTX_end(ctx);
@@ -72,7 +85,7 @@ int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
}
#ifdef MONT_WORD
static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
static int bn_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
{
BIGNUM *n;
BN_ULONG *ap, *np, *rp, n0, v, carry;
@@ -95,12 +108,11 @@ static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
/* clear the top words of T */
i = max - r->top;
if (i < 0)
return 0;
if (i)
memset(&rp[r->top], 0, sizeof(*rp) * i);
r->top = max;
r->flags |= BN_FLG_FIXED_TOP;
n0 = mont->n0[0];
/*
@@ -119,6 +131,7 @@ static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
if (bn_wexpand(ret, nl) == NULL)
return 0;
ret->top = nl;
ret->flags |= BN_FLG_FIXED_TOP;
ret->neg = r->neg;
rp = ret->d;
@@ -129,20 +142,16 @@ static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
*/
ap = &(r->d[nl]);
carry -= bn_sub_words(rp, ap, np, nl);
/*
* |v| is one if |ap| - |np| underflowed or zero if it did not. Note |v|
* cannot be -1. That would imply the subtraction did not fit in |nl| words,
* and we know at most one subtraction is needed.
* |carry| is -1 if |ap| - |np| underflowed or zero if it did not. Note
* |carry| cannot be 1. That would imply the subtraction did not fit in
* |nl| words, and we know at most one subtraction is needed.
*/
v = bn_sub_words(rp, ap, np, nl) - carry;
v = 0 - v;
for (i = 0; i < nl; i++) {
rp[i] = (v & ap[i]) | (~v & rp[i]);
rp[i] = (carry & ap[i]) | (~carry & rp[i]);
ap[i] = 0;
}
bn_correct_top(r);
bn_correct_top(ret);
bn_check_top(ret);
return 1;
}
@@ -156,8 +165,11 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
BIGNUM *t;
BN_CTX_start(ctx);
if ((t = BN_CTX_get(ctx)) && BN_copy(t, a))
retn = BN_from_montgomery_word(ret, t, mont);
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 */
BIGNUM *t1, *t2;
@@ -195,6 +207,12 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
return retn;
}
int bn_to_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont,
BN_CTX *ctx)
{
return bn_mul_mont_fixed_top(r, a, &(mont->RR), mont, ctx);
}
BN_MONT_CTX *BN_MONT_CTX_new(void)
{
BN_MONT_CTX *ret;
@@ -232,7 +250,7 @@ void BN_MONT_CTX_free(BN_MONT_CTX *mont)
int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
{
int ret = 0;
int i, ret = 0;
BIGNUM *Ri, *R;
if (BN_is_zero(mod))
@@ -367,6 +385,11 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
if (!BN_mod(&(mont->RR), &(mont->RR), &(mont->N), ctx))
goto err;
for (i = mont->RR.top, ret = mont->N.top; i < ret; i++)
mont->RR.d[i] = 0;
mont->RR.top = ret;
mont->RR.flags |= BN_FLG_FIXED_TOP;
ret = 1;
err:
BN_CTX_end(ctx);
+1 -1
View File
@@ -254,7 +254,7 @@ static void nist_cp_bn_0(BN_ULONG *dst, const BN_ULONG *src, int top, int max)
int i;
#ifdef BN_DEBUG
assert(top <= max);
(void)ossl_assert(top <= max);
#endif
for (i = 0; i < top; i++)
dst[i] = src[i];
+2 -8
View File
@@ -82,14 +82,8 @@ int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
}
rr->neg = 0;
/*
* If the most-significant half of the top word of 'a' is zero, then the
* square of 'a' will max-1 words.
*/
if (a->d[al - 1] == (a->d[al - 1] & BN_MASK2l))
rr->top = max - 1;
else
rr->top = max;
rr->top = max;
bn_correct_top(rr);
if (r != rr && BN_copy(r, rr) == NULL)
goto err;
+1
View File
@@ -60,6 +60,7 @@ static const ERR_STRING_DATA CONF_str_reasons[] = {
{ERR_PACK(ERR_LIB_CONF, 0, CONF_R_NO_SECTION), "no section"},
{ERR_PACK(ERR_LIB_CONF, 0, CONF_R_NO_SUCH_FILE), "no such file"},
{ERR_PACK(ERR_LIB_CONF, 0, CONF_R_NO_VALUE), "no value"},
{ERR_PACK(ERR_LIB_CONF, 0, CONF_R_NUMBER_TOO_LARGE), "number too large"},
{ERR_PACK(ERR_LIB_CONF, 0, CONF_R_RECURSIVE_DIRECTORY_INCLUDE),
"recursive directory include"},
{ERR_PACK(ERR_LIB_CONF, 0, CONF_R_SSL_COMMAND_SECTION_EMPTY),
+33 -13
View File
@@ -11,6 +11,7 @@
#include <stdio.h>
#include <string.h>
#include "internal/conf.h"
#include "internal/ctype.h"
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/conf.h>
@@ -123,6 +124,7 @@ long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group,
int status;
long result = 0;
ERR_set_mark();
if (conf == NULL) {
status = NCONF_get_number_e(NULL, group, name, &result);
} else {
@@ -130,12 +132,8 @@ long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group,
CONF_set_nconf(&ctmp, conf);
status = NCONF_get_number_e(&ctmp, group, name, &result);
}
if (status == 0) {
/* This function does not believe in errors... */
ERR_clear_error();
}
return result;
ERR_pop_to_mark();
return status == 0 ? 0L : result;
}
void CONF_free(LHASH_OF(CONF_VALUE) *conf)
@@ -277,10 +275,23 @@ char *NCONF_get_string(const CONF *conf, const char *group, const char *name)
return NULL;
}
static int default_is_number(const CONF *conf, char c)
{
return ossl_isdigit(c);
}
static int default_to_int(const CONF *conf, char c)
{
return (int)(c - '0');
}
int NCONF_get_number_e(const CONF *conf, const char *group, const char *name,
long *result)
{
char *str;
long res;
int (*is_number)(const CONF *, char) = &default_is_number;
int (*to_int)(const CONF *, char) = &default_to_int;
if (result == NULL) {
CONFerr(CONF_F_NCONF_GET_NUMBER_E, ERR_R_PASSED_NULL_PARAMETER);
@@ -292,14 +303,23 @@ int NCONF_get_number_e(const CONF *conf, const char *group, const char *name,
if (str == NULL)
return 0;
if (conf == NULL)
*result = strtol(str, &str, 10);
else
for (*result = 0; conf->meth->is_number(conf, *str);) {
*result = (*result) * 10 + conf->meth->to_int(conf, *str);
str++;
}
if (conf != NULL) {
if (conf->meth->is_number != NULL)
is_number = conf->meth->is_number;
if (conf->meth->to_int != NULL)
to_int = conf->meth->to_int;
}
for (res = 0; is_number(conf, *str); str++) {
const int d = to_int(conf, *str);
if (res > (LONG_MAX - d) / 10L) {
CONFerr(CONF_F_NCONF_GET_NUMBER_E, CONF_R_NUMBER_TOO_LARGE);
return 0;
}
res = res * 10 + d;
}
*result = res;
return 1;
}
+314 -6
View File
@@ -13,7 +13,7 @@
# details see http://www.openssl.org/~appro/cryptogams/.
# ====================================================================
#
# X25519 lower-level primitives for x86_86.
# X25519 lower-level primitives for x86_64.
#
# February 2018.
#
@@ -102,13 +102,22 @@ $code.=<<___;
.type x25519_fe51_mul,\@function,3
.align 32
x25519_fe51_mul:
.cfi_startproc
push %rbp
.cfi_push %rbp
push %rbx
.cfi_push %rbx
push %r12
.cfi_push %r12
push %r13
.cfi_push %r13
push %r14
.cfi_push %r14
push %r15
.cfi_push %r15
lea -8*5(%rsp),%rsp
.cfi_adjust_cfa_offset 40
.Lfe51_mul_body:
mov 8*0(%rsi),%rax # f[0]
mov 8*0(%rdx),%r11 # load g[0-4]
@@ -236,19 +245,30 @@ x25519_fe51_mul:
mov 8*4(%rsp),%rdi # restore 1st argument
jmp .Lreduce51
.Lfe51_mul_epilogue:
.cfi_endproc
.size x25519_fe51_mul,.-x25519_fe51_mul
.globl x25519_fe51_sqr
.type x25519_fe51_sqr,\@function,2
.align 32
x25519_fe51_sqr:
.cfi_startproc
push %rbp
.cfi_push %rbp
push %rbx
.cfi_push %rbx
push %r12
.cfi_push %r12
push %r13
.cfi_push %r13
push %r14
.cfi_push %r14
push %r15
.cfi_push %r15
lea -8*5(%rsp),%rsp
.cfi_adjust_cfa_offset 40
.Lfe51_sqr_body:
mov 8*0(%rsi),%rax # g[0]
mov 8*2(%rsi),%r15 # g[2]
@@ -391,27 +411,45 @@ x25519_fe51_sqr:
mov %r10,8*4(%rdi)
mov 8*5(%rsp),%r15
.cfi_restore %r15
mov 8*6(%rsp),%r14
.cfi_restore %r14
mov 8*7(%rsp),%r13
.cfi_restore %r13
mov 8*8(%rsp),%r12
.cfi_restore %r12
mov 8*9(%rsp),%rbx
.cfi_restore %rbx
mov 8*10(%rsp),%rbp
.cfi_restore %rbp
lea 8*11(%rsp),%rsp
.cfi_adjust_cfa_offset 88
.Lfe51_sqr_epilogue:
ret
.cfi_endproc
.size x25519_fe51_sqr,.-x25519_fe51_sqr
.globl x25519_fe51_mul121666
.type x25519_fe51_mul121666,\@function,2
.align 32
x25519_fe51_mul121666:
.cfi_startproc
push %rbp
.cfi_push %rbp
push %rbx
.cfi_push %rbx
push %r12
.cfi_push %r12
push %r13
.cfi_push %r13
push %r14
.cfi_push %r14
push %r15
mov \$121666,%eax
.cfi_push %r15
lea -8*5(%rsp),%rsp
.cfi_adjust_cfa_offset 40
.Lfe51_mul121666_body:
mov \$121666,%eax
mulq 8*0(%rsi)
mov %rax,%rbx # %rbx:%rcx = h0
@@ -434,6 +472,8 @@ x25519_fe51_mul121666:
mov %rdx,%r15
jmp .Lreduce51
.Lfe51_mul121666_epilogue:
.cfi_endproc
.size x25519_fe51_mul121666,.-x25519_fe51_mul121666
___
########################################################################
@@ -460,14 +500,24 @@ x25519_fe64_eligible:
.type x25519_fe64_mul,\@function,3
.align 32
x25519_fe64_mul:
.cfi_startproc
push %rbp
.cfi_push %rbp
push %rbx
.cfi_push %rbx
push %r12
.cfi_push %r12
push %r13
.cfi_push %r13
push %r14
.cfi_push %r14
push %r15
.cfi_push %r15
push %rdi # offload dst
.cfi_push %rdi
lea -8*2(%rsp),%rsp
.cfi_adjust_cfa_offset 16
.Lfe64_mul_body:
mov %rdx,%rax
mov 8*0(%rdx),%rbp # b[0]
@@ -534,20 +584,32 @@ x25519_fe64_mul:
adox %rdi,$acc7 # of=0
jmp .Lreduce64
.Lfe64_mul_epilogue:
.cfi_endproc
.size x25519_fe64_mul,.-x25519_fe64_mul
.globl x25519_fe64_sqr
.type x25519_fe64_sqr,\@function,2
.align 32
x25519_fe64_sqr:
.cfi_startproc
push %rbp
.cfi_push %rbp
push %rbx
.cfi_push %rbx
push %r12
.cfi_push %r12
push %r13
.cfi_push %r13
push %r14
.cfi_push %r14
push %r15
.cfi_push %r15
push %rdi # offload dst
.cfi_push %rdi
lea -8*2(%rsp),%rsp
.cfi_adjust_cfa_offset 16
.Lfe64_sqr_body:
mov 8*0(%rsi),%rdx # a[0]
mov 8*1(%rsi),%rcx # a[1]
@@ -637,19 +699,29 @@ x25519_fe64_sqr:
mov $acc0,8*0(%rdi)
mov 8*3(%rsp),%r15
.cfi_restore %r15
mov 8*4(%rsp),%r14
.cfi_restore %r14
mov 8*5(%rsp),%r13
.cfi_restore %r13
mov 8*6(%rsp),%r12
.cfi_restore %r12
mov 8*7(%rsp),%rbx
.cfi_restore %rbx
mov 8*8(%rsp),%rbp
.cfi_restore %rbp
lea 8*9(%rsp),%rsp
.cfi_adjust_cfa_offset 88
.Lfe64_sqr_epilogue:
ret
.cfi_endproc
.size x25519_fe64_sqr,.-x25519_fe64_sqr
.globl x25519_fe64_mul121666
.type x25519_fe64_mul121666,\@function,2
.align 32
x25519_fe64_mul121666:
.Lfe64_mul121666_body:
mov \$121666,%edx
mulx 8*0(%rsi),$acc0,%rcx
mulx 8*1(%rsi),$acc1,%rax
@@ -676,6 +748,7 @@ x25519_fe64_mul121666:
mov $acc3,8*3(%rdi)
mov $acc0,8*0(%rdi)
.Lfe64_mul121666_epilogue:
ret
.size x25519_fe64_mul121666,.-x25519_fe64_mul121666
@@ -683,6 +756,7 @@ x25519_fe64_mul121666:
.type x25519_fe64_add,\@function,3
.align 32
x25519_fe64_add:
.Lfe64_add_body:
mov 8*0(%rsi),$acc0
mov 8*1(%rsi),$acc1
mov 8*2(%rsi),$acc2
@@ -698,13 +772,18 @@ x25519_fe64_add:
add %rax,$acc0
adc \$0,$acc1
mov $acc0,8*0(%rdi)
adc \$0,$acc2
mov $acc1,8*1(%rdi)
adc \$0,$acc3
mov $acc2,8*2(%rdi)
sbb %rax,%rax # cf -> mask
mov $acc3,8*3(%rdi)
and \$38,%rax
add %rax,$acc0
mov $acc0,8*0(%rdi)
.Lfe64_add_epilogue:
ret
.size x25519_fe64_add,.-x25519_fe64_add
@@ -712,6 +791,7 @@ x25519_fe64_add:
.type x25519_fe64_sub,\@function,3
.align 32
x25519_fe64_sub:
.Lfe64_sub_body:
mov 8*0(%rsi),$acc0
mov 8*1(%rsi),$acc1
mov 8*2(%rsi),$acc2
@@ -727,13 +807,18 @@ x25519_fe64_sub:
sub %rax,$acc0
sbb \$0,$acc1
mov $acc0,8*0(%rdi)
sbb \$0,$acc2
mov $acc1,8*1(%rdi)
sbb \$0,$acc3
mov $acc2,8*2(%rdi)
sbb %rax,%rax # cf -> mask
mov $acc3,8*3(%rdi)
and \$38,%rax
sub %rax,$acc0
mov $acc0,8*0(%rdi)
.Lfe64_sub_epilogue:
ret
.size x25519_fe64_sub,.-x25519_fe64_sub
@@ -741,6 +826,7 @@ x25519_fe64_sub:
.type x25519_fe64_tobytes,\@function,2
.align 32
x25519_fe64_tobytes:
.Lfe64_to_body:
mov 8*0(%rsi),$acc0
mov 8*1(%rsi),$acc1
mov 8*2(%rsi),$acc2
@@ -751,6 +837,7 @@ x25519_fe64_tobytes:
sar \$63,$acc3 # most significant bit -> mask
shr \$1,%rax # most significant bit cleared
and \$19,$acc3
add \$19,$acc3 # compare to modulus in the same go
add $acc3,$acc0
adc \$0,$acc1
@@ -760,15 +847,20 @@ x25519_fe64_tobytes:
lea (%rax,%rax),$acc3
sar \$63,%rax # most significant bit -> mask
shr \$1,$acc3 # most significant bit cleared
not %rax
and \$19,%rax
add %rax,$acc0
sub %rax,$acc0
sbb \$0,$acc1
sbb \$0,$acc2
sbb \$0,$acc3
mov $acc0,8*0(%rdi)
mov $acc1,8*1(%rdi)
mov $acc2,8*2(%rdi)
mov $acc3,8*3(%rdi)
mov $acc0,8*0(%rdi)
.Lfe64_to_epilogue:
ret
.size x25519_fe64_tobytes,.-x25519_fe64_tobytes
___
@@ -804,6 +896,222 @@ $code.=<<___;
.asciz "X25519 primitives for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
___
# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
# CONTEXT *context,DISPATCHER_CONTEXT *disp)
if ($win64) {
$rec="%rcx";
$frame="%rdx";
$context="%r8";
$disp="%r9";
$code.=<<___;
.extern __imp_RtlVirtualUnwind
.type short_handler,\@abi-omnipotent
.align 16
short_handler:
push %rsi
push %rdi
push %rbx
push %rbp
push %r12
push %r13
push %r14
push %r15
pushfq
sub \$64,%rsp
mov 120($context),%rax # pull context->Rax
mov 248($context),%rbx # pull context->Rip
mov 8($disp),%rsi # disp->ImageBase
mov 56($disp),%r11 # disp->HandlerData
mov 0(%r11),%r10d # HandlerData[0]
lea (%rsi,%r10),%r10 # end of prologue label
cmp %r10,%rbx # context->Rip<end of prologue label
jb .Lcommon_seh_tail
mov 152($context),%rax # pull context->Rsp
jmp .Lcommon_seh_tail
.size short_handler,.-short_handler
.type full_handler,\@abi-omnipotent
.align 16
full_handler:
push %rsi
push %rdi
push %rbx
push %rbp
push %r12
push %r13
push %r14
push %r15
pushfq
sub \$64,%rsp
mov 120($context),%rax # pull context->Rax
mov 248($context),%rbx # pull context->Rip
mov 8($disp),%rsi # disp->ImageBase
mov 56($disp),%r11 # disp->HandlerData
mov 0(%r11),%r10d # HandlerData[0]
lea (%rsi,%r10),%r10 # end of prologue label
cmp %r10,%rbx # context->Rip<end of prologue label
jb .Lcommon_seh_tail
mov 152($context),%rax # pull context->Rsp
mov 4(%r11),%r10d # HandlerData[1]
lea (%rsi,%r10),%r10 # epilogue label
cmp %r10,%rbx # context->Rip>=epilogue label
jae .Lcommon_seh_tail
mov 8(%r11),%r10d # HandlerData[2]
lea (%rax,%r10),%rax
mov -8(%rax),%rbp
mov -16(%rax),%rbx
mov -24(%rax),%r12
mov -32(%rax),%r13
mov -40(%rax),%r14
mov -48(%rax),%r15
mov %rbx,144($context) # restore context->Rbx
mov %rbp,160($context) # restore context->Rbp
mov %r12,216($context) # restore context->R12
mov %r13,224($context) # restore context->R13
mov %r14,232($context) # restore context->R14
mov %r15,240($context) # restore context->R15
.Lcommon_seh_tail:
mov 8(%rax),%rdi
mov 16(%rax),%rsi
mov %rax,152($context) # restore context->Rsp
mov %rsi,168($context) # restore context->Rsi
mov %rdi,176($context) # restore context->Rdi
mov 40($disp),%rdi # disp->ContextRecord
mov $context,%rsi # context
mov \$154,%ecx # sizeof(CONTEXT)
.long 0xa548f3fc # cld; rep movsq
mov $disp,%rsi
xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER
mov 8(%rsi),%rdx # arg2, disp->ImageBase
mov 0(%rsi),%r8 # arg3, disp->ControlPc
mov 16(%rsi),%r9 # arg4, disp->FunctionEntry
mov 40(%rsi),%r10 # disp->ContextRecord
lea 56(%rsi),%r11 # &disp->HandlerData
lea 24(%rsi),%r12 # &disp->EstablisherFrame
mov %r10,32(%rsp) # arg5
mov %r11,40(%rsp) # arg6
mov %r12,48(%rsp) # arg7
mov %rcx,56(%rsp) # arg8, (NULL)
call *__imp_RtlVirtualUnwind(%rip)
mov \$1,%eax # ExceptionContinueSearch
add \$64,%rsp
popfq
pop %r15
pop %r14
pop %r13
pop %r12
pop %rbp
pop %rbx
pop %rdi
pop %rsi
ret
.size full_handler,.-full_handler
.section .pdata
.align 4
.rva .LSEH_begin_x25519_fe51_mul
.rva .LSEH_end_x25519_fe51_mul
.rva .LSEH_info_x25519_fe51_mul
.rva .LSEH_begin_x25519_fe51_sqr
.rva .LSEH_end_x25519_fe51_sqr
.rva .LSEH_info_x25519_fe51_sqr
.rva .LSEH_begin_x25519_fe51_mul121666
.rva .LSEH_end_x25519_fe51_mul121666
.rva .LSEH_info_x25519_fe51_mul121666
___
$code.=<<___ if ($addx);
.rva .LSEH_begin_x25519_fe64_mul
.rva .LSEH_end_x25519_fe64_mul
.rva .LSEH_info_x25519_fe64_mul
.rva .LSEH_begin_x25519_fe64_sqr
.rva .LSEH_end_x25519_fe64_sqr
.rva .LSEH_info_x25519_fe64_sqr
.rva .LSEH_begin_x25519_fe64_mul121666
.rva .LSEH_end_x25519_fe64_mul121666
.rva .LSEH_info_x25519_fe64_mul121666
.rva .LSEH_begin_x25519_fe64_add
.rva .LSEH_end_x25519_fe64_add
.rva .LSEH_info_x25519_fe64_add
.rva .LSEH_begin_x25519_fe64_sub
.rva .LSEH_end_x25519_fe64_sub
.rva .LSEH_info_x25519_fe64_sub
.rva .LSEH_begin_x25519_fe64_tobytes
.rva .LSEH_end_x25519_fe64_tobytes
.rva .LSEH_info_x25519_fe64_tobytes
___
$code.=<<___;
.section .xdata
.align 8
.LSEH_info_x25519_fe51_mul:
.byte 9,0,0,0
.rva full_handler
.rva .Lfe51_mul_body,.Lfe51_mul_epilogue # HandlerData[]
.long 88,0
.LSEH_info_x25519_fe51_sqr:
.byte 9,0,0,0
.rva full_handler
.rva .Lfe51_sqr_body,.Lfe51_sqr_epilogue # HandlerData[]
.long 88,0
.LSEH_info_x25519_fe51_mul121666:
.byte 9,0,0,0
.rva full_handler
.rva .Lfe51_mul121666_body,.Lfe51_mul121666_epilogue # HandlerData[]
.long 88,0
___
$code.=<<___ if ($addx);
.LSEH_info_x25519_fe64_mul:
.byte 9,0,0,0
.rva full_handler
.rva .Lfe64_mul_body,.Lfe64_mul_epilogue # HandlerData[]
.long 72,0
.LSEH_info_x25519_fe64_sqr:
.byte 9,0,0,0
.rva full_handler
.rva .Lfe64_sqr_body,.Lfe64_sqr_epilogue # HandlerData[]
.long 72,0
.LSEH_info_x25519_fe64_mul121666:
.byte 9,0,0,0
.rva short_handler
.rva .Lfe64_mul121666_body,.Lfe64_mul121666_epilogue # HandlerData[]
.LSEH_info_x25519_fe64_add:
.byte 9,0,0,0
.rva short_handler
.rva .Lfe64_add_body,.Lfe64_add_epilogue # HandlerData[]
.LSEH_info_x25519_fe64_sub:
.byte 9,0,0,0
.rva short_handler
.rva .Lfe64_sub_body,.Lfe64_sub_epilogue # HandlerData[]
.LSEH_info_x25519_fe64_tobytes:
.byte 9,0,0,0
.rva short_handler
.rva .Lfe64_to_body,.Lfe64_to_epilogue # HandlerData[]
___
}
$code =~ s/\`([^\`]*)\`/eval $1/gem;
print $code;
close STDOUT;
+150 -143
View File
@@ -11,149 +11,23 @@
#include "ec_lcl.h"
#include <openssl/sha.h>
#if defined(X25519_ASM) \
|| ( (defined(__SIZEOF_INT128__) && __SIZEOF_INT128__ == 16) \
&& !defined(__sparc__) \
&& !(defined(__ANDROID__) && !defined(__clang__)) )
/*
* Base 2^51 implementation.
*/
# define BASE_2_51_IMPLEMENTED
#if defined(X25519_ASM) && (defined(__x86_64) || defined(__x86_64__) || \
defined(_M_AMD64) || defined(_M_X64))
typedef uint64_t fe51[5];
# if !defined(X25519_ASM)
typedef __uint128_t u128;
# endif
static const uint64_t MASK51 = 0x7ffffffffffff;
static uint64_t load_7(const uint8_t *in)
{
uint64_t result;
result = in[0];
result |= ((uint64_t)in[1]) << 8;
result |= ((uint64_t)in[2]) << 16;
result |= ((uint64_t)in[3]) << 24;
result |= ((uint64_t)in[4]) << 32;
result |= ((uint64_t)in[5]) << 40;
result |= ((uint64_t)in[6]) << 48;
return result;
}
static uint64_t load_6(const uint8_t *in)
{
uint64_t result;
result = in[0];
result |= ((uint64_t)in[1]) << 8;
result |= ((uint64_t)in[2]) << 16;
result |= ((uint64_t)in[3]) << 24;
result |= ((uint64_t)in[4]) << 32;
result |= ((uint64_t)in[5]) << 40;
return result;
}
static void fe51_frombytes(fe51 h, const uint8_t *s)
{
uint64_t h0 = load_7(s); /* 56 bits */
uint64_t h1 = load_6(s + 7) << 5; /* 53 bits */
uint64_t h2 = load_7(s + 13) << 2; /* 58 bits */
uint64_t h3 = load_6(s + 20) << 7; /* 55 bits */
uint64_t h4 = (load_6(s + 26) & 0x7fffffffffff) << 4; /* 51 bits */
h1 |= h0 >> 51; h0 &= MASK51;
h2 |= h1 >> 51; h1 &= MASK51;
h3 |= h2 >> 51; h2 &= MASK51;
h4 |= h3 >> 51; h3 &= MASK51;
h[0] = h0;
h[1] = h1;
h[2] = h2;
h[3] = h3;
h[4] = h4;
}
static void fe51_tobytes(uint8_t *s, const fe51 h)
{
uint64_t h0 = h[0];
uint64_t h1 = h[1];
uint64_t h2 = h[2];
uint64_t h3 = h[3];
uint64_t h4 = h[4];
uint64_t q;
/* compare to modulus */
q = (h0 + 19) >> 51;
q = (h1 + q) >> 51;
q = (h2 + q) >> 51;
q = (h3 + q) >> 51;
q = (h4 + q) >> 51;
/* full reduce */
h0 += 19 * q;
h1 += h0 >> 51; h0 &= MASK51;
h2 += h1 >> 51; h1 &= MASK51;
h3 += h2 >> 51; h2 &= MASK51;
h4 += h3 >> 51; h3 &= MASK51;
h4 &= MASK51;
/* smash */
s[0] = (uint8_t)(h0 >> 0);
s[1] = (uint8_t)(h0 >> 8);
s[2] = (uint8_t)(h0 >> 16);
s[3] = (uint8_t)(h0 >> 24);
s[4] = (uint8_t)(h0 >> 32);
s[5] = (uint8_t)(h0 >> 40);
s[6] = (uint8_t)((h0 >> 48) | ((uint32_t)h1 << 3));
s[7] = (uint8_t)(h1 >> 5);
s[8] = (uint8_t)(h1 >> 13);
s[9] = (uint8_t)(h1 >> 21);
s[10] = (uint8_t)(h1 >> 29);
s[11] = (uint8_t)(h1 >> 37);
s[12] = (uint8_t)((h1 >> 45) | ((uint32_t)h2 << 6));
s[13] = (uint8_t)(h2 >> 2);
s[14] = (uint8_t)(h2 >> 10);
s[15] = (uint8_t)(h2 >> 18);
s[16] = (uint8_t)(h2 >> 26);
s[17] = (uint8_t)(h2 >> 34);
s[18] = (uint8_t)(h2 >> 42);
s[19] = (uint8_t)((h2 >> 50) | ((uint32_t)h3 << 1));
s[20] = (uint8_t)(h3 >> 7);
s[21] = (uint8_t)(h3 >> 15);
s[22] = (uint8_t)(h3 >> 23);
s[23] = (uint8_t)(h3 >> 31);
s[24] = (uint8_t)(h3 >> 39);
s[25] = (uint8_t)((h3 >> 47) | ((uint32_t)h4 << 4));
s[26] = (uint8_t)(h4 >> 4);
s[27] = (uint8_t)(h4 >> 12);
s[28] = (uint8_t)(h4 >> 20);
s[29] = (uint8_t)(h4 >> 28);
s[30] = (uint8_t)(h4 >> 36);
s[31] = (uint8_t)(h4 >> 44);
}
# ifdef X25519_ASM
void x25519_fe51_mul(fe51 h, const fe51 f, const fe51 g);
void x25519_fe51_sqr(fe51 h, const fe51 f);
void x25519_fe51_mul121666(fe51 h, fe51 f);
# define fe51_mul x25519_fe51_mul
# define fe51_sq x25519_fe51_sqr
# define fe51_mul121666 x25519_fe51_mul121666
# if defined(__x86_64) || defined(__x86_64__) || \
defined(_M_AMD64) || defined(_M_X64)
# define BASE_2_64_IMPLEMENTED
# define BASE_2_64_IMPLEMENTED
typedef uint64_t fe64[4];
int x25519_fe64_eligible(void);
/*
* There are no reference C implementations for this radix.
* Following subroutines perform corresponding operations modulo
* 2^256-38, i.e. double the curve modulus. However, inputs and
* outputs are permitted to be partially reduced, i.e. to remain
* in [0..2^256) range. It's all tied up in final fe64_tobytes
* that performs full reduction modulo 2^255-19.
*
* There are no reference C implementations for these.
*/
void x25519_fe64_mul(fe64 h, const fe64 f, const fe64 g);
void x25519_fe64_sqr(fe64 h, const fe64 f);
@@ -161,12 +35,12 @@ void x25519_fe64_mul121666(fe64 h, fe64 f);
void x25519_fe64_add(fe64 h, const fe64 f, const fe64 g);
void x25519_fe64_sub(fe64 h, const fe64 f, const fe64 g);
void x25519_fe64_tobytes(uint8_t *s, const fe64 f);
# define fe64_mul x25519_fe64_mul
# define fe64_sqr x25519_fe64_sqr
# define fe64_mul121666 x25519_fe64_mul121666
# define fe64_add x25519_fe64_add
# define fe64_sub x25519_fe64_sub
# define fe64_tobytes x25519_fe64_tobytes
# define fe64_mul x25519_fe64_mul
# define fe64_sqr x25519_fe64_sqr
# define fe64_mul121666 x25519_fe64_mul121666
# define fe64_add x25519_fe64_add
# define fe64_sub x25519_fe64_sub
# define fe64_tobytes x25519_fe64_tobytes
static uint64_t load_8(const uint8_t *in)
{
@@ -375,10 +249,143 @@ static void x25519_scalar_mulx(uint8_t out[32], const uint8_t scalar[32],
OPENSSL_cleanse(e, sizeof(e));
}
# endif
#endif
#if defined(X25519_ASM) \
|| ( (defined(__SIZEOF_INT128__) && __SIZEOF_INT128__ == 16) \
&& !defined(__sparc__) \
&& !(defined(__ANDROID__) && !defined(__clang__)) )
/*
* Base 2^51 implementation. It's virtually no different from reference
* base 2^25.5 implementation in respect to lax boundary conditions for
* intermediate values and even individual limbs. So that whatever you
* know about the reference, applies even here...
*/
# define BASE_2_51_IMPLEMENTED
typedef uint64_t fe51[5];
static const uint64_t MASK51 = 0x7ffffffffffff;
static uint64_t load_7(const uint8_t *in)
{
uint64_t result;
result = in[0];
result |= ((uint64_t)in[1]) << 8;
result |= ((uint64_t)in[2]) << 16;
result |= ((uint64_t)in[3]) << 24;
result |= ((uint64_t)in[4]) << 32;
result |= ((uint64_t)in[5]) << 40;
result |= ((uint64_t)in[6]) << 48;
return result;
}
static uint64_t load_6(const uint8_t *in)
{
uint64_t result;
result = in[0];
result |= ((uint64_t)in[1]) << 8;
result |= ((uint64_t)in[2]) << 16;
result |= ((uint64_t)in[3]) << 24;
result |= ((uint64_t)in[4]) << 32;
result |= ((uint64_t)in[5]) << 40;
return result;
}
static void fe51_frombytes(fe51 h, const uint8_t *s)
{
uint64_t h0 = load_7(s); /* 56 bits */
uint64_t h1 = load_6(s + 7) << 5; /* 53 bits */
uint64_t h2 = load_7(s + 13) << 2; /* 58 bits */
uint64_t h3 = load_6(s + 20) << 7; /* 55 bits */
uint64_t h4 = (load_6(s + 26) & 0x7fffffffffff) << 4; /* 51 bits */
h1 |= h0 >> 51; h0 &= MASK51;
h2 |= h1 >> 51; h1 &= MASK51;
h3 |= h2 >> 51; h2 &= MASK51;
h4 |= h3 >> 51; h3 &= MASK51;
h[0] = h0;
h[1] = h1;
h[2] = h2;
h[3] = h3;
h[4] = h4;
}
static void fe51_tobytes(uint8_t *s, const fe51 h)
{
uint64_t h0 = h[0];
uint64_t h1 = h[1];
uint64_t h2 = h[2];
uint64_t h3 = h[3];
uint64_t h4 = h[4];
uint64_t q;
/* compare to modulus */
q = (h0 + 19) >> 51;
q = (h1 + q) >> 51;
q = (h2 + q) >> 51;
q = (h3 + q) >> 51;
q = (h4 + q) >> 51;
/* full reduce */
h0 += 19 * q;
h1 += h0 >> 51; h0 &= MASK51;
h2 += h1 >> 51; h1 &= MASK51;
h3 += h2 >> 51; h2 &= MASK51;
h4 += h3 >> 51; h3 &= MASK51;
h4 &= MASK51;
/* smash */
s[0] = (uint8_t)(h0 >> 0);
s[1] = (uint8_t)(h0 >> 8);
s[2] = (uint8_t)(h0 >> 16);
s[3] = (uint8_t)(h0 >> 24);
s[4] = (uint8_t)(h0 >> 32);
s[5] = (uint8_t)(h0 >> 40);
s[6] = (uint8_t)((h0 >> 48) | ((uint32_t)h1 << 3));
s[7] = (uint8_t)(h1 >> 5);
s[8] = (uint8_t)(h1 >> 13);
s[9] = (uint8_t)(h1 >> 21);
s[10] = (uint8_t)(h1 >> 29);
s[11] = (uint8_t)(h1 >> 37);
s[12] = (uint8_t)((h1 >> 45) | ((uint32_t)h2 << 6));
s[13] = (uint8_t)(h2 >> 2);
s[14] = (uint8_t)(h2 >> 10);
s[15] = (uint8_t)(h2 >> 18);
s[16] = (uint8_t)(h2 >> 26);
s[17] = (uint8_t)(h2 >> 34);
s[18] = (uint8_t)(h2 >> 42);
s[19] = (uint8_t)((h2 >> 50) | ((uint32_t)h3 << 1));
s[20] = (uint8_t)(h3 >> 7);
s[21] = (uint8_t)(h3 >> 15);
s[22] = (uint8_t)(h3 >> 23);
s[23] = (uint8_t)(h3 >> 31);
s[24] = (uint8_t)(h3 >> 39);
s[25] = (uint8_t)((h3 >> 47) | ((uint32_t)h4 << 4));
s[26] = (uint8_t)(h4 >> 4);
s[27] = (uint8_t)(h4 >> 12);
s[28] = (uint8_t)(h4 >> 20);
s[29] = (uint8_t)(h4 >> 28);
s[30] = (uint8_t)(h4 >> 36);
s[31] = (uint8_t)(h4 >> 44);
}
# if defined(X25519_ASM)
void x25519_fe51_mul(fe51 h, const fe51 f, const fe51 g);
void x25519_fe51_sqr(fe51 h, const fe51 f);
void x25519_fe51_mul121666(fe51 h, fe51 f);
# define fe51_mul x25519_fe51_mul
# define fe51_sq x25519_fe51_sqr
# define fe51_mul121666 x25519_fe51_mul121666
# else
typedef __uint128_t u128;
static void fe51_mul(fe51 h, const fe51 f, const fe51 g)
{
u128 h0, h1, h2, h3, h4;
+271 -57
View File
@@ -15,63 +15,6 @@
#ifndef OPENSSL_NO_EC2M
const EC_METHOD *EC_GF2m_simple_method(void)
{
static const EC_METHOD ret = {
EC_FLAGS_DEFAULT_OCT,
NID_X9_62_characteristic_two_field,
ec_GF2m_simple_group_init,
ec_GF2m_simple_group_finish,
ec_GF2m_simple_group_clear_finish,
ec_GF2m_simple_group_copy,
ec_GF2m_simple_group_set_curve,
ec_GF2m_simple_group_get_curve,
ec_GF2m_simple_group_get_degree,
ec_group_simple_order_bits,
ec_GF2m_simple_group_check_discriminant,
ec_GF2m_simple_point_init,
ec_GF2m_simple_point_finish,
ec_GF2m_simple_point_clear_finish,
ec_GF2m_simple_point_copy,
ec_GF2m_simple_point_set_to_infinity,
0 /* set_Jprojective_coordinates_GFp */ ,
0 /* get_Jprojective_coordinates_GFp */ ,
ec_GF2m_simple_point_set_affine_coordinates,
ec_GF2m_simple_point_get_affine_coordinates,
0, 0, 0,
ec_GF2m_simple_add,
ec_GF2m_simple_dbl,
ec_GF2m_simple_invert,
ec_GF2m_simple_is_at_infinity,
ec_GF2m_simple_is_on_curve,
ec_GF2m_simple_cmp,
ec_GF2m_simple_make_affine,
ec_GF2m_simple_points_make_affine,
0 /* mul */,
0 /* precompute_mul */,
0 /* have_precompute_mul */,
ec_GF2m_simple_field_mul,
ec_GF2m_simple_field_sqr,
ec_GF2m_simple_field_div,
0 /* field_encode */ ,
0 /* field_decode */ ,
0, /* field_set_to_one */
ec_key_simple_priv2oct,
ec_key_simple_oct2priv,
0, /* set private */
ec_key_simple_generate_key,
ec_key_simple_check_key,
ec_key_simple_generate_public_key,
0, /* keycopy */
0, /* keyfinish */
ecdh_simple_compute_key,
0, /* field_inverse_mod_ord */
0 /* blind_coordinates */
};
return &ret;
}
/*
* Initialize a GF(2^m)-based EC_GROUP structure. Note that all other members
* are handled by EC_GROUP_new.
@@ -737,4 +680,275 @@ int ec_GF2m_simple_field_div(const EC_GROUP *group, BIGNUM *r,
return BN_GF2m_mod_div(r, a, b, group->field, ctx);
}
/*-
* Lopez-Dahab ladder, pre step.
* See e.g. "Guide to ECC" Alg 3.40.
* Modified to blind s and r independently.
* s:= p, r := 2p
*/
static
int ec_GF2m_simple_ladder_pre(const EC_GROUP *group,
EC_POINT *r, EC_POINT *s,
EC_POINT *p, BN_CTX *ctx)
{
/* if p is not affine, something is wrong */
if (p->Z_is_one == 0)
return 0;
/* s blinding: make sure lambda (s->Z here) is not zero */
do {
if (!BN_priv_rand(s->Z, BN_num_bits(group->field) - 1,
BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) {
ECerr(EC_F_EC_GF2M_SIMPLE_LADDER_PRE, ERR_R_BN_LIB);
return 0;
}
} while (BN_is_zero(s->Z));
/* if field_encode defined convert between representations */
if ((group->meth->field_encode != NULL
&& !group->meth->field_encode(group, s->Z, s->Z, ctx))
|| !group->meth->field_mul(group, s->X, p->X, s->Z, ctx))
return 0;
/* r blinding: make sure lambda (r->Y here for storage) is not zero */
do {
if (!BN_priv_rand(r->Y, BN_num_bits(group->field) - 1,
BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) {
ECerr(EC_F_EC_GF2M_SIMPLE_LADDER_PRE, ERR_R_BN_LIB);
return 0;
}
} while (BN_is_zero(r->Y));
if ((group->meth->field_encode != NULL
&& !group->meth->field_encode(group, r->Y, r->Y, ctx))
|| !group->meth->field_sqr(group, r->Z, p->X, ctx)
|| !group->meth->field_sqr(group, r->X, r->Z, ctx)
|| !BN_GF2m_add(r->X, r->X, group->b)
|| !group->meth->field_mul(group, r->Z, r->Z, r->Y, ctx)
|| !group->meth->field_mul(group, r->X, r->X, r->Y, ctx))
return 0;
s->Z_is_one = 0;
r->Z_is_one = 0;
return 1;
}
/*-
* Ladder step: differential addition-and-doubling, mixed Lopez-Dahab coords.
* http://www.hyperelliptic.org/EFD/g12o/auto-code/shortw/xz/ladder/mladd-2003-s.op3
* s := r + s, r := 2r
*/
static
int ec_GF2m_simple_ladder_step(const EC_GROUP *group,
EC_POINT *r, EC_POINT *s,
EC_POINT *p, BN_CTX *ctx)
{
if (!group->meth->field_mul(group, r->Y, r->Z, s->X, ctx)
|| !group->meth->field_mul(group, s->X, r->X, s->Z, ctx)
|| !group->meth->field_sqr(group, s->Y, r->Z, ctx)
|| !group->meth->field_sqr(group, r->Z, r->X, ctx)
|| !BN_GF2m_add(s->Z, r->Y, s->X)
|| !group->meth->field_sqr(group, s->Z, s->Z, ctx)
|| !group->meth->field_mul(group, s->X, r->Y, s->X, ctx)
|| !group->meth->field_mul(group, r->Y, s->Z, p->X, ctx)
|| !BN_GF2m_add(s->X, s->X, r->Y)
|| !group->meth->field_sqr(group, r->Y, r->Z, ctx)
|| !group->meth->field_mul(group, r->Z, r->Z, s->Y, ctx)
|| !group->meth->field_sqr(group, s->Y, s->Y, ctx)
|| !group->meth->field_mul(group, s->Y, s->Y, group->b, ctx)
|| !BN_GF2m_add(r->X, r->Y, s->Y))
return 0;
return 1;
}
/*-
* Recover affine (x,y) result from Lopez-Dahab r and s, affine p.
* See e.g. "Fast Multiplication on Elliptic Curves over GF(2**m)
* without Precomputation" (Lopez and Dahab, CHES 1999),
* Appendix Alg Mxy.
*/
static
int ec_GF2m_simple_ladder_post(const EC_GROUP *group,
EC_POINT *r, EC_POINT *s,
EC_POINT *p, BN_CTX *ctx)
{
int ret = 0;
BIGNUM *t0, *t1, *t2 = NULL;
if (BN_is_zero(r->Z))
return EC_POINT_set_to_infinity(group, r);
if (BN_is_zero(s->Z)) {
if (!EC_POINT_copy(r, p)
|| !EC_POINT_invert(group, r, ctx)) {
ECerr(EC_F_EC_GF2M_SIMPLE_LADDER_POST, ERR_R_EC_LIB);
return 0;
}
return 1;
}
BN_CTX_start(ctx);
t0 = BN_CTX_get(ctx);
t1 = BN_CTX_get(ctx);
t2 = BN_CTX_get(ctx);
if (t2 == NULL) {
ECerr(EC_F_EC_GF2M_SIMPLE_LADDER_POST, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!group->meth->field_mul(group, t0, r->Z, s->Z, ctx)
|| !group->meth->field_mul(group, t1, p->X, r->Z, ctx)
|| !BN_GF2m_add(t1, r->X, t1)
|| !group->meth->field_mul(group, t2, p->X, s->Z, ctx)
|| !group->meth->field_mul(group, r->Z, r->X, t2, ctx)
|| !BN_GF2m_add(t2, t2, s->X)
|| !group->meth->field_mul(group, t1, t1, t2, ctx)
|| !group->meth->field_sqr(group, t2, p->X, ctx)
|| !BN_GF2m_add(t2, p->Y, t2)
|| !group->meth->field_mul(group, t2, t2, t0, ctx)
|| !BN_GF2m_add(t1, t2, t1)
|| !group->meth->field_mul(group, t2, p->X, t0, ctx)
|| !BN_GF2m_mod_inv(t2, t2, group->field, ctx)
|| !group->meth->field_mul(group, t1, t1, t2, ctx)
|| !group->meth->field_mul(group, r->X, r->Z, t2, ctx)
|| !BN_GF2m_add(t2, p->X, r->X)
|| !group->meth->field_mul(group, t2, t2, t1, ctx)
|| !BN_GF2m_add(r->Y, p->Y, t2)
|| !BN_one(r->Z))
goto err;
r->Z_is_one = 1;
/* GF(2^m) field elements should always have BIGNUM::neg = 0 */
BN_set_negative(r->X, 0);
BN_set_negative(r->Y, 0);
ret = 1;
err:
BN_CTX_end(ctx);
return ret;
}
static
int ec_GF2m_simple_points_mul(const EC_GROUP *group, EC_POINT *r,
const BIGNUM *scalar, size_t num,
const EC_POINT *points[],
const BIGNUM *scalars[],
BN_CTX *ctx)
{
int ret = 0;
EC_POINT *t = NULL;
/*-
* We limit use of the ladder only to the following cases:
* - r := scalar * G
* Fixed point mul: scalar != NULL && num == 0;
* - r := scalars[0] * points[0]
* Variable point mul: scalar == NULL && num == 1;
* - r := scalar * G + scalars[0] * points[0]
* used, e.g., in ECDSA verification: scalar != NULL && num == 1
*
* In any other case (num > 1) we use the default wNAF implementation.
*
* We also let the default implementation handle degenerate cases like group
* order or cofactor set to 0.
*/
if (num > 1 || BN_is_zero(group->order) || BN_is_zero(group->cofactor))
return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
if (scalar != NULL && num == 0)
/* Fixed point multiplication */
return ec_scalar_mul_ladder(group, r, scalar, NULL, ctx);
if (scalar == NULL && num == 1)
/* Variable point multiplication */
return ec_scalar_mul_ladder(group, r, scalars[0], points[0], ctx);
/*-
* Double point multiplication:
* r := scalar * G + scalars[0] * points[0]
*/
if ((t = EC_POINT_new(group)) == NULL) {
ECerr(EC_F_EC_GF2M_SIMPLE_POINTS_MUL, ERR_R_MALLOC_FAILURE);
return 0;
}
if (!ec_scalar_mul_ladder(group, t, scalar, NULL, ctx)
|| !ec_scalar_mul_ladder(group, r, scalars[0], points[0], ctx)
|| !EC_POINT_add(group, r, t, r, ctx))
goto err;
ret = 1;
err:
EC_POINT_free(t);
return ret;
}
const EC_METHOD *EC_GF2m_simple_method(void)
{
static const EC_METHOD ret = {
EC_FLAGS_DEFAULT_OCT,
NID_X9_62_characteristic_two_field,
ec_GF2m_simple_group_init,
ec_GF2m_simple_group_finish,
ec_GF2m_simple_group_clear_finish,
ec_GF2m_simple_group_copy,
ec_GF2m_simple_group_set_curve,
ec_GF2m_simple_group_get_curve,
ec_GF2m_simple_group_get_degree,
ec_group_simple_order_bits,
ec_GF2m_simple_group_check_discriminant,
ec_GF2m_simple_point_init,
ec_GF2m_simple_point_finish,
ec_GF2m_simple_point_clear_finish,
ec_GF2m_simple_point_copy,
ec_GF2m_simple_point_set_to_infinity,
0, /* set_Jprojective_coordinates_GFp */
0, /* get_Jprojective_coordinates_GFp */
ec_GF2m_simple_point_set_affine_coordinates,
ec_GF2m_simple_point_get_affine_coordinates,
0, /* point_set_compressed_coordinates */
0, /* point2oct */
0, /* oct2point */
ec_GF2m_simple_add,
ec_GF2m_simple_dbl,
ec_GF2m_simple_invert,
ec_GF2m_simple_is_at_infinity,
ec_GF2m_simple_is_on_curve,
ec_GF2m_simple_cmp,
ec_GF2m_simple_make_affine,
ec_GF2m_simple_points_make_affine,
ec_GF2m_simple_points_mul,
0, /* precompute_mult */
0, /* have_precompute_mult */
ec_GF2m_simple_field_mul,
ec_GF2m_simple_field_sqr,
ec_GF2m_simple_field_div,
0, /* field_encode */
0, /* field_decode */
0, /* field_set_to_one */
ec_key_simple_priv2oct,
ec_key_simple_oct2priv,
0, /* set private */
ec_key_simple_generate_key,
ec_key_simple_check_key,
ec_key_simple_generate_public_key,
0, /* keycopy */
0, /* keyfinish */
ecdh_simple_compute_key,
0, /* field_inverse_mod_ord */
0, /* blind_coordinates */
ec_GF2m_simple_ladder_pre,
ec_GF2m_simple_ladder_step,
ec_GF2m_simple_ladder_post
};
return &ret;
}
#endif
+15 -6
View File
@@ -70,10 +70,16 @@ static const ERR_STRING_DATA EC_str_functs[] = {
"ec_GF2m_simple_group_check_discriminant"},
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, 0),
"ec_GF2m_simple_group_set_curve"},
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_LADDER_POST, 0),
"ec_GF2m_simple_ladder_post"},
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_LADDER_PRE, 0),
"ec_GF2m_simple_ladder_pre"},
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_OCT2POINT, 0),
"ec_GF2m_simple_oct2point"},
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_POINT2OCT, 0),
"ec_GF2m_simple_point2oct"},
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_POINTS_MUL, 0),
"ec_GF2m_simple_points_mul"},
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, 0),
"ec_GF2m_simple_point_get_affine_coordinates"},
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES, 0),
@@ -191,6 +197,7 @@ static const ERR_STRING_DATA EC_str_functs[] = {
{ERR_PACK(ERR_LIB_EC, EC_F_EC_PKEY_PARAM_CHECK, 0), "ec_pkey_param_check"},
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINTS_MAKE_AFFINE, 0),
"EC_POINTs_make_affine"},
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINTS_MUL, 0), "EC_POINTs_mul"},
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_ADD, 0), "EC_POINT_add"},
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_BN2POINT, 0), "EC_POINT_bn2point"},
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_CMP, 0), "EC_POINT_cmp"},
@@ -226,6 +233,8 @@ static const ERR_STRING_DATA EC_str_functs[] = {
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_TO_INFINITY, 0),
"EC_POINT_set_to_infinity"},
{ERR_PACK(ERR_LIB_EC, EC_F_EC_PRE_COMP_NEW, 0), "ec_pre_comp_new"},
{ERR_PACK(ERR_LIB_EC, EC_F_EC_SCALAR_MUL_LADDER, 0),
"ec_scalar_mul_ladder"},
{ERR_PACK(ERR_LIB_EC, EC_F_EC_WNAF_MUL, 0), "ec_wNAF_mul"},
{ERR_PACK(ERR_LIB_EC, EC_F_EC_WNAF_PRECOMPUTE_MULT, 0),
"ec_wNAF_precompute_mult"},
@@ -261,12 +270,6 @@ static const ERR_STRING_DATA EC_str_functs[] = {
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_KEYGEN, 0), "pkey_ec_keygen"},
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_PARAMGEN, 0), "pkey_ec_paramgen"},
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_SIGN, 0), "pkey_ec_sign"},
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_SM2_CTRL, 0), "pkey_sm2_ctrl"},
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_SM2_CTRL_STR, 0), "pkey_sm2_ctrl_str"},
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_SM2_INIT, 0), "pkey_sm2_init"},
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_SM2_KEYGEN, 0), "pkey_sm2_keygen"},
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_SM2_PARAMGEN, 0), "pkey_sm2_paramgen"},
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_SM2_SIGN, 0), "pkey_sm2_sign"},
{ERR_PACK(ERR_LIB_EC, EC_F_VALIDATE_ECX_DERIVE, 0), "validate_ecx_derive"},
{0, NULL}
};
@@ -320,6 +323,9 @@ static const ERR_STRING_DATA EC_str_reasons[] = {
"invalid trinomial basis"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_KDF_PARAMETER_ERROR), "kdf parameter error"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_KEYS_NOT_SET), "keys not set"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_LADDER_POST_FAILURE), "ladder post failure"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_LADDER_PRE_FAILURE), "ladder pre failure"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_LADDER_STEP_FAILURE), "ladder step failure"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_MISSING_PARAMETERS), "missing parameters"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_MISSING_PRIVATE_KEY), "missing private key"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_NEED_NEW_SETUP_VALUES),
@@ -339,6 +345,8 @@ static const ERR_STRING_DATA EC_str_reasons[] = {
{ERR_PACK(ERR_LIB_EC, 0, EC_R_POINT_ARITHMETIC_FAILURE),
"point arithmetic failure"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_POINT_AT_INFINITY), "point at infinity"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_POINT_COORDINATES_BLIND_FAILURE),
"point coordinates blind failure"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_POINT_IS_NOT_ON_CURVE),
"point is not on curve"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_RANDOM_NUMBER_GENERATION_FAILED),
@@ -347,6 +355,7 @@ static const ERR_STRING_DATA EC_str_reasons[] = {
{ERR_PACK(ERR_LIB_EC, 0, EC_R_SLOT_FULL), "slot full"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_UNDEFINED_GENERATOR), "undefined generator"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_UNDEFINED_ORDER), "undefined order"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_UNKNOWN_COFACTOR), "unknown cofactor"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_UNKNOWN_GROUP), "unknown group"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_UNKNOWN_ORDER), "unknown order"},
{ERR_PACK(ERR_LIB_EC, 0, EC_R_UNSUPPORTED_FIELD), "unsupported field"},
+81
View File
@@ -178,6 +178,15 @@ struct ec_method_st {
int (*field_inverse_mod_ord)(const EC_GROUP *, BIGNUM *r,
const BIGNUM *x, BN_CTX *);
int (*blind_coordinates)(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx);
int (*ladder_pre)(const EC_GROUP *group,
EC_POINT *r, EC_POINT *s,
EC_POINT *p, BN_CTX *ctx);
int (*ladder_step)(const EC_GROUP *group,
EC_POINT *r, EC_POINT *s,
EC_POINT *p, BN_CTX *ctx);
int (*ladder_post)(const EC_GROUP *group,
EC_POINT *r, EC_POINT *s,
EC_POINT *p, BN_CTX *ctx);
};
/*
@@ -637,4 +646,76 @@ int X25519(uint8_t out_shared_key[32], const uint8_t private_key[32],
void X25519_public_from_private(uint8_t out_public_value[32],
const uint8_t private_key[32]);
/*-
* This functions computes a single point multiplication over the EC group,
* using, at a high level, a Montgomery ladder with conditional swaps, with
* various timing attack defenses.
*
* It performs either a fixed point multiplication
* (scalar * generator)
* when point is NULL, or a variable point multiplication
* (scalar * point)
* when point is not NULL.
*
* `scalar` cannot be NULL and should be in the range [0,n) otherwise all
* constant time bets are off (where n is the cardinality of the EC group).
*
* This function expects `group->order` and `group->cardinality` to be well
* defined and non-zero: it fails with an error code otherwise.
*
* NB: This says nothing about the constant-timeness of the ladder step
* implementation (i.e., the default implementation is based on EC_POINT_add and
* EC_POINT_dbl, which of course are not constant time themselves) or the
* underlying multiprecision arithmetic.
*
* The product is stored in `r`.
*
* This is an internal function: callers are in charge of ensuring that the
* input parameters `group`, `r`, `scalar` and `ctx` are not NULL.
*
* Returns 1 on success, 0 otherwise.
*/
int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
const BIGNUM *scalar, const EC_POINT *point,
BN_CTX *ctx);
int ec_point_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx);
static inline int ec_point_ladder_pre(const EC_GROUP *group,
EC_POINT *r, EC_POINT *s,
EC_POINT *p, BN_CTX *ctx)
{
if (group->meth->ladder_pre != NULL)
return group->meth->ladder_pre(group, r, s, p, ctx);
if (!EC_POINT_copy(s, p)
|| !EC_POINT_dbl(group, r, s, ctx))
return 0;
return 1;
}
static inline int ec_point_ladder_step(const EC_GROUP *group,
EC_POINT *r, EC_POINT *s,
EC_POINT *p, BN_CTX *ctx)
{
if (group->meth->ladder_step != NULL)
return group->meth->ladder_step(group, r, s, p, ctx);
if (!EC_POINT_add(group, s, r, s, ctx)
|| !EC_POINT_dbl(group, r, r, ctx))
return 0;
return 1;
}
static inline int ec_point_ladder_post(const EC_GROUP *group,
EC_POINT *r, EC_POINT *s,
EC_POINT *p, BN_CTX *ctx)
{
if (group->meth->ladder_post != NULL)
return group->meth->ladder_post(group, r, s, p, ctx);
return 1;
}
+31 -4
View File
@@ -919,11 +919,38 @@ int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
size_t num, const EC_POINT *points[],
const BIGNUM *scalars[], BN_CTX *ctx)
{
if (group->meth->mul == 0)
/* use default */
return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
int ret = 0;
size_t i = 0;
BN_CTX *new_ctx = NULL;
return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
if ((scalar == NULL) && (num == 0)) {
return EC_POINT_set_to_infinity(group, r);
}
if (!ec_point_is_compat(r, group)) {
ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
for (i = 0; i < num; i++) {
if (!ec_point_is_compat(points[i], group)) {
ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
}
if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL) {
ECerr(EC_F_EC_POINTS_MUL, ERR_R_INTERNAL_ERROR);
return 0;
}
if (group->meth->mul != NULL)
ret = group->meth->mul(group, r, scalar, num, points, scalars, ctx);
else
/* use default */
ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
BN_CTX_free(new_ctx);
return ret;
}
int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
+114 -81
View File
@@ -108,10 +108,9 @@ void EC_ec_pre_comp_free(EC_PRE_COMP *pre)
} 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.
* This functions computes a single point multiplication over the EC group,
* using, at a high level, a Montgomery ladder with conditional swaps, with
* various timing attack defenses.
*
* It performs either a fixed point multiplication
* (scalar * generator)
@@ -119,51 +118,85 @@ void EC_ec_pre_comp_free(EC_PRE_COMP *pre)
* (scalar * point)
* when point is not NULL.
*
* scalar should be in the range [0,n) otherwise all constant time bets are off.
* `scalar` cannot be NULL and should be in the range [0,n) otherwise all
* constant time bets are off (where n is the cardinality of the EC group).
*
* NB: This says nothing about EC_POINT_add and EC_POINT_dbl,
* which of course are not constant time themselves.
* This function expects `group->order` and `group->cardinality` to be well
* defined and non-zero: it fails with an error code otherwise.
*
* The product is stored in r.
* NB: This says nothing about the constant-timeness of the ladder step
* implementation (i.e., the default implementation is based on EC_POINT_add and
* EC_POINT_dbl, which of course are not constant time themselves) or the
* underlying multiprecision arithmetic.
*
* The product is stored in `r`.
*
* This is an internal function: callers are in charge of ensuring that the
* input parameters `group`, `r`, `scalar` and `ctx` are not NULL.
*
* 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 ec_scalar_mul_ladder(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 *p = NULL;
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_secure_new()) == NULL)
/* early exit if the input point is the point at infinity */
if (point != NULL && EC_POINT_is_at_infinity(group, point))
return EC_POINT_set_to_infinity(group, r);
if (BN_is_zero(group->order)) {
ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_UNKNOWN_ORDER);
return 0;
}
if (BN_is_zero(group->cofactor)) {
ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_UNKNOWN_COFACTOR);
return 0;
}
BN_CTX_start(ctx);
s = EC_POINT_new(group);
if (s == NULL)
if (((p = EC_POINT_new(group)) == NULL)
|| ((s = EC_POINT_new(group)) == NULL)) {
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_MALLOC_FAILURE);
goto err;
if (point == NULL) {
if (!EC_POINT_copy(s, group->generator))
goto err;
} else {
if (!EC_POINT_copy(s, point))
goto err;
}
if (point == NULL) {
if (!EC_POINT_copy(p, group->generator)) {
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_EC_LIB);
goto err;
}
} else {
if (!EC_POINT_copy(p, point)) {
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_EC_LIB);
goto err;
}
}
EC_POINT_BN_set_flags(p, BN_FLG_CONSTTIME);
EC_POINT_BN_set_flags(r, BN_FLG_CONSTTIME);
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))
if (k == NULL) {
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!BN_mul(cardinality, group->order, group->cofactor, ctx)) {
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
goto err;
}
/*
* Group cardinalities are often on a word boundary.
@@ -174,11 +207,15 @@ static int ec_mul_consttime(const EC_GROUP *group, EC_POINT *r,
cardinality_bits = BN_num_bits(cardinality);
group_top = bn_get_top(cardinality);
if ((bn_wexpand(k, group_top + 1) == NULL)
|| (bn_wexpand(lambda, group_top + 1) == NULL))
|| (bn_wexpand(lambda, group_top + 1) == NULL)) {
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
goto err;
}
if (!BN_copy(k, scalar))
if (!BN_copy(k, scalar)) {
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
goto err;
}
BN_set_flags(k, BN_FLG_CONSTTIME);
@@ -187,15 +224,21 @@ static int ec_mul_consttime(const EC_GROUP *group, EC_POINT *r,
* this is an unusual input, and we don't guarantee
* constant-timeness
*/
if (!BN_nnmod(k, k, cardinality, ctx))
if (!BN_nnmod(k, k, cardinality, ctx)) {
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
goto err;
}
}
if (!BN_add(lambda, k, cardinality))
if (!BN_add(lambda, k, cardinality)) {
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
goto err;
}
BN_set_flags(lambda, BN_FLG_CONSTTIME);
if (!BN_add(k, lambda, cardinality))
if (!BN_add(k, lambda, cardinality)) {
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
goto err;
}
/*
* lambda := scalar + cardinality
* k := scalar + 2*cardinality
@@ -209,8 +252,13 @@ static int ec_mul_consttime(const EC_GROUP *group, EC_POINT *r,
|| (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))
|| (bn_wexpand(r->Z, group_top) == NULL)
|| (bn_wexpand(p->X, group_top) == NULL)
|| (bn_wexpand(p->Y, group_top) == NULL)
|| (bn_wexpand(p->Z, group_top) == NULL)) {
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
goto err;
}
/*-
* Apply coordinate blinding for EC_POINT.
@@ -220,19 +268,19 @@ static int ec_mul_consttime(const EC_GROUP *group, EC_POINT *r,
* success or if coordinate blinding is not implemented for this
* group.
*/
if (!ec_point_blind_coordinates(group, s, ctx))
if (!ec_point_blind_coordinates(group, p, ctx)) {
ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_POINT_COORDINATES_BLIND_FAILURE);
goto err;
}
/* Initialize the Montgomery ladder */
if (!ec_point_ladder_pre(group, r, s, p, ctx)) {
ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_LADDER_PRE_FAILURE);
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;
pbit = 1;
#define EC_POINT_CSWAP(c, a, b, w, t) do { \
BN_consttime_swap(c, (a)->X, (b)->X, w); \
@@ -304,10 +352,12 @@ static int ec_mul_consttime(const EC_GROUP *group, EC_POINT *r,
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))
/* Perform a single step of the Montgomery ladder */
if (!ec_point_ladder_step(group, r, s, p, ctx)) {
ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_LADDER_STEP_FAILURE);
goto err;
}
/*
* pbit logic merges this cswap with that of the
* next iteration
@@ -318,12 +368,18 @@ static int ec_mul_consttime(const EC_GROUP *group, EC_POINT *r,
EC_POINT_CSWAP(pbit, r, s, group_top, Z_is_one);
#undef EC_POINT_CSWAP
/* Finalize ladder (and recover full point coordinates) */
if (!ec_point_ladder_post(group, r, s, p, ctx)) {
ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_LADDER_POST_FAILURE);
goto err;
}
ret = 1;
err:
EC_POINT_free(p);
EC_POINT_free(s);
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
return ret;
}
@@ -355,7 +411,6 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
BN_CTX *ctx)
{
BN_CTX *new_ctx = NULL;
const EC_POINT *generator = NULL;
EC_POINT *tmp = NULL;
size_t totalnum;
@@ -380,56 +435,35 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
* precomputation is not available */
int ret = 0;
if (!ec_point_is_compat(r, group)) {
ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
if ((scalar == NULL) && (num == 0)) {
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.
* Handle the common cases where the scalar is secret, enforcing a
* scalar multiplication implementation based on a Montgomery ladder,
* with various timing attack defenses.
*/
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.
* 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 ladder version.
*/
return ec_mul_consttime(group, r, scalar, NULL, ctx);
return ec_scalar_mul_ladder(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.
* In this case we want to compute scalar * VariablePoint: 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 ladder version.
*/
return ec_mul_consttime(group, r, scalars[0], points[0], ctx);
return ec_scalar_mul_ladder(group, r, scalars[0], points[0], ctx);
}
}
for (i = 0; i < num; i++) {
if (!ec_point_is_compat(points[i], group)) {
ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
}
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
goto err;
}
if (scalar != NULL) {
generator = EC_GROUP_get0_generator(group);
if (generator == NULL) {
@@ -736,7 +770,6 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
ret = 1;
err:
BN_CTX_free(new_ctx);
EC_POINT_free(tmp);
OPENSSL_free(wsize);
OPENSSL_free(wNAF_len);
+37 -94
View File
@@ -10,9 +10,8 @@
#include <string.h>
#include <openssl/err.h>
#include <openssl/obj_mac.h>
#include <openssl/bn.h>
#include <openssl/rand.h>
#include <openssl/ec.h>
#include "internal/bn_int.h"
#include "ec_lcl.h"
int ossl_ecdsa_sign(int type, const unsigned char *dgst, int dlen,
@@ -53,13 +52,12 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
return 0;
}
if (ctx_in == NULL) {
if ((ctx = ctx_in) == NULL) {
if ((ctx = BN_CTX_new()) == NULL) {
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
return 0;
}
} else
ctx = ctx_in;
}
k = BN_new(); /* this value is later returned in *kinvp */
r = BN_new(); /* this value is later returned in *rp */
@@ -73,10 +71,6 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
goto err;
}
order = EC_GROUP_get0_order(group);
if (order == NULL) {
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
goto err;
}
/* Preallocate space */
order_bits = BN_num_bits(order);
@@ -87,23 +81,23 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
do {
/* get random k */
do
do {
if (dgst != NULL) {
if (!BN_generate_dsa_nonce
(k, order, EC_KEY_get0_private_key(eckey), dgst, dlen,
ctx)) {
if (!BN_generate_dsa_nonce(k, order,
EC_KEY_get0_private_key(eckey),
dgst, dlen, ctx)) {
ECerr(EC_F_ECDSA_SIGN_SETUP,
EC_R_RANDOM_NUMBER_GENERATION_FAILED);
EC_R_RANDOM_NUMBER_GENERATION_FAILED);
goto err;
}
} else {
if (!BN_priv_rand_range(k, order)) {
ECerr(EC_F_ECDSA_SIGN_SETUP,
EC_R_RANDOM_NUMBER_GENERATION_FAILED);
EC_R_RANDOM_NUMBER_GENERATION_FAILED);
goto err;
}
}
while (BN_is_zero(k));
} while (BN_is_zero(k));
/* compute r the x-coordinate of generator * k */
if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) {
@@ -112,18 +106,16 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
}
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
NID_X9_62_prime_field) {
if (!EC_POINT_get_affine_coordinates_GFp
(group, tmp_point, X, NULL, ctx)) {
if (!EC_POINT_get_affine_coordinates_GFp(group, tmp_point, X,
NULL, ctx)) {
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
goto err;
}
}
#ifndef OPENSSL_NO_EC2M
else { /* NID_X9_62_characteristic_two_field */
if (!EC_POINT_get_affine_coordinates_GF2m(group,
tmp_point, X, NULL,
ctx)) {
if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp_point, X,
NULL, ctx)) {
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
goto err;
}
@@ -133,8 +125,7 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
goto err;
}
}
while (BN_is_zero(r));
} while (BN_is_zero(r));
/* compute the inverse of k */
if (!ec_group_do_inverse_ord(group, k, k, ctx)) {
@@ -172,8 +163,7 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
EC_KEY *eckey)
{
int ok = 0, i;
BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL, *blind = NULL;
BIGNUM *blindm = NULL;
BIGNUM *kinv = NULL, *s, *m = NULL;
const BIGNUM *order, *ckinv;
BN_CTX *ctx = NULL;
const EC_GROUP *group;
@@ -206,27 +196,13 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
}
s = ret->s;
ctx = BN_CTX_secure_new();
if (ctx == NULL) {
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
goto err;
}
BN_CTX_start(ctx);
tmp = BN_CTX_get(ctx);
m = BN_CTX_get(ctx);
blind = BN_CTX_get(ctx);
blindm = BN_CTX_get(ctx);
if (blindm == NULL) {
if ((ctx = BN_CTX_new()) == NULL
|| (m = BN_new()) == NULL) {
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
goto err;
}
order = EC_GROUP_get0_order(group);
if (order == NULL) {
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_EC_LIB);
goto err;
}
i = BN_num_bits(order);
/*
* Need to truncate digest if it is too long: first truncate whole bytes.
@@ -237,7 +213,7 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
goto err;
}
/* If still too long truncate remaining bits with a shift */
/* If still too long, truncate remaining bits with a shift */
if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
goto err;
@@ -258,59 +234,27 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
}
/*
* The normal signature calculation is:
*
* s := k^-1 * (m + r * priv_key) mod order
*
* We will blind this to protect against side channel attacks
*
* s := blind^-1 * k^-1 * (blind * m + blind * r * priv_key) mod order
* With only one multiplicant being in Montgomery domain
* multiplication yields real result without post-conversion.
* Also note that all operations but last are performed with
* zero-padded vectors. Last operation, BN_mod_mul_montgomery
* below, returns user-visible value with removed zero padding.
*/
/* Generate a blinding value */
do {
if (!BN_priv_rand(blind, BN_num_bits(order) - 1,
BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY))
goto err;
} while (BN_is_zero(blind));
BN_set_flags(blind, BN_FLG_CONSTTIME);
BN_set_flags(blindm, BN_FLG_CONSTTIME);
BN_set_flags(tmp, BN_FLG_CONSTTIME);
/* tmp := blind * priv_key * r mod order */
if (!BN_mod_mul(tmp, blind, priv_key, order, ctx)) {
if (!bn_to_mont_fixed_top(s, ret->r, group->mont_data, ctx)
|| !bn_mul_mont_fixed_top(s, s, priv_key, group->mont_data, ctx)) {
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
goto err;
}
if (!BN_mod_mul(tmp, tmp, ret->r, order, ctx)) {
if (!bn_mod_add_fixed_top(s, s, m, order)) {
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
goto err;
}
/* blindm := blind * m mod order */
if (!BN_mod_mul(blindm, blind, m, order, ctx)) {
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
goto err;
}
/* s : = (blind * priv_key * r) + (blind * m) mod order */
if (!BN_mod_add_quick(s, tmp, blindm, order)) {
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
goto err;
}
/* s := s * k^-1 mod order */
if (!BN_mod_mul(s, s, ckinv, order, ctx)) {
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
goto err;
}
/* s:= s * blind^-1 mod order */
if (BN_mod_inverse(blind, blind, order, ctx) == NULL) {
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
goto err;
}
if (!BN_mod_mul(s, s, blind, order, ctx)) {
/*
* |s| can still be larger than modulus, because |m| can be. In
* such case we count on Montgomery reduction to tie it up.
*/
if (!bn_to_mont_fixed_top(s, s, group->mont_data, ctx)
|| !BN_mod_mul_montgomery(s, s, ckinv, group->mont_data, ctx)) {
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
goto err;
}
@@ -324,11 +268,11 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, EC_R_NEED_NEW_SETUP_VALUES);
goto err;
}
} else
} else {
/* s != 0 => we have a valid signature */
break;
}
while (1);
}
} while (1);
ok = 1;
err:
@@ -336,9 +280,8 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
ECDSA_SIG_free(ret);
ret = NULL;
}
if (ctx != NULL)
BN_CTX_end(ctx);
BN_CTX_free(ctx);
BN_clear_free(m);
BN_clear_free(kinv);
return ret;
}
+4 -1
View File
@@ -63,7 +63,10 @@ const EC_METHOD *EC_GFp_mont_method(void)
0, /* keyfinish */
ecdh_simple_compute_key,
0, /* field_inverse_mod_ord */
ec_GFp_simple_blind_coordinates
ec_GFp_simple_blind_coordinates,
0, /* ladder_pre */
0, /* ladder_step */
0 /* ladder_post */
};
return &ret;
+4 -1
View File
@@ -65,7 +65,10 @@ const EC_METHOD *EC_GFp_nist_method(void)
0, /* keyfinish */
ecdh_simple_compute_key,
0, /* field_inverse_mod_ord */
ec_GFp_simple_blind_coordinates
ec_GFp_simple_blind_coordinates,
0, /* ladder_pre */
0, /* ladder_step */
0 /* ladder_post */
};
return &ret;
+4 -6
View File
@@ -292,7 +292,10 @@ const EC_METHOD *EC_GFp_nistp224_method(void)
0, /* keyfinish */
ecdh_simple_compute_key,
0, /* field_inverse_mod_ord */
0 /* blind_coordinates */
0, /* blind_coordinates */
0, /* ladder_pre */
0, /* ladder_step */
0 /* ladder_post */
};
return &ret;
@@ -1393,7 +1396,6 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
int j;
unsigned i;
int mixed = 0;
BN_CTX *new_ctx = NULL;
BIGNUM *x, *y, *z, *tmp_scalar;
felem_bytearray g_secret;
felem_bytearray *secrets = NULL;
@@ -1410,9 +1412,6 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
const EC_POINT *p = NULL;
const BIGNUM *p_scalar = NULL;
if (ctx == NULL)
if ((ctx = new_ctx = BN_CTX_new()) == NULL)
return 0;
BN_CTX_start(ctx);
x = BN_CTX_get(ctx);
y = BN_CTX_get(ctx);
@@ -1575,7 +1574,6 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
err:
BN_CTX_end(ctx);
EC_POINT_free(generator);
BN_CTX_free(new_ctx);
OPENSSL_free(secrets);
OPENSSL_free(pre_comp);
OPENSSL_free(tmp_felems);
+6 -6
View File
@@ -1821,7 +1821,12 @@ const EC_METHOD *EC_GFp_nistp256_method(void)
ec_key_simple_generate_public_key,
0, /* keycopy */
0, /* keyfinish */
ecdh_simple_compute_key
ecdh_simple_compute_key,
0, /* field_inverse_mod_ord */
0, /* blind_coordinates */
0, /* ladder_pre */
0, /* ladder_step */
0 /* ladder_post */
};
return &ret;
@@ -2013,7 +2018,6 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
int ret = 0;
int j;
int mixed = 0;
BN_CTX *new_ctx = NULL;
BIGNUM *x, *y, *z, *tmp_scalar;
felem_bytearray g_secret;
felem_bytearray *secrets = NULL;
@@ -2031,9 +2035,6 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
const EC_POINT *p = NULL;
const BIGNUM *p_scalar = NULL;
if (ctx == NULL)
if ((ctx = new_ctx = BN_CTX_new()) == NULL)
return 0;
BN_CTX_start(ctx);
x = BN_CTX_get(ctx);
y = BN_CTX_get(ctx);
@@ -2202,7 +2203,6 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
err:
BN_CTX_end(ctx);
EC_POINT_free(generator);
BN_CTX_free(new_ctx);
OPENSSL_free(secrets);
OPENSSL_free(pre_comp);
OPENSSL_free(tmp_smallfelems);
+4 -6
View File
@@ -1660,7 +1660,10 @@ const EC_METHOD *EC_GFp_nistp521_method(void)
0, /* keyfinish */
ecdh_simple_compute_key,
0, /* field_inverse_mod_ord */
0 /* blind_coordinates */
0, /* blind_coordinates */
0, /* ladder_pre */
0, /* ladder_step */
0 /* ladder_post */
};
return &ret;
@@ -1852,7 +1855,6 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
int ret = 0;
int j;
int mixed = 0;
BN_CTX *new_ctx = NULL;
BIGNUM *x, *y, *z, *tmp_scalar;
felem_bytearray g_secret;
felem_bytearray *secrets = NULL;
@@ -1869,9 +1871,6 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
const EC_POINT *p = NULL;
const BIGNUM *p_scalar = NULL;
if (ctx == NULL)
if ((ctx = new_ctx = BN_CTX_new()) == NULL)
return 0;
BN_CTX_start(ctx);
x = BN_CTX_get(ctx);
y = BN_CTX_get(ctx);
@@ -2038,7 +2037,6 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
err:
BN_CTX_end(ctx);
EC_POINT_free(generator);
BN_CTX_free(new_ctx);
OPENSSL_free(secrets);
OPENSSL_free(pre_comp);
OPENSSL_free(tmp_felems);
+4 -25
View File
@@ -1139,12 +1139,10 @@ __owur static int ecp_nistz256_points_mul(const EC_GROUP *group,
const BIGNUM *scalars[], BN_CTX *ctx)
{
int i = 0, ret = 0, no_precomp_for_generator = 0, p_is_infinity = 0;
size_t j;
unsigned char p_str[33] = { 0 };
const PRECOMP256_ROW *preComputedTable = NULL;
const NISTZ256_PRE_COMP *pre_comp = NULL;
const EC_POINT *generator = NULL;
BN_CTX *new_ctx = NULL;
const BIGNUM **new_scalars = NULL;
const EC_POINT **new_points = NULL;
unsigned int idx = 0;
@@ -1162,27 +1160,6 @@ __owur static int ecp_nistz256_points_mul(const EC_GROUP *group,
return 0;
}
if (!ec_point_is_compat(r, group)) {
ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
if ((scalar == NULL) && (num == 0))
return EC_POINT_set_to_infinity(group, r);
for (j = 0; j < num; j++) {
if (!ec_point_is_compat(points[j], group)) {
ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
}
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
goto err;
}
BN_CTX_start(ctx);
if (scalar) {
@@ -1380,7 +1357,6 @@ __owur static int ecp_nistz256_points_mul(const EC_GROUP *group,
err:
if (ctx)
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
OPENSSL_free(new_points);
OPENSSL_free(new_scalars);
return ret;
@@ -1731,7 +1707,10 @@ const EC_METHOD *EC_GFp_nistz256_method(void)
0, /* keyfinish */
ecdh_simple_compute_key,
ecp_nistz256_inv_mod_ord, /* can be #define-d NULL */
0 /* blind_coordinates */
0, /* blind_coordinates */
0, /* ladder_pre */
0, /* ladder_step */
0 /* ladder_post */
};
return &ret;
+4 -2
View File
@@ -64,7 +64,10 @@ const EC_METHOD *EC_GFp_simple_method(void)
0, /* keyfinish */
ecdh_simple_compute_key,
0, /* field_inverse_mod_ord */
ec_GFp_simple_blind_coordinates
ec_GFp_simple_blind_coordinates,
0, /* ladder_pre */
0, /* ladder_step */
0 /* ladder_post */
};
return &ret;
@@ -1418,4 +1421,3 @@ int ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p,
BN_CTX_end(ctx);
return ret;
}
+5 -5
View File
@@ -361,20 +361,20 @@ static const struct digest_data_st {
#endif
{ NID_sha1, 20, CRYPTO_SHA1 },
#ifndef OPENSSL_NO_RMD160
# if !defined(CHECK_BSD_STYLE_MACROS) && defined(CRYPTO_RIPEMD160)
# if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_RIPEMD160)
{ NID_ripemd160, 20, CRYPTO_RIPEMD160 },
# endif
#endif
#if !defined(CHECK_BSD_STYLE_MACROS) && defined(CRYPTO_SHA2_224)
#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_224)
{ NID_sha224, 224 / 8, CRYPTO_SHA2_224 },
#endif
#if !defined(CHECK_BSD_STYLE_MACROS) && defined(CRYPTO_SHA2_256)
#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_256)
{ NID_sha256, 256 / 8, CRYPTO_SHA2_256 },
#endif
#if !defined(CHECK_BSD_STYLE_MACROS) && defined(CRYPTO_SHA2_384)
#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_384)
{ NID_sha384, 384 / 8, CRYPTO_SHA2_384 },
#endif
#if !defined(CHECK_BSD_STYLE_MACROS) && defined(CRYPTO_SHA2_512)
#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_512)
{ NID_sha512, 512 / 8, CRYPTO_SHA2_512 },
#endif
};
+11
View File
@@ -521,8 +521,11 @@ EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY:208:ec_GF2m_montgomery_point_multiply
EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT:159:\
ec_GF2m_simple_group_check_discriminant
EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE:195:ec_GF2m_simple_group_set_curve
EC_F_EC_GF2M_SIMPLE_LADDER_POST:285:ec_GF2m_simple_ladder_post
EC_F_EC_GF2M_SIMPLE_LADDER_PRE:288:ec_GF2m_simple_ladder_pre
EC_F_EC_GF2M_SIMPLE_OCT2POINT:160:ec_GF2m_simple_oct2point
EC_F_EC_GF2M_SIMPLE_POINT2OCT:161:ec_GF2m_simple_point2oct
EC_F_EC_GF2M_SIMPLE_POINTS_MUL:289:ec_GF2m_simple_points_mul
EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES:162:\
ec_GF2m_simple_point_get_affine_coordinates
EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES:163:\
@@ -601,6 +604,7 @@ EC_F_EC_KEY_SIMPLE_PRIV2OCT:260:ec_key_simple_priv2oct
EC_F_EC_PKEY_CHECK:273:ec_pkey_check
EC_F_EC_PKEY_PARAM_CHECK:274:ec_pkey_param_check
EC_F_EC_POINTS_MAKE_AFFINE:136:EC_POINTs_make_affine
EC_F_EC_POINTS_MUL:290:EC_POINTs_mul
EC_F_EC_POINT_ADD:112:EC_POINT_add
EC_F_EC_POINT_BN2POINT:280:EC_POINT_bn2point
EC_F_EC_POINT_CMP:113:EC_POINT_cmp
@@ -630,6 +634,7 @@ EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP:126:\
EC_POINT_set_Jprojective_coordinates_GFp
EC_F_EC_POINT_SET_TO_INFINITY:127:EC_POINT_set_to_infinity
EC_F_EC_PRE_COMP_NEW:196:ec_pre_comp_new
EC_F_EC_SCALAR_MUL_LADDER:284:ec_scalar_mul_ladder
EC_F_EC_WNAF_MUL:187:ec_wNAF_mul
EC_F_EC_WNAF_PRECOMPUTE_MULT:188:ec_wNAF_precompute_mult
EC_F_I2D_ECPARAMETERS:190:i2d_ECParameters
@@ -2012,6 +2017,7 @@ CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE:106:no conf or environment variable
CONF_R_NO_SECTION:107:no section
CONF_R_NO_SUCH_FILE:114:no such file
CONF_R_NO_VALUE:108:no value
CONF_R_NUMBER_TOO_LARGE:121:number too large
CONF_R_RECURSIVE_DIRECTORY_INCLUDE:111:recursive directory include
CONF_R_SSL_COMMAND_SECTION_EMPTY:117:ssl command section empty
CONF_R_SSL_COMMAND_SECTION_NOT_FOUND:118:ssl command section not found
@@ -2129,6 +2135,9 @@ EC_R_INVALID_PRIVATE_KEY:123:invalid private key
EC_R_INVALID_TRINOMIAL_BASIS:137:invalid trinomial basis
EC_R_KDF_PARAMETER_ERROR:148:kdf parameter error
EC_R_KEYS_NOT_SET:140:keys not set
EC_R_LADDER_POST_FAILURE:136:ladder post failure
EC_R_LADDER_PRE_FAILURE:153:ladder pre failure
EC_R_LADDER_STEP_FAILURE:162:ladder step failure
EC_R_MISSING_PARAMETERS:124:missing parameters
EC_R_MISSING_PRIVATE_KEY:125:missing private key
EC_R_NEED_NEW_SETUP_VALUES:157:need new setup values
@@ -2143,12 +2152,14 @@ EC_R_PEER_KEY_ERROR:149:peer key error
EC_R_PKPARAMETERS2GROUP_FAILURE:127:pkparameters2group failure
EC_R_POINT_ARITHMETIC_FAILURE:155:point arithmetic failure
EC_R_POINT_AT_INFINITY:106:point at infinity
EC_R_POINT_COORDINATES_BLIND_FAILURE:163:point coordinates blind failure
EC_R_POINT_IS_NOT_ON_CURVE:107:point is not on curve
EC_R_RANDOM_NUMBER_GENERATION_FAILED:158:random number generation failed
EC_R_SHARED_INFO_ERROR:150:shared info error
EC_R_SLOT_FULL:108:slot full
EC_R_UNDEFINED_GENERATOR:113:undefined generator
EC_R_UNDEFINED_ORDER:128:undefined order
EC_R_UNKNOWN_COFACTOR:164:unknown cofactor
EC_R_UNKNOWN_GROUP:129:unknown group
EC_R_UNKNOWN_ORDER:114:unknown order
EC_R_UNSUPPORTED_FIELD:131:unsupported field
+21 -19
View File
@@ -144,6 +144,22 @@ void AES_xts_decrypt(const unsigned char *inp, unsigned char *out, size_t len,
const unsigned char iv[16]);
#endif
/* increment counter (64-bit int) by 1 */
static void ctr64_inc(unsigned char *counter)
{
int n = 8;
unsigned char c;
do {
--n;
c = counter[n];
++c;
counter[n] = c;
if (c)
return;
} while (n);
}
#if defined(OPENSSL_CPUID_OBJ) && (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC))
# include "ppc_arch.h"
# ifdef VPAES_ASM
@@ -1654,7 +1670,7 @@ static int s390x_aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
* Invocation field will be at least 8 bytes in size and so no need
* to check wrap around or increment more than last 8 bytes.
*/
(*(unsigned long long *)(gctx->iv + gctx->ivlen - 8))++;
ctr64_inc(gctx->iv + gctx->ivlen - 8);
gctx->iv_set = 1;
return 1;
@@ -2291,7 +2307,7 @@ static int s390x_aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
memcpy(buf, ptr, arg);
cctx->aes.ccm.tls_aad_len = arg;
len = *(uint16_t *)(buf + arg - 2);
len = buf[arg - 2] << 8 | buf[arg - 1];
if (len < EVP_CCM_TLS_EXPLICIT_IV_LEN)
return 0;
@@ -2307,7 +2323,9 @@ static int s390x_aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
len -= cctx->aes.ccm.m;
}
*(uint16_t *)(buf + arg - 2) = len;
buf[arg - 2] = len >> 8;
buf[arg - 1] = len & 0xff;
/* Extra padding: tag appended to record. */
return cctx->aes.ccm.m;
@@ -2791,22 +2809,6 @@ static int aes_gcm_cleanup(EVP_CIPHER_CTX *c)
return 1;
}
/* increment counter (64-bit int) by 1 */
static void ctr64_inc(unsigned char *counter)
{
int n = 8;
unsigned char c;
do {
--n;
c = counter[n];
++c;
counter[n] = c;
if (c)
return;
} while (n);
}
static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
{
EVP_AES_GCM_CTX *gctx = EVP_C_DATA(EVP_AES_GCM_CTX,c);
+14
View File
@@ -60,4 +60,18 @@ void bn_set_static_words(BIGNUM *a, BN_ULONG *words, int size);
*/
int bn_set_words(BIGNUM *a, BN_ULONG *words, int num_words);
/*
* Some BIGNUM functions assume most significant limb to be non-zero, which
* is customarily arranged by bn_correct_top. Output from below functions
* is not processed with bn_correct_top, and for this reason it may not be
* returned out of public API. It may only be passed internally into other
* functions known to support non-minimal or zero-padded BIGNUMs.
*/
int bn_mul_mont_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
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);
#endif
+3
View File
@@ -15,6 +15,9 @@
# ifndef OPENSSL_NO_SM2
# ifdef __cplusplus
extern "C"
# endif
int ERR_load_SM2_strings(void);
/*
+6 -16
View File
@@ -42,22 +42,13 @@ static u32 ocb_ntz(u64 n)
static void ocb_block_lshift(const unsigned char *in, size_t shift,
unsigned char *out)
{
unsigned char shift_mask;
int i;
unsigned char mask[15];
unsigned char carry = 0, carry_next;
shift_mask = 0xff;
shift_mask <<= (8 - shift);
for (i = 15; i >= 0; i--) {
if (i > 0) {
mask[i - 1] = in[i] & shift_mask;
mask[i - 1] >>= 8 - shift;
}
out[i] = in[i] << shift;
if (i != 15) {
out[i] ^= mask[i];
}
carry_next = in[i] >> (8 - shift);
out[i] = (in[i] << shift) | carry;
carry = carry_next;
}
}
@@ -74,7 +65,7 @@ static void ocb_double(OCB_BLOCK *in, OCB_BLOCK *out)
*/
mask = in->c[0] & 0x80;
mask >>= 7;
mask *= 135;
mask = (0 - mask) & 0x87;
ocb_block_lshift(in->c, 1, out->c);
@@ -119,8 +110,7 @@ static OCB_BLOCK *ocb_lookup_l(OCB128_CONTEXT *ctx, size_t idx)
* the index.
*/
ctx->max_l_index += (idx - ctx->max_l_index + 4) & ~3;
tmp_ptr =
OPENSSL_realloc(ctx->l, ctx->max_l_index * sizeof(OCB_BLOCK));
tmp_ptr = OPENSSL_realloc(ctx->l, ctx->max_l_index * sizeof(OCB_BLOCK));
if (tmp_ptr == NULL) /* prevent ctx->l from being clobbered */
return NULL;
ctx->l = tmp_ptr;
+38 -39
View File
@@ -3753,6 +3753,44 @@ poly1305_emit_base2_44:
.size poly1305_emit_base2_44,.-poly1305_emit_base2_44
___
} } }
$code.=<<___;
.align 64
.Lconst:
.Lmask24:
.long 0x0ffffff,0,0x0ffffff,0,0x0ffffff,0,0x0ffffff,0
.L129:
.long `1<<24`,0,`1<<24`,0,`1<<24`,0,`1<<24`,0
.Lmask26:
.long 0x3ffffff,0,0x3ffffff,0,0x3ffffff,0,0x3ffffff,0
.Lpermd_avx2:
.long 2,2,2,3,2,0,2,1
.Lpermd_avx512:
.long 0,0,0,1, 0,2,0,3, 0,4,0,5, 0,6,0,7
.L2_44_inp_permd:
.long 0,1,1,2,2,3,7,7
.L2_44_inp_shift:
.quad 0,12,24,64
.L2_44_mask:
.quad 0xfffffffffff,0xfffffffffff,0x3ffffffffff,0xffffffffffffffff
.L2_44_shift_rgt:
.quad 44,44,42,64
.L2_44_shift_lft:
.quad 8,8,10,64
.align 64
.Lx_mask44:
.quad 0xfffffffffff,0xfffffffffff,0xfffffffffff,0xfffffffffff
.quad 0xfffffffffff,0xfffffffffff,0xfffffffffff,0xfffffffffff
.Lx_mask42:
.quad 0x3ffffffffff,0x3ffffffffff,0x3ffffffffff,0x3ffffffffff
.quad 0x3ffffffffff,0x3ffffffffff,0x3ffffffffff,0x3ffffffffff
___
}
$code.=<<___;
.asciz "Poly1305 for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
.align 16
___
{ # chacha20-poly1305 helpers
my ($out,$inp,$otp,$len)=$win64 ? ("%rcx","%rdx","%r8", "%r9") : # Win64 order
@@ -3857,45 +3895,6 @@ xor128_decrypt_n_pad:
.size xor128_decrypt_n_pad,.-xor128_decrypt_n_pad
___
}
$code.=<<___;
.align 64
.Lconst:
.Lmask24:
.long 0x0ffffff,0,0x0ffffff,0,0x0ffffff,0,0x0ffffff,0
.L129:
.long `1<<24`,0,`1<<24`,0,`1<<24`,0,`1<<24`,0
.Lmask26:
.long 0x3ffffff,0,0x3ffffff,0,0x3ffffff,0,0x3ffffff,0
.Lpermd_avx2:
.long 2,2,2,3,2,0,2,1
.Lpermd_avx512:
.long 0,0,0,1, 0,2,0,3, 0,4,0,5, 0,6,0,7
.L2_44_inp_permd:
.long 0,1,1,2,2,3,7,7
.L2_44_inp_shift:
.quad 0,12,24,64
.L2_44_mask:
.quad 0xfffffffffff,0xfffffffffff,0x3ffffffffff,0xffffffffffffffff
.L2_44_shift_rgt:
.quad 44,44,42,64
.L2_44_shift_lft:
.quad 8,8,10,64
.align 64
.Lx_mask44:
.quad 0xfffffffffff,0xfffffffffff,0xfffffffffff,0xfffffffffff
.quad 0xfffffffffff,0xfffffffffff,0xfffffffffff,0xfffffffffff
.Lx_mask42:
.quad 0x3ffffffffff,0x3ffffffffff,0x3ffffffffff,0x3ffffffffff
.quad 0x3ffffffffff,0x3ffffffffff,0x3ffffffffff,0x3ffffffffff
___
}
$code.=<<___;
.asciz "Poly1305 for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
.align 16
___
# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
# CONTEXT *context,DISPATCHER_CONTEXT *disp)
+23 -15
View File
@@ -150,32 +150,40 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
dblen = num - mdlen - 1;
db = OPENSSL_malloc(dblen);
em = OPENSSL_malloc(num);
if (db == NULL || em == NULL) {
if (db == NULL) {
RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE);
goto cleanup;
}
/*
* Always do this zero-padding copy (even when num == flen) to avoid
* leaking that information. The copy still leaks some side-channel
* information, but it's impossible to have a fixed memory access
* pattern since we can't read out of the bounds of |from|.
*
* TODO(emilia): Consider porting BN_bn2bin_padded from BoringSSL.
*/
memset(em, 0, num);
memcpy(em + num - flen, from, flen);
if (flen != num) {
em = OPENSSL_zalloc(num);
if (em == NULL) {
RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1,
ERR_R_MALLOC_FAILURE);
goto cleanup;
}
/*
* Caller is encouraged to pass zero-padded message created with
* BN_bn2binpad, but if it doesn't, we do this zero-padding copy
* to avoid leaking that information. The copy still leaks some
* side-channel information, but it's impossible to have a fixed
* memory access pattern since we can't read out of the bounds of
* |from|.
*/
memcpy(em + num - flen, from, flen);
from = em;
}
/*
* The first byte must be zero, however we must not leak if this is
* true. See James H. Manger, "A Chosen Ciphertext Attack on RSA
* Optimal Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001).
*/
good = constant_time_is_zero(em[0]);
good = constant_time_is_zero(from[0]);
maskedseed = em + 1;
maskeddb = em + 1 + mdlen;
maskedseed = from + 1;
maskeddb = from + 1 + mdlen;
if (PKCS1_MGF1(seed, mdlen, maskeddb, dblen, mgf1md))
goto cleanup;
+12 -26
View File
@@ -68,7 +68,7 @@ static int rsa_ossl_public_encrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
BIGNUM *f, *ret;
int i, j, k, num = 0, r = -1;
int i, num = 0, r = -1;
unsigned char *buf = NULL;
BN_CTX *ctx = NULL;
@@ -142,15 +142,10 @@ static int rsa_ossl_public_encrypt(int flen, const unsigned char *from,
goto err;
/*
* put in leading 0 bytes if the number is less than the length of the
* modulus
* BN_bn2binpad puts in leading 0 bytes if the number is less than
* the length of the modulus.
*/
j = BN_num_bytes(ret);
i = BN_bn2bin(ret, &(to[num - j]));
for (k = 0; k < (num - i); k++)
to[k] = 0;
r = num;
r = BN_bn2binpad(ret, to, num);
err:
if (ctx != NULL)
BN_CTX_end(ctx);
@@ -239,7 +234,7 @@ static int rsa_ossl_private_encrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
BIGNUM *f, *ret, *res;
int i, j, k, num = 0, r = -1;
int i, num = 0, r = -1;
unsigned char *buf = NULL;
BN_CTX *ctx = NULL;
int local_blinding = 0;
@@ -354,15 +349,10 @@ static int rsa_ossl_private_encrypt(int flen, const unsigned char *from,
}
/*
* put in leading 0 bytes if the number is less than the length of the
* modulus
* BN_bn2binpad puts in leading 0 bytes if the number is less than
* the length of the modulus.
*/
j = BN_num_bytes(res);
i = BN_bn2bin(res, &(to[num - j]));
for (k = 0; k < (num - i); k++)
to[k] = 0;
r = num;
r = BN_bn2binpad(res, to, num);
err:
if (ctx != NULL)
BN_CTX_end(ctx);
@@ -376,7 +366,6 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from,
{
BIGNUM *f, *ret;
int j, num = 0, r = -1;
unsigned char *p;
unsigned char *buf = NULL;
BN_CTX *ctx = NULL;
int local_blinding = 0;
@@ -472,8 +461,7 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from,
if (!rsa_blinding_invert(blinding, ret, unblind, ctx))
goto err;
p = buf;
j = BN_bn2bin(ret, p); /* j is only used with no-padding mode */
j = BN_bn2binpad(ret, buf, num);
switch (padding) {
case RSA_PKCS1_PADDING:
@@ -486,7 +474,7 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from,
r = RSA_padding_check_SSLv23(to, num, buf, j, num);
break;
case RSA_NO_PADDING:
r = RSA_padding_check_none(to, num, buf, j, num);
memcpy(to, buf, (r = j));
break;
default:
RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
@@ -509,7 +497,6 @@ static int rsa_ossl_public_decrypt(int flen, const unsigned char *from,
{
BIGNUM *f, *ret;
int i, num = 0, r = -1;
unsigned char *p;
unsigned char *buf = NULL;
BN_CTX *ctx = NULL;
@@ -574,8 +561,7 @@ static int rsa_ossl_public_decrypt(int flen, const unsigned char *from,
if (!BN_sub(ret, rsa->n, ret))
goto err;
p = buf;
i = BN_bn2bin(ret, p);
i = BN_bn2binpad(ret, buf, num);
switch (padding) {
case RSA_PKCS1_PADDING:
@@ -585,7 +571,7 @@ static int rsa_ossl_public_decrypt(int flen, const unsigned char *from,
r = RSA_padding_check_X931(to, num, buf, i, num);
break;
case RSA_NO_PADDING:
r = RSA_padding_check_none(to, num, buf, i, num);
memcpy(to, buf, (r = i));
break;
default:
RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
+21 -18
View File
@@ -175,27 +175,30 @@ int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen,
if (num < 11)
goto err;
em = OPENSSL_zalloc(num);
if (em == NULL) {
RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, ERR_R_MALLOC_FAILURE);
return -1;
if (flen != num) {
em = OPENSSL_zalloc(num);
if (em == NULL) {
RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, ERR_R_MALLOC_FAILURE);
return -1;
}
/*
* Caller is encouraged to pass zero-padded message created with
* BN_bn2binpad, but if it doesn't, we do this zero-padding copy
* to avoid leaking that information. The copy still leaks some
* side-channel information, but it's impossible to have a fixed
* memory access pattern since we can't read out of the bounds of
* |from|.
*/
memcpy(em + num - flen, from, flen);
from = em;
}
/*
* Always do this zero-padding copy (even when num == flen) to avoid
* leaking that information. The copy still leaks some side-channel
* information, but it's impossible to have a fixed memory access
* pattern since we can't read out of the bounds of |from|.
*
* TODO(emilia): Consider porting BN_bn2bin_padded from BoringSSL.
*/
memcpy(em + num - flen, from, flen);
good = constant_time_is_zero(em[0]);
good &= constant_time_eq(em[1], 2);
good = constant_time_is_zero(from[0]);
good &= constant_time_eq(from[1], 2);
found_zero_byte = 0;
for (i = 2; i < num; i++) {
unsigned int equals0 = constant_time_is_zero(em[i]);
unsigned int equals0 = constant_time_is_zero(from[i]);
zero_index =
constant_time_select_int(~found_zero_byte & equals0, i,
zero_index);
@@ -203,7 +206,7 @@ int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen,
}
/*
* PS must be at least 8 bytes long, and it starts two bytes into |em|.
* PS must be at least 8 bytes long, and it starts two bytes into |from|.
* If we never found a 0-byte, then |zero_index| is 0 and the check
* also fails.
*/
@@ -232,7 +235,7 @@ int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen,
goto err;
}
memcpy(to, em + msg_index, mlen);
memcpy(to, from + msg_index, mlen);
err:
OPENSSL_clear_free(em, num);
+8
View File
@@ -63,6 +63,14 @@ int RSA_padding_check_SSLv23(unsigned char *to, int tlen,
RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_DATA_TOO_SMALL);
return -1;
}
/* Accept even zero-padded input */
if (flen == num) {
if (*(p++) != 0) {
RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_BLOCK_TYPE_IS_NOT_02);
return -1;
}
flen--;
}
if ((num != (flen + 1)) || (*(p++) != 02)) {
RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_BLOCK_TYPE_IS_NOT_02);
return -1;