Commit Graph

340 Commits

Author SHA1 Message Date
Adam Langley
0c9ac2e7bf Drop FULL_UNROLL code in aes.c.
We've never defined this so this code has always been dead.

Change-Id: Ibcc4095bf812c7e1866c5f39968789606f0995ae
Reviewed-on: https://boringssl-review.googlesource.com/28024
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2018-05-03 16:10:14 +00:00
David Benjamin
8e75ae4880 Add a Wycheproof driver for AES-CBC.
Change-Id: I782ea51e1db8d05f552832a7c6910954fa2dda5f
Reviewed-on: https://boringssl-review.googlesource.com/27924
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2018-05-02 19:41:48 +00:00
Matthew Braithwaite
58d6fc48cc Add missing #include of <openssl/err.h>.
Change-Id: Ib2ce220e31a4f808999934197a7f43b8723131e8
Reviewed-on: https://boringssl-review.googlesource.com/27884
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2018-05-01 01:00:44 +00:00
David Benjamin
8370fb6b41 Implement constant-time generic multiplication.
This is slower, but constant-time. It intentionally omits the signed
digit optimization because we cannot be sure the doubling case will be
unreachable for all curves. This is a fallback generic implementation
for curves which we must support for compatibility but which are not
common or important enough to justify curve-specific work.

Before:
Did 814 ECDH P-384 operations in 1085384us (750.0 ops/sec)
Did 1430 ECDSA P-384 signing operations in 1081988us (1321.6 ops/sec)
Did 308 ECDH P-521 operations in 1057741us (291.2 ops/sec)
Did 539 ECDSA P-521 signing operations in 1049797us (513.4 ops/sec)

After:
Did 715 ECDH P-384 operations in 1080161us (661.9 ops/sec)
Did 1188 ECDSA P-384 verify operations in 1069567us (1110.7 ops/sec)
Did 275 ECDH P-521 operations in 1060503us (259.3 ops/sec)
Did 506 ECDSA P-521 signing operations in 1084739us (466.5 ops/sec)

But we're still faster than the old BIGNUM implementation. EC_FELEM
more than paid for both the loss of points_make_affine and this CL.

Bug: 239
Change-Id: I65d71a731aad16b523928ee47618822d503ea704
Reviewed-on: https://boringssl-review.googlesource.com/27708
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2018-04-27 20:11:29 +00:00
David Benjamin
8b0dc7a720 Simplify ec_wNAF_mul table sizing.
w=4 appears to be the correct answer for P-224 through P-521. There's
nominally some optimizations in here for 70- and 20-bit primes, but
that's absurd.

Change-Id: Id4ccec779b17e375e9258c1784e46d7d3651c59a
Reviewed-on: https://boringssl-review.googlesource.com/27707
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2018-04-27 19:49:08 +00:00
David Benjamin
041dd68cec Clear mallocs in ec_wNAF_mul.
EC_POINT is split into the existing public EC_POINT (where the caller is
sanity-checked about group mismatches) and the low-level EC_RAW_POINT
(which, like EC_FELEM and EC_SCALAR, assume that is your problem and is
a plain old struct). Having both EC_POINT and EC_RAW_POINT is a little
silly, but we're going to want different type signatures for functions
which return void anyway (my plan is to lift a non-BIGNUM
get_affine_coordinates up through the ECDSA and ECDH code), so I think
it's fine.

This wasn't strictly necessary, but wnaf.c is a lot tidier now. Perf is
a wash; once we get up to this layer, it's only 8 entries in the table
so not particularly interesting.

Bug: 239
Change-Id: I8ace749393d359f42649a5bb0734597bb7c07a2e
Reviewed-on: https://boringssl-review.googlesource.com/27706
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2018-04-27 19:44:58 +00:00
David Benjamin
e14e4a7ee3 Remove ec_compute_wNAF's failure cases.
Replace them with asserts and better justify why each of the internal
cases are not reachable. Also change the loop to count up to bits+1 so
it is obvious there is no memory error. (The previous loop shape made
more sense when ec_compute_wNAF would return a variable length
schedule.)

Change-Id: I9c7df6abac4290b7a3e545e3d4aa1462108e239e
Reviewed-on: https://boringssl-review.googlesource.com/27705
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2018-04-27 19:24:58 +00:00
Adam Langley
cece32610b Add SHA256_TransformBlocks.
Rather than expose a (potentially) assembly function directly, wrap it
in a C function to make visibility control easier.

Change-Id: I4a2dfeb8999ff021b2e10fbc54850eeadabbefff
Reviewed-on: https://boringssl-review.googlesource.com/27724
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2018-04-25 17:51:50 +00:00
David Benjamin
ec4f0ddafc EC_GROUP_dup cannot fail.
We've since ref-counted it.

Change-Id: I5589e79f5bbba35b02ae659c7aa6ac76ba0082a3
Reviewed-on: https://boringssl-review.googlesource.com/27669
Reviewed-by: Adam Langley <agl@google.com>
2018-04-25 16:43:19 +00:00
David Benjamin
32e0d10069 Add EC_FELEM for EC_POINTs and related temporaries.
This introduces EC_FELEM, which is analogous to EC_SCALAR. It is used
for EC_POINT's representation in the generic EC_METHOD, as well as
random operations on tuned EC_METHODs that still are implemented
genericly.

Unlike EC_SCALAR, EC_FELEM's exact representation is awkwardly specific
to the EC_METHOD, analogous to how the old values were BIGNUMs but may
or may not have been in Montgomery form. This is kind of a nuisance, but
no more than before. (If p224-64.c were easily convertable to Montgomery
form, we could say |EC_FELEM| is always in Montgomery form. If we
exposed the internal add and double implementations in each of the
curves, we could give |EC_POINT| an |EC_METHOD|-specific representation
and |EC_FELEM| is purely a |EC_GFp_mont_method| type. I'll leave this
for later.)

The generic add and doubling formulas are aligned with the formulas
proved in fiat-crypto. Those only applied to a = -3, so I've proved a
generic one in https://github.com/mit-plv/fiat-crypto/pull/356, in case
someone uses a custom curve.  The new formulas are verified,
constant-time, and swap a multiply for a square. As expressed in
fiat-crypto they do use more temporaries, but this seems to be fine with
stack-allocated EC_FELEMs. (We can try to help the compiler later,
but benchamrks below suggest this isn't necessary.)

Unlike BIGNUM, EC_FELEM can be stack-allocated. It also captures the
bounds in the type system and, in particular, that the width is correct,
which will make it easier to select a point in constant-time in the
future. (Indeed the old code did not always have the correct width. Its
point formula involved halving and implemented this in variable time and
variable width.)

Before:
Did 77274 ECDH P-256 operations in 10046087us (7692.0 ops/sec)
Did 5959 ECDH P-384 operations in 10031701us (594.0 ops/sec)
Did 10815 ECDSA P-384 signing operations in 10087892us (1072.1 ops/sec)
Did 8976 ECDSA P-384 verify operations in 10071038us (891.3 ops/sec)
Did 2600 ECDH P-521 operations in 10091688us (257.6 ops/sec)
Did 4590 ECDSA P-521 signing operations in 10055195us (456.5 ops/sec)
Did 3811 ECDSA P-521 verify operations in 10003574us (381.0 ops/sec)

After:
Did 77736 ECDH P-256 operations in 10029858us (7750.5 ops/sec) [+0.8%]
Did 7519 ECDH P-384 operations in 10068076us (746.8 ops/sec) [+25.7%]
Did 13335 ECDSA P-384 signing operations in 10029962us (1329.5 ops/sec) [+24.0%]
Did 11021 ECDSA P-384 verify operations in 10088600us (1092.4 ops/sec) [+22.6%]
Did 2912 ECDH P-521 operations in 10001325us (291.2 ops/sec) [+13.0%]
Did 5150 ECDSA P-521 signing operations in 10027462us (513.6 ops/sec) [+12.5%]
Did 4264 ECDSA P-521 verify operations in 10069694us (423.4 ops/sec) [+11.1%]

This more than pays for removing points_make_affine previously and even
speeds up ECDH P-256 slightly. (The point-on-curve check uses the
generic code.)

Next is to push the stack-allocating up to ec_wNAF_mul, followed by a
constant-time single-point multiplication.

Bug: 239
Change-Id: I44a2dff7c52522e491d0f8cffff64c4ab5cd353c
Reviewed-on: https://boringssl-review.googlesource.com/27668
Reviewed-by: Adam Langley <agl@google.com>
2018-04-25 16:39:58 +00:00
David Benjamin
6a289b3ec4 Remove EC_POINTs_make_affine and related logic.
This does not appear to actually pull its weight. The purpose of this
logic is to switch some adds to the faster add_mixed in the wNAF code,
at the cost of a rather expensive inversion. This optimization kicks in
for generic curves, so P-384 and P-521:

With:
Did 32130 ECDSA P-384 signing operations in 30077563us (1068.2 ops/sec)
Did 27456 ECDSA P-384 verify operations in 30073086us (913.0 ops/sec)
Did 14122 ECDSA P-521 signing operations in 30077407us (469.5 ops/sec)
Did 11973 ECDSA P-521 verify operations in 30037330us (398.6 ops/sec)

Without:
Did 32445 ECDSA P-384 signing operations in 30069721us (1079.0 ops/sec)
Did 27056 ECDSA P-384 verify operations in 30032303us (900.9 ops/sec)
Did 13905 ECDSA P-521 signing operations in 30000430us (463.5 ops/sec)
Did 11433 ECDSA P-521 verify operations in 30021876us (380.8 ops/sec)

For single-point multiplication, the optimization is not useful. This
makes sense as we only have one table's worth of additions to convert
but still pay for the inversion. For double-point multiplication, it is
slightly useful for P-384 and very useful for P-521. However, the next
change to stack-allocate EC_FELEMs will more than compensate for
removing it.  (The immediate goal here is to simplify the EC_FELEM
story.)

Additionally, that this optimization was not useful for single-point
multiplication implies that, should we wish to recover this, a modest
8-entry pre-computed (affine) base point table should have the same
effect or better.

Update-Note: I do not believe anything was calling either of these
functions. (If necessary, we can always add no-op stubs as whether a
point is affine is not visible to external code. It previously kicked in
some optimizations, but those were removed for constant-time needs
anyway.)

Bug: 239
Change-Id: Ic9c51b001c45595cfe592274c7d5d652f4234839
Reviewed-on: https://boringssl-review.googlesource.com/27667
Reviewed-by: Adam Langley <agl@google.com>
2018-04-25 16:12:06 +00:00
David Benjamin
06d467c58a ghashv8-armx.pl: add Qualcomm Kryo results.
(Imported from upstream's 753316232243ccbf86b96c1c51ffcb41651d9ad5.)

Just to sync up a bit further.

Change-Id: I805150d0f0c10d68648fae83603b0d46231ae4ec
Reviewed-on: https://boringssl-review.googlesource.com/27685
Commit-Queue: Steven Valdez <svaldez@google.com>
Reviewed-by: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2018-04-24 19:48:59 +00:00
David Benjamin
a7c8f2b7b0 ghashv8-armvx.pl: Fix various typos.
(Imported from upstream's 46f4e1bec51dc96fa275c168752aa34359d9ee51.)

Change-Id: Ie9c1e9cfc38a3962e3674a68bc0174d064272fc2
Reviewed-on: https://boringssl-review.googlesource.com/27684
Commit-Queue: Steven Valdez <svaldez@google.com>
Reviewed-by: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2018-04-24 19:48:49 +00:00
David Benjamin
a63d0ad40d Require BN_mod_exp_mont* inputs be reduced.
If the caller asked for the base to be treated as secret, we should
provide that. Allowing unbounded inputs is not compatible with being
constant-time.

Additionally, this aligns with the guidance here:
https://github.com/HACS-workshop/spectre-mitigations/blob/master/crypto_guidelines.md#1-do-not-conditionally-choose-between-constant-and-non-constant-time

Update-Note: BN_mod_exp_mont_consttime and BN_mod_exp_mont now require
inputs be fully reduced. I believe current callers tolerate this.

Additionally, due to a quirk of how certain operations were ordered,
using (publicly) zero exponent tolerated a NULL BN_CTX while other
exponents required non-NULL BN_CTX. Non-NULL BN_CTX is now required
uniformly. This is unlikely to cause problems. Any call site where the
exponent is always zero should just be replaced with BN_value_one().

Change-Id: I7c941953ea05f36dc2754facb9f4cf83a6789c61
Reviewed-on: https://boringssl-review.googlesource.com/27665
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: Steven Valdez <svaldez@google.com>
2018-04-24 18:29:29 +00:00
David Benjamin
5c0e0cec83 Remove Z = 1 special-case in generic point_get_affine.
As the point may be the output of some private key operation, whether Z
accidentally hit one is secret.

Bug: 239
Change-Id: I7db34cd3b5dd5ca4b96980e8993a9b4eda49eb88
Reviewed-on: https://boringssl-review.googlesource.com/27664
Reviewed-by: Adam Langley <alangley@gmail.com>
2018-04-24 16:16:53 +00:00
David Benjamin
f5858ca008 Remove unnecessary endian flip in p224-64.c.
We have little-endian BIGNUM functions now.

Change-Id: Iffc46a14e75c6bba2e170b824b1a08c69d2e9d18
Reviewed-on: https://boringssl-review.googlesource.com/27594
Reviewed-by: Adam Langley <alangley@gmail.com>
2018-04-24 16:15:28 +00:00
David Benjamin
b8f14b7d53 Add dedicated scalar inversion code to p256-x86_64.c.
This is adapted from upstream's
eb7916960bf50f436593abe3d5f2e0592d291017.

This gives a 22% win for ECDSA signing. (Upstream cites 30-40%, but they
are unnecessarily using BN_mod_exp_mont_consttime in their generic path.
The exponent is public. I expect part of their 30-40% is just offsetting
this.)

Did 506000 ECDSA P-256 signing operations in 25044595us (20204.0 ops/sec)
Did 170506 ECDSA P-256 verify operations in 25033567us (6811.1 ops/sec)

Did 618000 ECDSA P-256 signing operations in 25031294us (24689.1 ops/sec)
Did 182240 ECDSA P-256 verify operations in 25006918us (7287.6 ops/sec)

Most of the performance win appears to be from the assembly operations
and not the addition chain. I have a CL to graft the addition chain onto
the C implementation, but it did not show measurable improvement in
ECDSA verify. ECDSA sign gets 2-4% faster, but we're more concerned
about ECDSA verify in the OPENSSL_SMALL builds.

Change-Id: Ide166f98b146c025f7f80ed7906336c16818540a
Reviewed-on: https://boringssl-review.googlesource.com/27593
Reviewed-by: Adam Langley <alangley@gmail.com>
2018-04-24 16:14:57 +00:00
David Benjamin
364a51ec3a Abstract scalar inversion in EC_METHOD.
This introduces a hook for the OpenSSL assembly.

Change-Id: I35e0588f0ed5bed375b12f738d16c9f46ceedeea
Reviewed-on: https://boringssl-review.googlesource.com/27592
Reviewed-by: Adam Langley <alangley@gmail.com>
2018-04-24 16:13:24 +00:00
David Benjamin
b27b579fdd Add some tests for scalar operations.
Largely random data, but make it easy to add things in the future.

Change-Id: I30bee790bd9671b4d0327c2244fe5cd1a8954f90
Reviewed-on: https://boringssl-review.googlesource.com/27591
Reviewed-by: Adam Langley <alangley@gmail.com>
2018-04-24 16:12:34 +00:00
David Benjamin
3861ae662a p256-x86_64-asm.pl: add .cfi and SEH handlers to new functions.
Imported from upstream's d5e11843fe430dfa89bdf83b6f7805c709dcdb41.

Change-Id: Ie6d64ef821b66531995b43d015ab2755558eaa57
Reviewed-on: https://boringssl-review.googlesource.com/27590
Reviewed-by: Adam Langley <alangley@gmail.com>
2018-04-24 16:10:08 +00:00
David Benjamin
5c30dab835 Import P-256 scalar multiplication assembly from OpenSSL.
This imports the assembly portion of
eb7916960bf50f436593abe3d5f2e0592d291017 from upstream. Note the
OPENSSL_ia32cap_P bits were tweaked to be delocate-compatible. Those
should be reviewed against the original file.

Change-Id: I19eef722225bb7928275e3d93890f80aa2f8734d
Reviewed-on: https://boringssl-review.googlesource.com/27589
Reviewed-by: Adam Langley <alangley@gmail.com>
2018-04-24 16:09:08 +00:00
David Benjamin
7121fe24e9 Align ECDSA sign/verify scalar inversions.
We were still using the allocating scalar inversion for ECDSA verify
because previously it seemed to be faster. It appears to have flipped
now, though probably was always just a wash.

While I'm here, save a multiplication by swapping the inversion and
Montgomery reduction.

Did 200000 ECDSA P-256 signing operations in 10025749us (19948.6 ops/sec)
Did 66234 ECDSA P-256 verify operations in 10061123us (6583.2 ops/sec)

Did 202000 ECDSA P-256 signing operations in 10020846us (20158.0 ops/sec)
Did 68052 ECDSA P-256 verify operations in 10020592us (6791.2 ops/sec)

The actual motivation is to get rid of the unchecked EC_SCALAR function
and align sign/verify in preparation for the assembly scalar ops.

Change-Id: I1bd3a5719a67966dc8edaa43535a3864b69f76d0
Reviewed-on: https://boringssl-review.googlesource.com/27588
Reviewed-by: Adam Langley <alangley@gmail.com>
2018-04-24 16:00:12 +00:00
David Benjamin
941f535438 Abstract away EC_SCALAR operations.
Just a little bit cleaner.

Change-Id: I0ed192a531b5aa853ba082caa6088e838f12c863
Reviewed-on: https://boringssl-review.googlesource.com/27587
Reviewed-by: Adam Langley <alangley@gmail.com>
2018-04-24 15:37:40 +00:00
David Benjamin
9291be5b27 Remove return values from bn_*_small.
No sense in adding impossible error cases we need to handle.
Additionally, tighten them a bit and require strong bounds. (I wasn't
sure what we'd need at first and made them unnecessarily general.)

Change-Id: I21a0afde90a55be2e9a0b8d7288f595252844f5f
Reviewed-on: https://boringssl-review.googlesource.com/27586
Reviewed-by: Adam Langley <alangley@gmail.com>
2018-04-24 15:34:32 +00:00
David Benjamin
3f8074c2de Fix the error on overly large group orders.
Change-Id: I9b11fabb79b5dfe031ac5ea2f021b28b87262761
Reviewed-on: https://boringssl-review.googlesource.com/27585
Reviewed-by: Adam Langley <alangley@gmail.com>
2018-04-24 15:27:17 +00:00
David Benjamin
cd01254900 Explicitly guarantee BN_MONT_CTX::{RR,N} have the same width.
This is so the *_small functions can assume somewhat more uniform
widths, to simplify their error-handling.

Change-Id: I0420cb237084b253e918c64b0c170a5dfd99ab40
Reviewed-on: https://boringssl-review.googlesource.com/27584
Reviewed-by: Adam Langley <alangley@gmail.com>
2018-04-24 15:22:09 +00:00
David Benjamin
a2938719a4 Improve the RSA key generation failure probability.
The FIPS 186-4 algorithm we use includes a limit which hits a 2^-20
failure probability, assuming my math is right. We've observed roughly
2^-23. This is a little large at scale. (See b/77854769.)

To avoid modifying the FIPS algorithm, retry the whole thing four times
to bring the failure rate down to 2^-80. Along the way, now that I have
the derivation on hand, adjust
https://boringssl-review.googlesource.com/22584 to target the same
failure probability.

Along the way, fix an issue with RSA_generate_key where, if callers
don't check for failure, there may be half a key in there.

Change-Id: I0e1da98413ebd4ffa65fb74c67a58a0e0cd570ff
Reviewed-on: https://boringssl-review.googlesource.com/27288
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2018-04-20 21:34:05 +00:00
David Benjamin
9af9b946d2 Restore the BN_mod codepath for public Montgomery moduli.
https://boringssl-review.googlesource.com/10520 and then later
https://boringssl-review.googlesource.com/25285 made BN_MONT_CTX_set
constant-time, which is necessary for RSA's mont_p and mont_q. However,
due to a typo in the benchmark, they did not correctly measure.

Split BN_MONT_CTX creation into a constant-time and variable-time one.
The constant-time one uses our current algorithm and the latter restores
the original BN_mod codepath.

Should we wish to avoid BN_mod, I have an alternate version lying
around:

First, BN_set_bit + bn_mod_lshift1_consttime as now to count up to 2*R.
Next, observe that 2*R = BN_to_montgomery(2) and R*R =
BN_to_montgomery(R) = BN_to_montgomery(2^r_bits) Also observe that
BN_mod_mul_montgomery only needs n0, not RR. Split the core of
BN_mod_exp_mont into its own function so the caller handles conversion.
Raise 2*R to the r_bits power to get 2^r_bits*R = R*R.

The advantage of that algorithm is that it is still constant-time, so we
only need one BN_MONT_CTX_new. Additionally, it avoids BN_mod which is
otherwise (almost, but the remaining links should be easy to cut) out of
the critical path for correctness. One less operation to worry about.

The disadvantage is that it is gives a 25% (RSA-2048) or 32% (RSA-4096)
slower RSA verification speed. I went with the BN_mod one for the time
being.

Before:
Did 9204 RSA 2048 signing operations in 10052053us (915.6 ops/sec)
Did 326000 RSA 2048 verify (same key) operations in 10028823us (32506.3 ops/sec)
Did 50830 RSA 2048 verify (fresh key) operations in 10033794us (5065.9 ops/sec)
Did 1269 RSA 4096 signing operations in 10019204us (126.7 ops/sec)
Did 88435 RSA 4096 verify (same key) operations in 10031129us (8816.1 ops/sec)
Did 14552 RSA 4096 verify (fresh key) operations in 10053411us (1447.5 ops/sec)

After:
Did 9150 RSA 2048 signing operations in 10022831us (912.9 ops/sec)
Did 322000 RSA 2048 verify (same key) operations in 10028604us (32108.2 ops/sec)
Did 289000 RSA 2048 verify (fresh key) operations in 10017205us (28850.4 ops/sec)
Did 1270 RSA 4096 signing operations in 10072950us (126.1 ops/sec)
Did 87480 RSA 4096 verify (same key) operations in 10036328us (8716.3 ops/sec)
Did 80730 RSA 4096 verify (fresh key) operations in 10073614us (8014.0 ops/sec)

Change-Id: Ie8916d1634ccf8513ceda458fa302f09f3e93c07
Reviewed-on: https://boringssl-review.googlesource.com/27287
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2018-04-20 20:50:15 +00:00
David Benjamin
7e2a8a34ba Speed up variable windowed exponentation a bit.
The first non-zero window (which we can condition on for public
exponents) always multiplies by one. This means we can cut out one
Montgomery multiplication. It also means we never actually need to
initialize r to one, saving another Montgomery multiplication for P-521.

This, in turn, means we don't need the bn_one_to_montgomery optimization
for the public-exponent exponentations, so we can delete
bn_one_to_montgomery_small. (The function does currently promise to
handle p = 0, but this is not actually reachable, so it can just do a
reduction on RR.)

For RSA, where we're not doing many multiplications to begin with,
saving one is noticeable.

Before:
Did 92000 RSA 2048 verify (same key) operations in 3002557us (30640.6 ops/sec)
Did 25165 RSA 4096 verify (same key) operations in 3045046us (8264.2 ops/sec)

After:
Did 100000 RSA 2048 verify (same key) operations in 3002483us (33305.8 ops/sec)
Did 26603 RSA 4096 verify (same key) operations in 3010942us (8835.4 ops/sec)

(Not looking at the fresh key number yet as that still needs to be
fixed.)

Change-Id: I81a025a68d9b0f8eb0f9c6c04ec4eedf0995a345
Reviewed-on: https://boringssl-review.googlesource.com/27286
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2018-04-20 20:37:45 +00:00
David Benjamin
56ea9e2769 Fix bn_mod_exp_mont_small when exponentiating to zero.
It's defined to return one in Montgomery form, not a normal one.

(Not that this matters. This function is only used to Fermat's Little
Theorem. Probably it should have been less general, though we'd need to
make new test vectors first.)

Change-Id: Ia8d7588e6a413b25f01280af9aacef0192283771
Reviewed-on: https://boringssl-review.googlesource.com/27285
Reviewed-by: Adam Langley <agl@google.com>
2018-04-18 22:13:16 +00:00
David Benjamin
e0ae249f03 Remove a = 0 special-case in BN_mod_exp_mont.
BN_mod_exp_mont is intended to protect the base, but not the exponent.
Accordingly, it shouldn't treat a base of zero as special.

Change-Id: Ib053e8ce65ab1741973a9f9bfeff8c353567439c
Reviewed-on: https://boringssl-review.googlesource.com/27284
Reviewed-by: Adam Langley <agl@google.com>
2018-04-18 22:03:16 +00:00
David Benjamin
d319205007 Deny CRT to unbalanced RSA keys.
Our technique to perform the reduction only works for balanced key
sizes. For unbalanced keys, we fall back to variable-time logic.
Instead, fall back earlier to the non-CRT codepath, which is still
secure, just slower. This also aligns with the advice here:

https://github.com/HACS-workshop/spectre-mitigations/blob/master/crypto_guidelines.md#1-do-not-conditionally-choose-between-constant-and-non-constant-time

Update-Note: This is a performance hit (some keys will run 3x slower),
but only for keys with different-sized primes. I believe the Windows
crypto APIs will not accept such keys at all. There are two scenarios to
be concerned with for RSA performance:

1. Performance of reasonably-generated keys. Keys that BoringSSL or
anyone else reasonable generates will all be balanced, so this change
does not affect them.

2. Worst-case performance for DoS purposes. This CL does not change the
worst-case performance for RSA at a given bit size. In fact, it improves
it slightly. A sufficiently unbalanced RSA key is as slow as not doing
CRT at all.

In both cases, this change does not affect performance. The affected
keys are pathologically-generated ones that were not quite pathological
enough.

Bug: 235
Change-Id: Ie298dabb549ab9108fa9374aa86ebffe8b6c6c88
Reviewed-on: https://boringssl-review.googlesource.com/27504
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2018-04-17 15:14:04 +00:00
Adam Langley
b2eaeb0b8b Drop some trial-division primes for 1024-bit candidates.
This is helpful at smaller sizes because the benefits of an unlikely hit
by trival-division are smaller.

The full set of kPrimes eliminates about 94.3% of random numbers. The
first quarter eliminates about 93.2% of them. But the little extra power
of the full set seems to be borderline for RSA 3072 and clearly positive
for RSA 4096.

Did 316 RSA 2048 key-gen operations in 30035598us (10.5 ops/sec)
  min: 19423us, median: 80448us, max: 394265us

Change-Id: Iee53f721329674ae7a08fabd85b4f645c24e119d
Reviewed-on: https://boringssl-review.googlesource.com/26944
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: David Benjamin <davidben@google.com>
2018-04-05 03:53:01 +00:00
David Benjamin
eda47f5d98 Make generic point arithmetic slightly less variable-time.
The generic code special-cases affine points, but this leaks
information. (Of course, the generic code also doesn't have a
constant-time multiply and other problems, but one thing at a time.)

The optimization in point doubling is not useful. Point multiplication
more-or-less never doubles an affine point. The optimization in point
addition *is* useful because the wNAF code converts the tables to
affine. Accordingly, align with the P-256 code which adds a 'mixed'
parameter.

(I haven't aligned the formally-verified point formulas themselves yet;
initial testing suggests that the large number of temporaries take a
perf hit with BIGNUM. I'll check the results in EC_FELEM, which will be
stack-allocated, to see if we still need to help the compiler out.)

Strangly, it actually got a bit faster with this change. I'm guessing
because now it doesn't need to bother with unnecessary comparisons and
maybe was kinder to the branch predictor?

Before:
Did 2201 ECDH P-384 operations in 3068341us (717.3 ops/sec)
Did 4092 ECDSA P-384 signing operations in 3076981us (1329.9 ops/sec)
Did 3503 ECDSA P-384 verify operations in 3024753us (1158.1 ops/sec)
Did 992 ECDH P-521 operations in 3017884us (328.7 ops/sec)
Did 1798 ECDSA P-521 signing operations in 3059000us (587.8 ops/sec)
Did 1581 ECDSA P-521 verify operations in 3033142us (521.2 ops/sec)

After:
Did 2310 ECDH P-384 operations in 3092648us (746.9 ops/sec)
Did 4080 ECDSA P-384 signing operations in 3044588us (1340.1 ops/sec)
Did 3520 ECDSA P-384 verify operations in 3056070us (1151.8 ops/sec)
Did 992 ECDH P-521 operations in 3012779us (329.3 ops/sec)
Did 1792 ECDSA P-521 signing operations in 3019459us (593.5 ops/sec)
Did 1600 ECDSA P-521 verify operations in 3047749us (525.0 ops/sec)

Bug: 239
Change-Id: If5d13825fc98e4c58bdd1580cf0245bf7ce93a82
Reviewed-on: https://boringssl-review.googlesource.com/27004
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2018-04-04 21:33:22 +00:00
David Benjamin
ba9da449a4 Tolerate a null BN_CTX in BN_primality_test.
This used to work, but I broke it on accident in the recent rewrite.

Change-Id: I06ab5e06eb0c0a6b67ecc97919654e386f3c2198
Reviewed-on: https://boringssl-review.googlesource.com/26984
Commit-Queue: David Benjamin <davidben@google.com>
Commit-Queue: Martin Kreichgauer <martinkr@google.com>
Reviewed-by: Martin Kreichgauer <martinkr@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2018-04-03 18:13:47 +00:00
David Benjamin
5b05988add Implement field_{mul,sqr} in p224-64.c with p224_felems.
This is in preparation for representing field elements with
stack-allocated types in the generic code. While there is likely little
benefit in threading all the turned field arithmetic through all the
generic code, and the P-224 logic, in particular, does not have a tight
enough abstraction for this, the current implementations depend on
BN_div, which is not compatible with stack-allocating things and avoiding
malloc.

This also speeds things up slightly, now that benchmarks cover point
validation.

Before:
Did 82786 ECDH P-224 operations in 10024326us (8258.5 ops/sec)
After:
Did 89991 ECDH P-224 operations in 10012429us (8987.9 ops/sec)

Change-Id: I468483b49f5dc69187aebd62834365ce5caab795
Reviewed-on: https://boringssl-review.googlesource.com/26971
Reviewed-by: Adam Langley <agl@google.com>
2018-04-02 18:27:45 +00:00
David Benjamin
c81ecf3436 Add test coverage for the a != -3 case.
Alas, it is reachable by way of the legacy custom curves API. Add a
basic test to ensure those codepaths work.

Change-Id: If631110045a664001133a0d07fdac4c67971a15f
Reviewed-on: https://boringssl-review.googlesource.com/26970
Reviewed-by: Adam Langley <agl@google.com>
2018-04-02 18:25:08 +00:00
David Benjamin
04018c5929 Remove EC_LOOSE_SCALAR.
ECDSA converts digests to scalars by taking the leftmost n bits, where n
is the number of bits in the group order. This does not necessarily
produce a fully-reduced scalar.

Montgomery multiplication actually tolerates this slightly looser bound,
so we did not bother with the conditional subtraction. However, this
subtraction is free compared to the multiplication, inversion, and base
point multiplication. Simplify things by keeping it fully-reduced.

Change-Id: If49dffefccc21510f40418dc52ea4da7e3ff198f
Reviewed-on: https://boringssl-review.googlesource.com/26968
Reviewed-by: Adam Langley <agl@google.com>
2018-04-02 18:22:58 +00:00
David Benjamin
9c1f8b4ac7 Add tests for large digests.
ECDSA's logic for converting digests to scalars sometimes produces
slightly unreduced values. Test these cases.

Change-Id: I67a5078db684ee82c286f41e71b13b57c3ee707b
Reviewed-on: https://boringssl-review.googlesource.com/26967
Reviewed-by: Adam Langley <agl@google.com>
2018-04-02 18:18:23 +00:00
David Benjamin
2257e8f3bf Use bn_rshift_words for the ECDSA bit-shift.
May as well use it. Also avoid an overflow with digest_len if someone
asks to sign a truly enormous digest.

Change-Id: Ia0a53007a496f9c7cadd44b1020ec2774b310936
Reviewed-on: https://boringssl-review.googlesource.com/26966
Reviewed-by: Adam Langley <agl@google.com>
2018-04-02 18:17:39 +00:00
David Benjamin
0645c05f5e Test the bit-shifting case in ECDSA.
For non-custom curves, this only comes up with P-521 and, even then,
only with excessively large hashes. Still, we should have test coverage
for this.

Change-Id: Id17a6f47d59d6dd4a43a93857fd3df490f9fa965
Reviewed-on: https://boringssl-review.googlesource.com/26965
Reviewed-by: Adam Langley <agl@google.com>
2018-04-02 18:14:27 +00:00
David Benjamin
cbe77925f4 Extract the single-subtraction reduction into a helper function.
We do this in four different places, with the same long comment, and I'm
about to add yet another one.

Change-Id: If28e3f87ea71020d9b07b92e8947f3848473d99d
Reviewed-on: https://boringssl-review.googlesource.com/26964
Reviewed-by: Adam Langley <agl@google.com>
2018-04-02 18:13:45 +00:00
David Benjamin
25f3d84f4c Rewrite BN_rand without an extra malloc.
RSA keygen uses this to pick primes. May as well avoid bouncing on
malloc. (The BIGNUM internally allocates, of course, but that allocation
will be absorbed by BN_CTX in RSA keygen.)

Change-Id: Ie2243a6e48b9c55f777153cbf67ba5c06688c2f1
Reviewed-on: https://boringssl-review.googlesource.com/26887
Reviewed-by: Adam Langley <agl@google.com>
2018-04-02 18:07:12 +00:00
Adam Langley
eb7c3008cc Only do 16 iterations to blind the primality test.
With this, in 0.02% of 1024-bit primes (which is what's used with an RSA
2048 generation), we'll leak that we struggled to generate values less
than the prime. I.e. that there's a greater likelihood of zero bits
after the leading 1 bit in the prime.

But this recovers all the speed loss from making key generation
constant-time, and then some.

Did 273 RSA 2048 key-gen operations in 30023223us (9.1 ops/sec)
  min: 23867us, median: 93688us, max: 421466us
Did 66 RSA 3072 key-gen operations in 30041763us (2.2 ops/sec)
  min: 117044us, median: 402095us, max: 1096538us
Did 31 RSA 4096 key-gen operations in 31673405us (1.0 ops/sec)
  min: 245109us, median: 769480us, max: 2659386us

Change-Id: Id82dedde35f5fbb36b278189c0685a13c7824590
Reviewed-on: https://boringssl-review.googlesource.com/26924
Reviewed-by: Adam Langley <alangley@gmail.com>
2018-03-30 22:31:36 +00:00
David Benjamin
5833dd807e Limit the public exponent in RSA_generate_key_ex.
Windows CryptoAPI and Go bound public exponents at 2^32-1, so don't
generate keys which would violate that.

https://github.com/golang/go/issues/3161
https://msdn.microsoft.com/en-us/library/aa387685(VS.85).aspx

BoringSSL itself also enforces a 33-bit limit.

I don't currently have plans to take much advantage of it, but the
modular inverse step and one of the GCDs in RSA key generation are
helped by small public exponents[0]. In case someone feels inspired
later, get this limit enforced now. Use 32-bits as that's a more
convenient limit, and there's no requirement to produce e=2^32+1 keys.
(Is there still a requirement to accept them?)

[0] This isn't too bad, but it's only worth it if it produces simpler or
smaller code. RSA keygen is not performance-critical.

1. Make bn_mod_u16_consttime work for uint32_t. It only barely doesn't
   work. Maybe only accept 3 and 65537 and pre-compute, maybe call into
   bn_div_rem_words and friends, maybe just tighten the bound a hair
   longer.
2. Implement bn_div_u32_consttime by incorporating 32-bit chunks much
   like bn_mod_u32_consttime.
3. Perform one normal Euclidean algorithm iteration rather than using the
   binary version. u, v, B, and D are now single words, while A and C
   are full-width.
4. Continue with binary Euclidean algorithm (u and v are still secret),
   taking advantage of most values being small.

Update-Note: RSA_generate_key_ex will no longer generate keys with
   public exponents larger than 2^32-1. Everyone uses 65537, save some
   folks who use 3, so this shouldn't matter.

Change-Id: I0d28a29a30d9ff73bff282e34dd98e2b64c35c79
Reviewed-on: https://boringssl-review.googlesource.com/26365
Reviewed-by: Adam Langley <alangley@gmail.com>
2018-03-30 19:54:18 +00:00
David Benjamin
c1c6eeb5e2 Check d is mostly-reduced in RSA_check_key.
We don't check it is fully reduced because different implementations use
Carmichael vs Euler totients, but if d exceeds n, something is wrong.
Note the fixed-width BIGNUM changes already fail operations with
oversized d.

Update-Note: Some blatantly invalid RSA private keys will be rejected at
    RSA_check_key time. Note that most of those keys already are not
    usable with BoringSSL anyway. This CL moves the failure from
    sign/decrypt to RSA_check_key.

Change-Id: I468dbba74a148aa58c5994cc27f549e7ae1486a2
Reviewed-on: https://boringssl-review.googlesource.com/26374
Reviewed-by: Adam Langley <alangley@gmail.com>
2018-03-30 19:54:10 +00:00
David Benjamin
cba958f406 Make RSA_check_key constant-time and more meaningful.
Rather than recompute values the same as in key generation, where
possible, we check differently. In particular, most RSA values are
modular inverses of some value. Check each of them by multiplying and
using our naive constant-time division function.

Median of 29 RSA keygens: 0m0.218s -> 0m0.205s
(Accuracy beyond 0.1s is questionable.)

Bug: 238
Change-Id: Iaca19f12c045457013def844a17bf502ed09136e
Reviewed-on: https://boringssl-review.googlesource.com/26373
Reviewed-by: Adam Langley <alangley@gmail.com>
2018-03-30 19:54:00 +00:00
David Benjamin
c4e4757b63 Make RSA key generation constant-time.
This leaves RSA_check_key, which will be fixed in subsequent commits.

Median of 29 RSA keygens: 0m0.220s -> 0m0.209s
(Accuracy beyond 0.1s is questionable.)

Bug: 238
Change-Id: I325f23fcc59302e68570908e5427b65471b799f6
Reviewed-on: https://boringssl-review.googlesource.com/26371
Reviewed-by: Adam Langley <alangley@gmail.com>
2018-03-30 19:53:52 +00:00
David Benjamin
a44dae7fd3 Add a constant-time generic modular inverse function.
This uses the full binary GCD algorithm, where all four of A, B, C, and
D must be retained. (BN_mod_inverse_odd implements the odd number
version which only needs A and C.) It is patterned after the version
in the Handbook of Applied Cryptography, but tweaked so the coefficients
are non-negative and bounded.

Median of 29 RSA keygens: 0m0.225s -> 0m0.220s
(Accuracy beyond 0.1s is questionable.)

Bug: 238
Change-Id: I6dc13524ea7c8ac1072592857880ddf141d87526
Reviewed-on: https://boringssl-review.googlesource.com/26370
Reviewed-by: Adam Langley <alangley@gmail.com>
2018-03-30 19:53:44 +00:00
David Benjamin
1044553d6d Add new GCD and related primitives.
RSA key generation requires computing a GCD (p-1 and q-1 are relatively
prime with e) and an LCM (the Carmichael totient). I haven't made BN_gcd
itself constant-time here to save having to implement
bn_lshift_secret_shift, since the two necessary operations can be served
by bn_rshift_secret_shift, already added for Rabin-Miller. However, the
guts of BN_gcd are replaced. Otherwise, the new functions are only
connected to tests for now, they'll be used in subsequent CLs.

To support LCM, there is also now a constant-time division function.
This does not replace BN_div because bn_div_consttime is some 40x slower
than BN_div. That penalty is fine for RSA keygen because that operation
is not bottlenecked on division, so we prefer simplicity over
performance.

Median of 29 RSA keygens: 0m0.212s -> 0m0.225s
(Accuracy beyond 0.1s is questionable.)

Bug: 238
Change-Id: Idbfbfa6e7f5a3b8782ce227fa130417b3702cf97
Reviewed-on: https://boringssl-review.googlesource.com/26369
Reviewed-by: Adam Langley <alangley@gmail.com>
2018-03-30 19:53:36 +00:00