Compare commits

...

523 Commits

Author SHA1 Message Date
David Benjamin c8ff30cbe7 Add an option to allow unknown ALPN protocols.
We received an external request to add an option to undo the check added
in 3e51757de2.

Change-Id: Ifdd4b07705f2fa3d781d775d5cd139ea72d36734
Reviewed-on: https://boringssl-review.googlesource.com/14644
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>
2017-04-05 00:33:57 +00:00
David Benjamin 0686c09eea Fix CRYPTO_dup_ex_data.
On malloc error, CRYPTO_set_ex_data may fail. (See upstream's
62f488d31733e5dc77b339f905b44f165550e47d.)

It also failed to copy the reserved slots when we revised the app-data
machinery, although this is unreachable as EC_KEY is the only thing
which uses this function and EC_KEY has no reserved slots. (We probably
can/should also take CRYPTO_dup_ex_data out of there, as it's a little
bit weird...)

Change-Id: I60bbc301f919d4c0ee7fff362f979f6ec18d73b7
Reviewed-on: https://boringssl-review.googlesource.com/14604
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Steven Valdez <svaldez@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-04-04 18:21:49 +00:00
Adam Langley b18cb6a5d0 Make the POWER hardware capability value a global in crypto.c.
(Thanks to Sam Panzer for the patch.)

At least some linkers will drop constructor functions if no symbols from
that translation unit are used elsewhere in the program. On POWER, since
the cached capability value isn't a global in crypto.o (like other
platforms), the constructor function is getting discarded.

The C++11 spec says (3.6.2, paragraph 4):

    It is implementation-defined whether the dynamic initialization of a
    non-local variable with static storage duration is done before the
    first statement of main. If the initialization is deferred to some
    point in time after the first statement of main, it shall occur
    before the first odr-use (3.2) of any function or variable defined
    in the same translation unit as the variable to be initialized.

Compilers appear to interpret that to mean they are allowed to drop
(i.e. indefinitely defer) constructors that occur in translation units
that are never used, so they can avoid initializing some part of a
library if it's dropped on the floor.

This change makes the hardware capability value for POWER a global in
crypto.c, which should prevent the constructor function from being
ignored.

Change-Id: I43ebe492d0ac1491f6f6c2097971a277f923dd3e
Reviewed-on: https://boringssl-review.googlesource.com/14664
Commit-Queue: Adam Langley <agl@google.com>
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>
2017-04-04 18:19:19 +00:00
David Benjamin 42329a828b Clean up PKCS5_PBKDF2_HMAC.
This was a mess. HMAC_CTX_copy_ex would avoid having to cleanup and init
the HMAC_CTX repeatedly, but even that is unnecessary. hctx_tpl was just
to reuse the key. Instead, HMAC_CTX already can be reset with the same
key. (Alas, with a slightly odd API, but so it goes.) Do that, and use
goto err to cleanup the error-handling.

Thanks to upstream's b98530d6e09f4cb34c791b8840e936c1fc1467cf for
drawing attention to this. (Though we've diverged significantly from
upstream with all the heap-allocated bits, so I didn't use the change
itself.)

While I'm here, tidy up some variable names and cite the newer RFC.

Change-Id: Ic1259f46b7c5a14dc341b8cee385be5508ac4daf
Reviewed-on: https://boringssl-review.googlesource.com/14605
Reviewed-by: Steven Valdez <svaldez@google.com>
Commit-Queue: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-04-04 18:13:53 +00:00
Martin Kreichgauer 8b487b73aa util/generate_build_files.py: Filter test runner sources from BUILD files.
Change-Id: I6eb13647843b124b0cfeb7ea592736a80d723836
Reviewed-on: https://boringssl-review.googlesource.com/14624
Reviewed-by: Adam Langley <agl@google.com>
2017-04-03 23:12:33 +00:00
Alessandro Ghedini 67bb45f44b Support enabling early data on SSL
This moves the early data switch to CERT to make this
|SSL_set_SSL_CTX|-proof.

Change-Id: Icca96e76636d87578deb24b2d507cabee7e46a4a
Reviewed-on: https://boringssl-review.googlesource.com/14545
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>
2017-04-03 20:25:29 +00:00
Adam Langley faa539f877 Remove static output buffers for hash & HMAC functions.
These static output buffers are a legacy from a time before processes
had threads. This change drops support and callers who were depending on
this (of which there are hopefully none) will crash.

Change-Id: I7b8eb3440def507f92543e55465f821dfa02c7da
Reviewed-on: https://boringssl-review.googlesource.com/14528
Commit-Queue: Adam Langley <agl@google.com>
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>
2017-04-02 17:53:17 +00:00
David Benjamin ebcb5beb19 Sync vendored copies of Go poly1305 and curve25519.
Taken from revision 3cb07270c9455e8ad27956a70891c962d121a228 of
go-crypto. Some of the changes look like they might fix some of the
crashes we've been having on ARM bots?

Change-Id: I127fd358db553eae4805e777011a89124f595ff0
Reviewed-on: https://boringssl-review.googlesource.com/14544
Commit-Queue: David Benjamin <davidben@google.com>
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-30 20:04:23 +00:00
Adam Langley 107d4388cb Gate assembly sources on !OPENSSL_NO_ASM.
Change-Id: I32b37306265e89afca568f20bfba2e04559c4f0b
Reviewed-on: https://boringssl-review.googlesource.com/14527
Commit-Queue: Adam Langley <agl@google.com>
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>
2017-03-30 19:34:21 +00:00
David Benjamin cbfd3c044c Refresh fuzzer corpora.
Change-Id: I04babe31dcea8198a88c8affd5f9f9e24e449e4a
Reviewed-on: https://boringssl-review.googlesource.com/14526
Reviewed-by: Steven Valdez <svaldez@google.com>
2017-03-30 16:55:36 +00:00
David Benjamin 0c05c37f93 Update fuzzer exclusions.
We've got to get a bot for this...

Change-Id: I6af0c466c10ec52bf2e67f1e6fa2513411aeb3c0
Reviewed-on: https://boringssl-review.googlesource.com/14524
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Steven Valdez <svaldez@google.com>
2017-03-30 16:54:38 +00:00
David Benjamin 519118f984 Fix FUZZING.md typo.
Change-Id: Ie43ffabfdf5b10fbb0c8adcc2626a2913152e5e1
Reviewed-on: https://boringssl-review.googlesource.com/14525
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Steven Valdez <svaldez@google.com>
2017-03-30 16:54:18 +00:00
Doug Kwan a5f1b38de5 Use vec_vsx_ld to performance unaligned load instead of dereferencing a pointer
and relying on a compiler to generate code for unaligned access.  Both gcc
and llvm currently do that but llvm is going to change to generate code for
aligned access.  The change in llvm will break SHA-1 on POWER without this fix.

Change-Id: If9393968288cf94b684ad340e3ea295e03174aa9
Reviewed-on: https://boringssl-review.googlesource.com/14378
Reviewed-by: Adam Langley <agl@google.com>
2017-03-30 16:43:30 +00:00
David Benjamin 7e9949c30b Import additional test vectors from RFC 8032.
There are a few test vectors which were not imported from djb's. Mirror
those. Also as RFC 8032 uses a slightly different private key
representation, document this in curve25519.h.

BUG=187

Change-Id: I119381168ba1af9b332365fd8f974fba41759d57
Reviewed-on: https://boringssl-review.googlesource.com/14445
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-03-30 16:28:55 +00:00
David Benjamin 17eeb9820c Unwind the rest of EVP_PKEY_supports_digest.
This is a remnant of a previous iteration of the SSL client certificate
bridging logic in Chromium.

Change-Id: Ifa8e15cc970395f179e2f6db65c97a342af5498d
Reviewed-on: https://boringssl-review.googlesource.com/14444
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-03-30 16:28:25 +00:00
David Benjamin 6bb507bc9c Add missing tests for the Channel ID / 0-RTT interaction.
Clients or servers enabling both should not stop functioning.

Change-Id: I5cca09f8adfc8ff56b8943123847bbdaf8885cf4
Reviewed-on: https://boringssl-review.googlesource.com/14485
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>
2017-03-30 16:25:44 +00:00
David Benjamin e94ec3f85b Use a union in tls_cbc.c.
This is slightly tidier than casting through function pointers. (Also
more defined? But we cast T* => void* within a function pointer all over
the place, so that's probably a lost cause.)

Change-Id: I8f435906f3066d1377eababf940e3db34c626acd
Reviewed-on: https://boringssl-review.googlesource.com/14313
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-03-30 16:25:11 +00:00
David Benjamin 79bc7a3212 Remove unsigned-based constant-time functions.
We only need the size_t ones now.

BUG=22

Change-Id: Ie6935656bbc4bd2b602b8fad78effc401c493416
Reviewed-on: https://boringssl-review.googlesource.com/14312
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-03-30 16:24:19 +00:00
David Benjamin 643b77e644 Convert tls_cbc.c to size_t.
Not that this is remotely necessary since the code bounds to 1MB, the
caller bounds to INT_MAX (due to EVP_CIPHER) and the grandcaller bounds
to 16k (due to TLS).

BUG=22

Change-Id: Ia75990a30bac26ca617532630340ff94a88e4e20
Reviewed-on: https://boringssl-review.googlesource.com/14311
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-03-30 16:23:38 +00:00
David Benjamin 053a8f728e Bound EVP_tls_cbc_digest_record at runtime.
This is redundant because these "AEAD"s are not meant to be used outside
of TLS, but since we've moved them into their own layer, they should
check internally.

Change-Id: Ieb3541b2e494902527c2bb56a816cef620cb237b
Reviewed-on: https://boringssl-review.googlesource.com/14310
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-03-30 16:20:55 +00:00
David Benjamin 8d979e5430 Push variable declarations in EVP_tls_cbc_digest_record.
This makes it a bit easier to see what is what.

Change-Id: I0f73f6ffa84bd30de3efcbf2bd34e1d3a889d1ee
Reviewed-on: https://boringssl-review.googlesource.com/14309
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-03-30 16:20:36 +00:00
David Benjamin b0ad3d74db Convert more RSA padding check functions to size_t.
BUG=22

Change-Id: I9f392eef44e83efb4b13931acb2a3c642cbf1f29
Reviewed-on: https://boringssl-review.googlesource.com/14308
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-03-30 16:19:45 +00:00
David Benjamin 43ea204db7 Convert RSA_padding_check_PKCS1_type_1 to size_t.
BUG=22

Change-Id: I5bfa543c261623d125e7a25cea905e3b90b0c014
Reviewed-on: https://boringssl-review.googlesource.com/14307
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-03-30 16:03:20 +00:00
David Benjamin d1c0de6fe0 Add size_t variants of constant-time functions.
These will be used in follow-up commits. The _s names are taken from
upstream, to ease importing code. I've also promoted the CONSTTIME_*
macros from the test. None of them are really necessary except
~0u cannot substitute for CONSTTIME_TRUE_S on 64-bit platforms, so
having the macros seems safer.

Once everything is converted, I expect the unsigned versions can be
removed, so I've made the _8 and _int functions act on size_t rather
than unsigned. The users of these functions basically only believe that
array indices and bytes exist.

BUG=22

Change-Id: I987bfb0c708dc726a6f2afcb05b6619bbd600564
Reviewed-on: https://boringssl-review.googlesource.com/14306
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-03-30 15:38:43 +00:00
Steven Valdez f368c73826 Fix fuzzer excludes.
Change-Id: I013cf58528463ccca9e087c1c5d544beec3db24a
Reviewed-on: https://boringssl-review.googlesource.com/14466
Reviewed-by: David Benjamin <davidben@google.com>
2017-03-30 02:39:56 +00:00
David Benjamin fef78b0356 Use an actual SCT for fuzzing.
SSL_CTX_set_signed_cert_timestamp_list fails now if its input is not
well-formed.

Change-Id: I84a4034f66868da11f98bf33e5b7f5c9fc958933
Reviewed-on: https://boringssl-review.googlesource.com/14484
Reviewed-by: Steven Valdez <svaldez@google.com>
Commit-Queue: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-29 23:00:36 +00:00
Steven Valdez a507617e4d Adding server fuzzer for early data.
Since any ALPN mismatch and other cause for early data rejection will
cause the server to revert to the non-early data path, this is safe to
flip on for all the fuzzers.

BUG=76

Change-Id: I573740ef8f455915820943d82247fb6bfc37ae41
Reviewed-on: https://boringssl-review.googlesource.com/14465
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>
2017-03-29 22:51:46 +00:00
Adam Langley 764ab9802e Support and test P-224 certificates.
Previously we only needed to be able to serve P-224 certificates, but
now we anticipate a need to be able to connect and validate them also.
Since this requires advertising support for P-224 in the handshake, we
need to support P-224 ECDHE too.

P-224 support is disabled by default and so clients need to both set the
enabled curves explicitly and set a maximum version of TLS 1.2.

Change-Id: Idc69580f47334e0912eb431a0db0e78ee2eb5bbe
Reviewed-on: https://boringssl-review.googlesource.com/14225
Reviewed-by: Adam Langley <alangley@gmail.com>
Commit-Queue: Adam Langley <alangley@gmail.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-29 17:50:36 +00:00
Steven Valdez a0ba400c33 Add cipher asserts for read/write app data.
Allow the fuzzers to treat this situation, if they ever discover it,
as a bug.

Change-Id: Ie6f1562e9b185d49463cf1a6db28d28780169b11
Reviewed-on: https://boringssl-review.googlesource.com/14424
Reviewed-by: David Benjamin <davidben@google.com>
2017-03-28 21:02:56 +00:00
David Benjamin ccbb165d98 Tidy up ssl3_choose_cipher.
Change-Id: Ied6b73fde61eb133c9871b42a56aa5a64131b67b
Reviewed-on: https://boringssl-review.googlesource.com/14328
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>
2017-03-27 20:13:13 +00:00
David Benjamin 8c26d750e1 Test the behavior of running SSL_do_handshake twice in a row.
BUG=185

Change-Id: I4ce6735ca78cd687538a8c0fdbd78ee97b93585c
Reviewed-on: https://boringssl-review.googlesource.com/14382
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>
2017-03-27 18:30:44 +00:00
David Benjamin 7a60ca095d Synchronize bsaes-armv7.pl with upstream.
This pulls in upstream's 0822d41b6d54132df96c02cc6f6fa9b179378351 and a
portion of a285992763f3961f69a8d86bf7dfff020a08cef9. The former, in
particular, fixes a crash on iOS.

Change-Id: I3c083975d8d11e58b5a2919fcabbf83628f36340
Reviewed-on: https://boringssl-review.googlesource.com/14383
Reviewed-by: Steven Valdez <svaldez@chromium.org>
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>
2017-03-27 16:38:33 +00:00
David Benjamin 0f5d7d3f04 Just allocate what's needed for SSL write buffers.
When we refactored all the buffering logic, we retained upstream
OpenSSL's allocation patterns. In particular, we always allocated fixed
size write buffer, even though, unlike when reading, we trivially know a
tighter bound (namely however much we happen to be writing right now).

Since the cutoff for when Windows' malloc starts having a hard time is
just below the TLS maximum record size, do the more natural thing of
allocating what we need to hold outgoing ciphertext.

(This only does anything to the write half. Read half is a bit more
involved.)

BUG=chromium:524258

Change-Id: I0165f9ce822b9cc413f3c77e269e6154160537a7
Reviewed-on: https://boringssl-review.googlesource.com/14405
Reviewed-by: Steven Valdez <svaldez@chromium.org>
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>
2017-03-27 16:37:53 +00:00
David Benjamin 95321e15f2 Fix diff_asm.go.
We now have another non-OpenSSL perlasm file.

Change-Id: Id5ab606089f22a4cb4c7d29f2cf7d140b66861f7
Reviewed-on: https://boringssl-review.googlesource.com/14404
Reviewed-by: Steven Valdez <svaldez@chromium.org>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Steven Valdez <svaldez@chromium.org>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-27 14:29:55 +00:00
David Benjamin bbfe603519 Clean up end_of_early_data processing.
Remove another remnant of the SSL3_PROTOCOL_METHOD hook.

Change-Id: If6bf055e2ee318420e4c5c40b8eb5356eadda68c
Reviewed-on: https://boringssl-review.googlesource.com/14381
Commit-Queue: David Benjamin <davidben@google.com>
Commit-Queue: Steven Valdez <svaldez@chromium.org>
Reviewed-by: Steven Valdez <svaldez@chromium.org>
Reviewed-by: David Benjamin <davidben@google.com>
2017-03-26 20:39:44 +00:00
David Benjamin fc2d78dd1e Document server 0-RTT behavior.
BUG=76

Change-Id: I68bc1dce13af9155b385a7b589480aacf02ec0db
Reviewed-on: https://boringssl-review.googlesource.com/14380
Commit-Queue: David Benjamin <davidben@google.com>
Commit-Queue: Steven Valdez <svaldez@chromium.org>
Reviewed-by: Steven Valdez <svaldez@chromium.org>
Reviewed-by: David Benjamin <davidben@google.com>
2017-03-26 20:39:31 +00:00
Steven Valdez 681eb6ac2d Adding support for receiving early data on the server.
BUG=76

Change-Id: Ie894ea5d327f88e66b234767de437dbe5c67c41d
Reviewed-on: https://boringssl-review.googlesource.com/12960
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>
2017-03-26 19:30:27 +00:00
David Benjamin 32c8927159 Add a test for missing end_of_early_data.
BUG=76

Change-Id: I43672ee82a50f8fe706a5d607ef774a6e96db252
Reviewed-on: https://boringssl-review.googlesource.com/14379
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>
2017-03-26 19:09:17 +00:00
David Benjamin 81a191dc4d Convert constant_time_test to GTest.
This ends up under half the size of the original file.

BUG=129

Change-Id: Idec69d9517bd57cee6b3b83bc0cce05396565b70
Reviewed-on: https://boringssl-review.googlesource.com/14305
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>
2017-03-26 19:04:07 +00:00
David Benjamin 94cf5d030f Remove some unnecessary NULL checks.
OPENSSL_free will handle NULL.

Change-Id: I18593a015cd4a081c2eeebf0cd738a024d02a97d
Reviewed-on: https://boringssl-review.googlesource.com/14373
Reviewed-by: Steven Valdez <svaldez@chromium.org>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Steven Valdez <svaldez@chromium.org>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-26 18:58:17 +00:00
David Benjamin e000440982 Detach pkcs7.c from the OID table.
It still depends on crypto/x509, but we will need a CRYPTO_BUFFER
version of PKCS7_get_certificates for Chromium. Start with this.

BUG=54

Change-Id: I62dcb9ba768091ce37dc9fe819f4f14ac025219c
Reviewed-on: https://boringssl-review.googlesource.com/14372
Reviewed-by: Steven Valdez <svaldez@chromium.org>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Steven Valdez <svaldez@chromium.org>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-26 18:58:15 +00:00
Alessandro Ghedini ca307ab6a3 tool: show if early data was accepted
Change-Id: I5e1302d75f863fb2e531d431a4e3ecfd90e0dca1
Reviewed-on: https://boringssl-review.googlesource.com/14376
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>
2017-03-26 18:31:07 +00:00
David Benjamin 065d733c4b Test ticket age skew when resuming a resumed session.
This tests that the ticket age is measured from ticket issuance and not
the initial authentication. Specifically, that ssl_session_renew_timeout
also rebases the time.

Change-Id: Iba51efb49c691a44e6428d1cd35f0803ca3d396a
Reviewed-on: https://boringssl-review.googlesource.com/14375
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>
2017-03-26 18:24:37 +00:00
Steven Valdez 2a0707210a Prevent Channel ID and Custom Extensions on 0-RTT.
Channel ID is incompatible with 0-RTT, so we gracefully decline 0-RTT
as a server and forbid their combination as a client. We'll keep this
logic around until Channel ID is removed.

Channel ID will be replaced by tokbind which currently uses custom
extensions. Those will need additional logic to work with 0-RTT.
This is not implemented yet so, for now, fail if both are ever
configured together at all. A later change will allow the two to
combine.

BUG=183

Change-Id: I46c5ba883ccd47930349691fb08074a1fab13d5f
Reviewed-on: https://boringssl-review.googlesource.com/14370
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>
2017-03-26 18:13:57 +00:00
Steven Valdez 246eeee61a Make RI on TLS 1.3 alert with ILLEGAL_PARAMETER.
Change-Id: I0e2e4166ad2c57e3192af058f23374f014a2fcf4
Reviewed-on: https://boringssl-review.googlesource.com/14377
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>
2017-03-26 18:10:37 +00:00
David Benjamin 794cc59e25 Send half-RTT tickets when negotiating 0-RTT.
Once 0-RTT data is added to the current 0-RTT logic, the server will
trigger a write when processing incoming data via SSL_read. This means
SSL_read will block on transport write, which is something we've not
tried to avoid far (assuming no renegotiation).

The specification allows for tickets to be sent at half-RTT by
predicting the client Finished. By doing this we both get the tickets on
the wire sooner and avoid confusing I/O patterns. Moreover, we
anticipate we will need this mode for one of the QUIC stateless reject
patterns.

This is tested by always processing NewSessionTickets in the
ExpectHalfRTTData path on 0-RTT connections. As not other
implementations using BoGo may not do this, this is configurable via the
shim config.

BUG=76

Change-Id: Ia0f56ae63f15078ff1cacceba972d2b99001947f
Reviewed-on: https://boringssl-review.googlesource.com/14371
Reviewed-by: Steven Valdez <svaldez@chromium.org>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Steven Valdez <svaldez@chromium.org>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-26 18:10:07 +00:00
David Benjamin 02084ea398 Decouple PKCS8_encrypt and PKCS8_decrypt's core from crypto/asn1.
These will be used by Chromium's crypto::ECPrivateKey to work with
EncryptedPrivateKeyInfo structures.

Note this comes with a behavior change: PKCS8_encrypt and PKCS8_decrypt
will no longer preserve PKCS#8 PrivateKeyInfo attributes. However, those
functions are only called by Chromium which does not care. They are also
called by the PEM code, but not in a way which exposes attributes.

The PKCS#12 PFX code is made to use PKCS8_parse_encrypted_private_key
because it's cleaner (no more tossing X509_SIG around) and to ease
decoupling that in the future.

crypto/pkcs8's dependency on the legacy ASN.1 stack is now limited to
pkcs8_x509.c.

BUG=54

Change-Id: I173e605d175e982c6b0250dd22187b73aca15b1a
Reviewed-on: https://boringssl-review.googlesource.com/14215
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>
2017-03-26 04:00:26 +00:00
David Benjamin 3cb12467cc Remove session_tickets_sent.
This is a remnant of before we made the handshake write
flight by flight.

Change-Id: I94c0105bb071ffca9ff5aa4c4bf43311c750b49a
Reviewed-on: https://boringssl-review.googlesource.com/14369
Reviewed-by: Steven Valdez <svaldez@chromium.org>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Steven Valdez <svaldez@chromium.org>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-26 01:22:27 +00:00
David Benjamin 7ce10d5da7 Partially split out crypto/pkcs8's legacy ASN.1 dependencies.
PKCS8_encrypt and PKCS8_decrypt still need to be split. The code for
processing PKCS#12 files is, for now, placed entirely in pkcs8_x509.c.
If we need to split it up, it should be straightforward to do so.
(Introduce a CRYPTO_BUFFER version of PKCS12_get_key_and_certs and go
from there.)

BUG=54

Change-Id: I9c87e916ec29ee14dbbd81c4d3fc10ac8a461f1a
Reviewed-on: https://boringssl-review.googlesource.com/14214
Reviewed-by: Steven Valdez <svaldez@chromium.org>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Steven Valdez <svaldez@chromium.org>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-26 00:17:25 +00:00
David Benjamin 4784b99bf3 Use set_{accept,connect}_state + do_handshake in bssl_shim.
This will make it easier to test 0-RTT later on.

BUG=76

Change-Id: I4d60b77c14bc9143ca9785d0a6b8169653a1b120
Reviewed-on: https://boringssl-review.googlesource.com/14367
Reviewed-by: Steven Valdez <svaldez@chromium.org>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Steven Valdez <svaldez@chromium.org>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-25 23:34:27 +00:00
David Benjamin 7d2dbc3791 Add a comment around the set_{min,max}_version logic.
It's not immediately obvious what's going on here.

Change-Id: Ibbba80a6ff9ace4d88e89a42efc270b77b4fad12
Reviewed-on: https://boringssl-review.googlesource.com/14368
Reviewed-by: Steven Valdez <svaldez@chromium.org>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Steven Valdez <svaldez@chromium.org>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-25 23:28:45 +00:00
David Benjamin e3843d41b9 Run all state machine coverage tests on implicit handshake.
The tests all work fine under it except for tests where the shim shuts
down. (In those the shim calls SSL_shutdown as the first function, so it
wouldn't do anything useful.)

Change-Id: Ia2e811bb3c553a690df38d1fd7d3107ae7c9aa12
Reviewed-on: https://boringssl-review.googlesource.com/14366
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>
2017-03-25 23:18:12 +00:00
David Benjamin f466cdb5e0 size_t the RSA padding add functions.
The padding check functions will need to tweak their calling conventions
and the constant-time helpers, so leaving those alone for now. These
were the easy ones.

BUG=22

Change-Id: Ia00e41e26a134de17d56be3def5820cb042794e1
Reviewed-on: https://boringssl-review.googlesource.com/14265
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>
2017-03-25 21:59:49 +00:00
David Benjamin bbf4246546 Add a test that ALPN is rejected on renegotiation.
We've never allowed this as no good can come of it. Add a test for this.

Change-Id: I4b92372f58c1fe2054e33007adbe496d153a9251
Reviewed-on: https://boringssl-review.googlesource.com/14266
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>
2017-03-25 21:51:42 +00:00
David Benjamin 8cd7bbf514 Push password encoding back into pkcs12_key_gen.
With PKCS8_encrypt_pbe and PKCS8_decrypt_pbe gone in
3e8b782c0c, we can restore the old
arrangement where the password encoding was handled in pkcs12_key_gen.
This simplifies the interface for the follow-up crypto/asn1 split.

Note this change is *not* a no-op for PKCS#12 files which use PBES2.
Before, we would perform the PKCS#12 password encoding for all parts of
PKCS#12 processing. The new behavior is we only perform it for the parts
that go through the PKCS#12 KDF. For such a file, it would only be the
MAC.

I believe the specification supports our new behavior. Although RFC 7292
B.1 says something which implies that the transformation is about
converting passwords to byte strings and would thus be universal,
appendix B itself is prefaced with:

   Note that this method for password privacy mode is not recommended
   and is deprecated for new usage.  The procedures and algorithms
   defined in PKCS #5 v2.1 [13] [22] should be used instead.
   Specifically, PBES2 should be used as encryption scheme, with PBKDF2
   as the key derivation function.

"This method" refers to the key derivation and not the password
formatting, but it does give support to the theory that password
formatting is tied to PKCS#12 key derivation.

(Of course, if one believes PKCS#12's assertion that their inane
encoding (NUL-terminated UTF-16!) is because PKCS#5 failed to talk about
passwords as Unicode strings, one would think that PBES2 (also in
PKCS#5) would have the same issue and thus need PKCS#12 to valiantly
save the day with an encoding...)

This matches OpenSSL's behavior and that of recent versions of NSS. See
https://bugzilla.mozilla.org/show_bug.cgi?id=1268141. I was unable to
figure out what variants, if any, macOS accepts.

BUG=54

Change-Id: I9a1bb4d5e168e6e76b82241e4634b1103e620b9b
Reviewed-on: https://boringssl-review.googlesource.com/14213
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>
2017-03-25 21:25:30 +00:00
David Benjamin 3cb047e56c Decouple PKCS#12 hash lookup from the OID table.
This isn't strictly necessary for Chromium yet, but we already have a
decoupled version of hash algorithm parsing available. For now, don't
export it but eventually we may wish to use it for OCSP.

BUG=54

Change-Id: If460d38d48bd47a2b4a853779f210c0cf7ee236b
Reviewed-on: https://boringssl-review.googlesource.com/14211
Reviewed-by: Steven Valdez <svaldez@chromium.org>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Steven Valdez <svaldez@chromium.org>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-25 21:22:50 +00:00
Steven Valdez 2d85062c4f Add Data-less Zero-RTT support.
This adds support on the server and client to accept data-less early
data. The server will still fail to parse early data with any
contents, so this should remain disabled.

BUG=76

Change-Id: Id85d192d8e0360b8de4b6971511b5e8a0e8012f7
Reviewed-on: https://boringssl-review.googlesource.com/12921
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>
2017-03-25 21:00:18 +00:00
David Benjamin f35e8384a8 Fix parsing of PBKDF2 parameters.
The OPTIONAL prf field is an AlgorithmIdentifier, not an OID.  I messed
this up in the recent rewrite.

Fix the parsing and add a test, produced by commenting out the logic in
OpenSSL to omit the field for hmacWithSHA1. (We don't currently support
any other PBKDF2, or I'd just add a test for that.)

Change-Id: I7d258bb01b93cd203a6fc1b8cccbddfdbc4dbbad
Reviewed-on: https://boringssl-review.googlesource.com/14330
Reviewed-by: Steven Valdez <svaldez@google.com>
Commit-Queue: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-25 16:29:06 +00:00
David Benjamin 7179e53ea6 Remove TODO.
This isn't something we need to fix, just an explanatory comment.

Change-Id: I284e6580d176f981c6b161e9951f367fef1b1be6
Reviewed-on: https://boringssl-review.googlesource.com/14264
Reviewed-by: Steven Valdez <svaldez@google.com>
Commit-Queue: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-25 16:29:04 +00:00
David Benjamin 1d4fa785bc Decouple PBE lookup from the OID table.
BUG=54

Change-Id: Ia792dadcbda4efb22b45ae69a6e425ae2b341f61
Reviewed-on: https://boringssl-review.googlesource.com/14210
Reviewed-by: Steven Valdez <svaldez@google.com>
Commit-Queue: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-25 16:28:44 +00:00
David Benjamin cfb9d147bb Update pkcs8 error data.
We forgot to run the script at some point.

Change-Id: I0bd142fdd13d64c1ed81d9b1515449220d1c936b
Reviewed-on: https://boringssl-review.googlesource.com/14329
Commit-Queue: David Benjamin <davidben@google.com>
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>
2017-03-23 15:07:28 +00:00
David Benjamin c90ed1901d Tidy up error-handling around computing the hash in PSS.
EVP_DigestUpdate can tolerate zero length inputs. Also properly clean up
ctx in all codepaths.

Change-Id: I90889c6236f6bf74625ba9f967de36949a9a6f83
Reviewed-on: https://boringssl-review.googlesource.com/14327
Commit-Queue: David Benjamin <davidben@google.com>
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>
2017-03-23 15:07:08 +00:00
David Benjamin 96e744c176 Decouple PKCS#5 cipher lookup from OID table.
We still need to expose a suitable API for Chromium to consume, but the
core implementation itself should now be ready.

The supported cipher list is based on what EVP_get_cipherbynid currently
supports, excluding the entries which don't have OIDs.

BUG=54

Change-Id: I3befca0a34b330ec1f663a029a8fbf049a4406bd
Reviewed-on: https://boringssl-review.googlesource.com/14212
Commit-Queue: David Benjamin <davidben@google.com>
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>
2017-03-22 18:30:24 +00:00
David Benjamin 9292632c8d Add some PSS test vectors with non-zero salt length.
Change-Id: I8c8341fef2c141aa2460f634b596856f40cbbaba
Reviewed-on: https://boringssl-review.googlesource.com/14326
Reviewed-by: Steven Valdez <svaldez@google.com>
Commit-Queue: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-22 17:53:10 +00:00
David Benjamin 5e2d0c929c Add some more RSA-PSS verification tests.
Playing around with the code, we seem to have sufficient positive test
vectors for the logic around the high bits, but not negative test
vectors. Add some. Also add a negative test vector for the trailing
byte.

(For future reference, use openssl rsautl -raw for raw RSA operations
and openssl pkeyutil for EVP_PKEY_sign.)

Change-Id: I36eddf048e51e037fd924902cd13dcb3c62bfd02
Reviewed-on: https://boringssl-review.googlesource.com/14325
Commit-Queue: David Benjamin <davidben@google.com>
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>
2017-03-22 17:47:40 +00:00
Alessandro Ghedini 57e81e666a Name |select_certificate_cb| return values
The |select_certificate_cb| return values are somewhat confusing due
to the fact that they don't match the |cert_cb| ones, despite the
similarities between the two callbacks (they both have "certificate" in
the name! well, sort of).

This also documents the error return value (-1) which was previously
undocumented, and it expands the |SSL_CTX_set_select_certificate_cb|
documentation regarding retrial (by shamelessly copying from
|SSL_CTX_set_ticket_aead_method|).

Also updates other scattered documentation that was missed by previous
changes.

Change-Id: Ib962b31d08e6475e09954cbc3c939988b0ba13f7
Reviewed-on: https://boringssl-review.googlesource.com/14245
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>
2017-03-22 01:27:00 +00:00
Matthew Braithwaite cedc6f1824 Remove DHE ciphersuites from TLS.
They can be restored by compiling with -DBORINGSSL_ENABLE_DHE_TLS.

This is similar to 9c8c4188 for RC4 ciphers.

Change-Id: I7cd3421b108a024f1ee11f13a6df881c2d0de3c3
Reviewed-on: https://boringssl-review.googlesource.com/14284
Commit-Queue: Matt Braithwaite <mab@google.com>
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>
2017-03-21 23:55:10 +00:00
David Benjamin d851842228 Reduce crypto/pkcs8 dependency on OID table.
To remove the OID table from Chromium, we'll need to decouple a lot of
this code. In preparation for that, detach the easy cases from the OID
table. What remains is PBES, cipher, and digest OIDs which will be doing
in follow-up changes.

BUG=54

Change-Id: Ie205d23d042e21114ca1faf68917fdc870969d09
Reviewed-on: https://boringssl-review.googlesource.com/14209
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>
2017-03-21 21:10:00 +00:00
David Benjamin aea20c15c9 Fix potential memory leak in ASN1_TIME_to_generalizedtime()
If ret is allocated, it may be leaked on error.

(Imported from upstream's cdfb7809b6a365a0a7874afd8f8778c5c572f267 and
ffcdb0e6efb6fb7033b2cd29e8cca2e2fe355c14.)

Change-Id: I50ed9ad072cf80461d9527d0834b596a8c32e3d3
Reviewed-on: https://boringssl-review.googlesource.com/14315
Reviewed-by: Steven Valdez <svaldez@google.com>
Commit-Queue: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-21 18:10:51 +00:00
David Benjamin 5c12778948 Convert bio_test to GTest.
BUG=129

Change-Id: Iaf07075afaa2ea447e19a8c53ec0d29560d625b3
Reviewed-on: https://boringssl-review.googlesource.com/14207
Commit-Queue: David Benjamin <davidben@google.com>
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>
2017-03-21 17:39:57 +00:00
David Benjamin 2d05568a7b Fix out-of-memory condition in conf.
conf has the ability to expand variables in config files. Repeatedly doing
this can lead to an exponential increase in the amount of memory required.
This places a limit on the length of a value that can result from an
expansion.

Credit to OSS-Fuzz for finding this problem.

(Imported from upstream's 6a6213556a80ab0a9eb926a1d6023b8bf44f2afd. This
also import's upstream's ee1ccd0a41ad068957fe65ba7521e593b51bbad4 which
we had previously missed.)

Change-Id: I9be06a7e8a062b5adcd00c974a7b245226123563
Reviewed-on: https://boringssl-review.googlesource.com/14316
Reviewed-by: Steven Valdez <svaldez@google.com>
Commit-Queue: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-21 16:19:22 +00:00
David Benjamin fd67f61bb4 Fix bounds check in RSA_verify_PKCS1_PSS_mgf1 when sLen is -2.
(Imported from upstream's 04cf39207f94abf89b3964c7710f22f829a1a78f.)

The other half of the change was fixed earlier, but this logic was still
off. This code is kind of a mess and needs a rewrite, but import the
change to get it correct and sufficiently tested first.

(If we could take the sLen = -2 case away altogether, that would be
great...)

Change-Id: I5786e980f26648822633fc216315e8f77ed4d45b
Reviewed-on: https://boringssl-review.googlesource.com/14321
Reviewed-by: Steven Valdez <svaldez@google.com>
Commit-Queue: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-21 16:17:19 +00:00
David Benjamin 5916207dd3 Improve RSA-PSS test coverage around length bounds.
One test case is commented out, to be fixed in a follow-up.

Change-Id: I543c7f54e63837c6e8088fdcbb03226e0144b2e5
Reviewed-on: https://boringssl-review.googlesource.com/14320
Reviewed-by: Steven Valdez <svaldez@google.com>
Commit-Queue: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-21 16:15:32 +00:00
David Benjamin 8c6467976c Remove BIGNUM and CBIGNUM crypto/asn1 types.
These too appear to be unused now that the core parsers use CBS. They
also were buggy as they silently ignored sign bits. This removes all
ASN1_PRIMITIVE_FUNCS definitions.  (The code to use them still exists as
we're not ready to diverge on tasn_*. Current thinking is we'll
eventually just ditch the code rather than do so.)

Change-Id: I8d20e2989460dd593d62368cfbd083d5de1ee2a1
Reviewed-on: https://boringssl-review.googlesource.com/14324
Reviewed-by: Steven Valdez <svaldez@google.com>
Commit-Queue: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-21 16:07:05 +00:00
David Benjamin eb3028847e Remove crypto/asn1 LONG and ZLONG.
These have no consumers remaining. Upstream recently had a long series
of bugfixes for these types (2cbd4d98673d99cd7cb10715656b6d3727342e77,
e5afec1831248c767be7c5844a88535dabecc01a,
9abe889702bdc73f9490f611f54bf9c865702554,
2e5adeb2904dd68780fb154dbeb6e3efafb418bb). Rather than worry about this,
just remove the code.

Change-Id: I90f896aad096fc4979877e2006131e76c9ff023b
Reviewed-on: https://boringssl-review.googlesource.com/14323
Reviewed-by: Steven Valdez <svaldez@google.com>
Commit-Queue: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-21 16:06:23 +00:00
David Benjamin 2ddc461a3f Add additional RSA-PSS and RSA-OAEP tests.
Import test data from:
ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip

This is a set of RSA-PSS and RSA-OAEP test vectors including some edge cases
with unusual key sizes.

(Imported from upstream's 946a515a2b370dbadb1f8c39e3586a8f1e3cff1a.)

Change-Id: I1d8aa85a8578e47b26c74bb4e4c246975619d574
Reviewed-on: https://boringssl-review.googlesource.com/14318
Commit-Queue: David Benjamin <davidben@google.com>
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>
2017-03-21 14:55:36 +00:00
David Benjamin 6a53b99f34 Fix generate-coverage.sh.
It was not updated to exclude GTest. (Sometime later we really should
just write a productionized version of this that runs automatically and
portably. Preferably not in bash.)

Change-Id: I99c9d2370fa0a35641a9905e071b96b7fbd7a993
Reviewed-on: https://boringssl-review.googlesource.com/14319
Reviewed-by: Steven Valdez <svaldez@google.com>
Commit-Queue: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-21 14:54:47 +00:00
David Benjamin 076c6a3389 Fix a memory leak in X509_STORE_add_cert/crl error handling.
(Imported from upstream's c8ee68aa28889a1b7824ee399262536202f27cc0.)

Change-Id: If794793f766bf70fb35b60274e74d581fcb2b9de
Reviewed-on: https://boringssl-review.googlesource.com/14317
Commit-Queue: David Benjamin <davidben@google.com>
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>
2017-03-21 14:51:17 +00:00
David Benjamin aefc6b27e1 Fix a crash in print_notice.
(Imported from upstream's e6c53b0ced916633c8038736fde5613bf5b3e0dc.)

Change-Id: I165ce6ab9a162cb14a93ac8cab2e1f44a60fe961
Reviewed-on: https://boringssl-review.googlesource.com/14322
Commit-Queue: David Benjamin <davidben@google.com>
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>
2017-03-21 14:50:26 +00:00
David Benjamin b228541129 Convert asn1_test to GTest.
BUG=129

Change-Id: I0af881c6f50a558a220853084e53189b8919e41e
Reviewed-on: https://boringssl-review.googlesource.com/14206
Commit-Queue: David Benjamin <davidben@google.com>
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>
2017-03-21 14:31:01 +00:00
David Benjamin 73812e06b0 Fix SSLv3 version check in BoGo.
Static RSA key exchange in SSLv3 does not have a length prefix. We were
checking the ClientHello version rather than the final version.

Change-Id: I2d0e9d3b5a368a7caf8b1ca69f1631400a847f52
Reviewed-on: https://boringssl-review.googlesource.com/14314
Commit-Queue: David Benjamin <davidben@google.com>
Commit-Queue: Matt Braithwaite <mab@google.com>
Reviewed-by: Matt Braithwaite <mab@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-20 22:12:16 +00:00
Alessandro Ghedini edb729959f Fix typo in the |ssl_ticket_aead_success| documentation
Change-Id: I6d07a8e146a925a14dbf5d11b4e8a57ef6eee39c
Reviewed-on: https://boringssl-review.googlesource.com/14244
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>
2017-03-20 19:10:10 +00:00
Alessandro Ghedini 3c8652d0c6 tool: fix typo in -root-certs description
Without the space the help output is:

    Implies thatverification is required.

Change-Id: If7ff91ef70f2d968da5f8c76de562996c83dff2f
Reviewed-on: https://boringssl-review.googlesource.com/14246
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>
2017-03-20 17:39:42 +00:00
Victor Vasiliev 438229a8d7 Correct a typo in ASN.1 type name.
Change-Id: I5879d78ce22163c66bf8e4c05f3a7d1b6dbbd9d9
Reviewed-on: https://boringssl-review.googlesource.com/14304
Reviewed-by: Steven Valdez <svaldez@google.com>
Commit-Queue: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-16 21:57:58 +00:00
David Benjamin 48e1d180a4 Restore SSL_CTX_set_ecdh_auto compatibility hook.
This was inadvertently dropped in
59015c365b. Python otherwise configures
P-256 if it assumes our OpenSSL predate's 1.0.2's multi-curve support.
This disables X25519, our preferred curve.

Change-Id: Ibf758583ea53e68c56667f16ee7096656bac719b
Reviewed-on: https://boringssl-review.googlesource.com/14208
Commit-Queue: David Benjamin <davidben@google.com>
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>
2017-03-14 14:54:45 +00:00
Adam Langley 2070f8ad91 Apply bugs to second, TLS 1.3 ClientHello.
Based on elements of the Bugs structure, runner will tweak a ClientHello
message after parsing. However, unless the same tweaks are made to a
second ClientHello in a TLS 1.3 connection, it might appear that they
don't match.

Change-Id: I4467c8ece12dc75c7c7b0fad9e622e6783c55f21
Reviewed-on: https://boringssl-review.googlesource.com/14224
Commit-Queue: Adam Langley <alangley@gmail.com>
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>
2017-03-11 16:33:50 +00:00
David Benjamin 707af294a8 Support asynchronous ticket decryption with TLS 1.3.
This shuffles a bit of the code around session resumption in TLS 1.3 to
make the async point cleaner to inject. It also fills in cipher and
tlsext_hostname more uniformly.

Filling in the cipher on resumption is a no-op as SSL_SESSION_dup
already copies it, but avoids confusion should we ever implement TLS
1.3's laxer cipher matching on the server. Not filling in
tlsext_hostname on resumption was an oversight; the relevant check isn't
whether we are resuming but whether we have a fresh SSL_SESSION to fill
things into.

Change-Id: Ic02eb079ff228ce4a4d3e0de7445e18cd367e8b2
Reviewed-on: https://boringssl-review.googlesource.com/14205
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-03-11 00:05:29 +00:00
Adam Langley 4c341d0299 Support asynchronous ticket decryption with TLS 1.0–1.2.
This change adds support for setting an |SSL_TICKET_AEAD_METHOD| which
allows a caller to control ticket encryption and decryption to a greater
extent than previously possible and also permits asynchronous ticket
decryption.

This change only includes partial support: TLS 1.3 work remains to be
done.

Change-Id: Ia2e10ebb3257e1a119630c463b6bf389cf20ef18
Reviewed-on: https://boringssl-review.googlesource.com/14144
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-03-11 00:04:18 +00:00
David Benjamin be49706c42 Rename initial_ctx to session_ctx.
This makes its purpose clearer. That the session cache is based on the
initial SSL_CTX is confusing (it's a remnant of OpenSSL's backwards
session resumption ordering), but we're probably stuck with it.
Relatedly, document SSL_set_SSL_CTX better.

Change-Id: I2832efc63f6c959c5424271b365825afc7eec5e4
Reviewed-on: https://boringssl-review.googlesource.com/14204
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-03-10 22:50:46 +00:00
David Benjamin 93103177a5 Remove 'file:' feature in v3_pci.c's CONF hooks.
This makes it easier to build a subset of BoringSSL which doesn't depend
on the filesystem (though perhaps it's worth a build define for that
now). This hook is also generally surprising. CONF hooks are bad enough
when they don't open arbitrary files.

Change-Id: Ibf791162dd3d4cec8117eb49ff0cd716a1c54abd
Reviewed-on: https://boringssl-review.googlesource.com/14166
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-10 17:12:55 +00:00
David Benjamin 91222b8d38 Fix configuring the empty cipher list.
Although it returns failure, the cipher list should still be updated.
Conscrypt relies on this behavior to support a Java API edge case.

Change-Id: If58efafc6a4a81e85a0e2ee2c38873a7a4938123
Reviewed-on: https://boringssl-review.googlesource.com/14165
Reviewed-by: Kenny Root <kroot@google.com>
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>
2017-03-10 01:20:25 +00:00
Matthew Braithwaite 6ad20dc912 Move error-on-empty-cipherlist into ssl_create_cipher_list().
It's more consistent to have the helper function do the check that
its every caller already performs.  This removes the error code
SSL_R_LIBRARY_HAS_NO_CIPHERS in favor of SSL_R_NO_CIPHER_MATCH.

Change-Id: I522239770dcb881d33d54616af386142ae41b29f
Reviewed-on: https://boringssl-review.googlesource.com/13964
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>
2017-03-09 17:31:45 +00:00
Steven Valdez 130d529b71 Adding version to AEAD.
This in preparation of 0-RTT which needs the AEAD version as part of
early data, before the full version negotiation.

BUG=76

Change-Id: Ief68bc69d794da6e55bb9208977b35f3b947273b
Reviewed-on: https://boringssl-review.googlesource.com/14104
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>
2017-03-08 19:12:39 +00:00
Adam Langley d04ca95356 Add |SSL[_CTX]_set_chain_and_key|.
This allows a caller to configure a serving chain without dealing with
crypto/x509.

Change-Id: Ib42bb2ab9227d32071cf13ab07f92d029643a9a6
Reviewed-on: https://boringssl-review.googlesource.com/14126
Commit-Queue: Adam Langley <alangley@gmail.com>
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>
2017-03-08 19:11:57 +00:00
Adam Langley c77ea04c81 Enable RSA AVX2 code.
This was disabled because we couldn't test it. We now have SDE for
testing which, even if it's not running on a builder yet, confirms that
this passes tests for all current and past Intel chips.

Change-Id: Iad74cc9944ee85557bb45c981751f84f335fb6c8
Reviewed-on: https://boringssl-review.googlesource.com/14010
Commit-Queue: Adam Langley <alangley@gmail.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-03-08 17:28:12 +00:00
David Benjamin 35ac5b7500 Export server-side ticket_age skew.
We'll measure this value to guide what tolerance to use in the 0-RTT
anti-replay mechanism. This also fixes a bug where we were previously
minting ticket_age_add-less tickets on the server. Add a check to reject
all those tickets.

BUG=113

Change-Id: I68e690c0794234234e0d0500b4b9a7f79aea641e
Reviewed-on: https://boringssl-review.googlesource.com/14068
Reviewed-by: Steven Valdez <svaldez@google.com>
Commit-Queue: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-08 14:59:01 +00:00
Adam Langley fe36672bf5 Allow users of the |CRYPTO_BUFFER|-based methods to verify certs after the handshake.
Previously, the |CRYPTO_BUFFER|-based methods always rejected
certificate chains because none of the current callbacks is suitable to
use. In the medium-term, we want an async callback for this but, for
now, we would like to get Chromium working. Chromium already installs a
no-op callback (except for the logic that was moved into BoringSSL in
a58baaf9e6) and so this hack will suffice
for Chromium.

Change-Id: Ie44b7b32b9e42f503c47b072e958507754136d72
Reviewed-on: https://boringssl-review.googlesource.com/14125
Commit-Queue: Adam Langley <agl@google.com>
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>
2017-03-08 01:09:42 +00:00
Adam Langley 0cade989e7 Make the no-op verify function push an error.
(Otherwise it's a pretty opaque failure.)

Change-Id: I164b237eebe2641f2148bb705966da74b399a618
Reviewed-on: https://boringssl-review.googlesource.com/14124
Commit-Queue: Adam Langley <agl@google.com>
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>
2017-03-08 01:03:05 +00:00
Brian Smith b6473199a3 Avoid the error case in |bn_mul_mont|.
On 32-bit x86, |bn_mul_mont| returns 0 when the modulus has less than
four limbs. Instead of calling |bn_mul_mont| and then falling back to
the |BN_mul|+|BN_from_montgomery_word| path for small moduli, just
avoid calling |bn_mul_mont| at all for small moduli.

This allows us to more clearly understand exactly when the fallback
code path, which is a timing side channel, is taken. This change makes
it easier to start minimizing this side channel.

The limit is set at 128 bits, which is four limbs on 32-bit and two
limbs on 64-bit platforms. Do this consistently on all platforms even
though it seems to be needed only for 32-bit x86, to minimize platform
variance: every platform uses the same cut-off in terms of input size.
128 bits is small enough to allow even questionably small curves, like
secp128r1, to use the |bn_mul_mont| path, and is way too small for RSA
and FFDH, so this change shouldn't have any security impact other than
the positive impact of simplifying the control flow.

Change-Id: I9b68ae33dc2c86b54ed4294839c7eca6a1dc11c0
Reviewed-on: https://boringssl-review.googlesource.com/14084
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-07 23:30:13 +00:00
David Benjamin 54689ed91e Move ssl_verify_alarm_type into ssl_x509.c.
It's only called from within that file.

Change-Id: I281c9eb1ea25d9cfbec492ba8a4d007f45ae2635
Reviewed-on: https://boringssl-review.googlesource.com/14027
Reviewed-by: Adam Langley <agl@google.com>
2017-03-07 23:14:16 +00:00
David Benjamin ab1d28e305 Trim x509.h includes.
There are still a few x509.h includes outside ssl_x509.c and ssl_file.c
due to referencing X509_V_* values, but otherwise these includes are no
longer needed.

Change-Id: Ide458e01358dc2ddb6838277d074ad249e599040
Reviewed-on: https://boringssl-review.googlesource.com/14026
Reviewed-by: Adam Langley <agl@google.com>
2017-03-07 23:13:49 +00:00
David Benjamin 8ebeabf0e2 Add SSL_CTX_get_ciphers.
This is an API from OpenSSL 1.1.0 which is a little risky to add ahead
of bumping OPENSSL_VERSION_NUMBER, but anything which currently builds
against BoringSSL already had an #ifdef due to the
ssl_cipher_preference_list_st business anyway.

Bump BORINGSSL_API_VERSION to make it easier to patch envoy for this.

BUG=6

Change-Id: If8307e30eb069bbd7dc4b8447b6e48e83899d584
Reviewed-on: https://boringssl-review.googlesource.com/14067
Reviewed-by: Steven Valdez <svaldez@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-03 17:16:18 +00:00
David Benjamin f29c429324 Remove support for old-style SSL_PRIVATE_KEY_METHOD types.
Everything has been updated to return the ECDSA curve.

Change-Id: Iee8fafb576c0ff92d9a47304d59cc607b5faa112
Reviewed-on: https://boringssl-review.googlesource.com/14066
Commit-Queue: David Benjamin <davidben@google.com>
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>
2017-03-03 15:52:08 +00:00
David Benjamin f465461062 Add SSL_get0_peer_certificates.
This adds a CRYPTO_BUFFER getter for the peer certificate chain.  Other
things we need for Chromium:

- Verification callback. Ultimately, we want an asynchronous one, but a
  synchronous one will do for now.

- Configure client cert chain without X509

I've also removed the historical note about SSL_SESSION serialization.
That was years ago and we've since invalidated all serialized client
sessions.

BUG=671420

Change-Id: I2b3bb010f9182e751fc791cdfd7db44a4ec348e6
Reviewed-on: https://boringssl-review.googlesource.com/14065
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>
2017-03-03 02:17:31 +00:00
Steven Valdez 924a352d1b Remove experimental TLS 1.3 short record header extension.
Due to middlebox and ecosystem intolerance, short record headers are going to
be unsustainable to deploy.

BUG=119

Change-Id: I20fee79dd85bff229eafc6aeb72e4f33cac96d82
Reviewed-on: https://boringssl-review.googlesource.com/14044
Reviewed-by: Steven Valdez <svaldez@google.com>
Commit-Queue: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-02 22:39:17 +00:00
Steven Valdez 9ea9f9ce51 Updating fuzzer corpus
Change-Id: Iaf31cc5978322fb45aca43b39178ac998dabb11a
Reviewed-on: https://boringssl-review.googlesource.com/14064
Reviewed-by: Steven Valdez <svaldez@google.com>
Commit-Queue: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-02 22:26:38 +00:00
Adam Langley d6c22ee938 Add |SSL_get0_server_requested_CAs|.
This function is a |CRYPTO_BUFFER|-based method for getting the X.509
names from a CertificateRequest.

Change-Id: Ife26f726d3c1a055b332656678c2bc560b5a66ec
Reviewed-on: https://boringssl-review.googlesource.com/14013
Commit-Queue: Adam Langley <agl@google.com>
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>
2017-03-02 21:04:53 +00:00
David Benjamin 919d8cf94e Sync util/bot with Chromium.
Change-Id: Iad15c9b824ca48e6c8a0e5f74fb2d296b3c1170e
Reviewed-on: https://boringssl-review.googlesource.com/14032
Commit-Queue: David Benjamin <davidben@google.com>
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-02 18:45:14 +00:00
Adam Langley 84cd49385c Don't pass |overhead_len| when testing “open” speed.
It's not needed and some compilers warn about it.

Change-Id: I45ace0db3e9773300387df9e319af4dd5a50d3dc
Reviewed-on: https://boringssl-review.googlesource.com/14011
Reviewed-by: Adam Langley <agl@google.com>
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>
2017-03-02 18:38:16 +00:00
David Benjamin a58baaf9e6 Forbid the server certificate from changing on renego.
This allows us to move the code from Chrome into BoringSSL itself.

BUG=126

Change-Id: I04b4f63008a6de0a58dd6c685c78e9edd06deda6
Reviewed-on: https://boringssl-review.googlesource.com/14028
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>
2017-03-01 23:26:50 +00:00
David Benjamin ad8f5e1de9 Don't use long for timestamps.
This is the first part to fixing the SSL stack to be 2038-clean.
Internal structures and functions are switched to use OPENSSL_timeval
which, unlike timeval and long, are suitable for timestamps on all
platforms.

It is generally accepted that the year is now sometime after 1970, so
use uint64_t for the timestamps to avoid worrying about serializing
negative numbers in SSL_SESSION.

A follow-up change will fix SSL_CTX_set_current_time_cb to use
OPENSSL_timeval. This will require some coordinating with WebRTC.
DTLSv1_get_timeout is left alone for compatibility and because it stores
time remaining rather than an absolute time.

BUG=155

Change-Id: I1a5054813300874b6f29e348f9cd8ca80f6b9729
Reviewed-on: https://boringssl-review.googlesource.com/13944
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>
2017-03-01 21:58:38 +00:00
David Benjamin 7dd4e429a5 Convert x25519_test to GTest.
This also adds a few missing assertions (X25519 returns true in normal
cases and, even when it returns zero, it still writes to out.)

BUG=129

Change-Id: I63f7e9025f88b2ec309382b66fc915acca6513a9
Reviewed-on: https://boringssl-review.googlesource.com/14030
Reviewed-by: Steven Valdez <svaldez@google.com>
Commit-Queue: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-03-01 21:46:11 +00:00
David Benjamin 11c82895d7 Remove support for blocking DTLS timeout handling.
The DTLS stack has two very different APIs for handling timeouts. In
non-blocking mode, timeouts are driven externally by the caller with
DTLSv1_get_timeout. In blocking mode, timeouts are driven by the BIO by
calling a BIO_ctrl with BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT.

The latter is never used by consumers, so remove support for it.
BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT implicitly depends on struct timeval
being used for timestamps, which we would like to remove. Without this,
the only public API which relies on this is the testing-only
SSL_CTX_set_current_time_cb which is BoringSSL-only and we can change at
our leisure.

BUG=155

Change-Id: Ic68fa70afab2fa9e6286b84d010eac8ddc9d2ef4
Reviewed-on: https://boringssl-review.googlesource.com/13945
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>
2017-03-01 19:59:28 +00:00
David Benjamin 7e42999122 Convert evp_extra_test into GTest.
BUG=129

Change-Id: Ie64a445a42fb3a6d16818b1fabba8481e6e9ad94
Reviewed-on: https://boringssl-review.googlesource.com/14029
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>
2017-03-01 18:32:29 +00:00
Adam Langley 39425b0f36 Add |TLS_with_buffers_method|.
This allows a caller to get an |SSL_METHOD| that is free of crypto/x509.

Change-Id: I088e78310fd3ff5db453844784e7890659a633bf
Reviewed-on: https://boringssl-review.googlesource.com/14009
Reviewed-by: Adam Langley <agl@google.com>
2017-03-01 00:24:40 +00:00
Adam Langley d5c565a98d Name ssl_x509.c functions consistently.
All the other |X509_METHOD| functions have their type in the name. The
|CERT|-based functions happened not to because they were first, but
that's not a good reason.

Change-Id: I5bcd8a5fb1d1db6966686700e293d8b1361c0095
Reviewed-on: https://boringssl-review.googlesource.com/14007
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>
2017-02-28 23:33:05 +00:00
Adam Langley 94a62e61aa Hang ssl_auto_chain_if_needed off |X509_METHOD|.
Change-Id: I6609b0e62ea13d14578ccbd945803a27e01ed488
Reviewed-on: https://boringssl-review.googlesource.com/13972
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-02-28 23:07:02 +00:00
Adam Langley 2a3b3439c8 Move X509-related verification code into ssl_x509.c.
Change-Id: I9f94033036550ae85c98cd4e09584972b4441b5d
Reviewed-on: https://boringssl-review.googlesource.com/13971
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-02-28 22:57:34 +00:00
Adam Langley 415c010d4a Make all X509-related functions check the X509_METHOD.
We don't have a way to create an X509-less |SSL| yet but, when we do,
it'll be bad to call any X509-related functions on it. This change adds
an assert to every X509-related call to catch this.

Change-Id: Iec1bdf13baa587ee3487a7cfdc8a105bee20f5ca
Reviewed-on: https://boringssl-review.googlesource.com/13970
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-02-28 22:51:52 +00:00
Adam Langley 0bdef09263 Check CA names during the handshake.
Rather than store CA names and only find out that they're unparsable
when we're asked for a |STACK_OF(X509_NAME)|, check that we can parse
them all during the handshake. This avoids changing the semantics with
the previous change that kept CA names as |CRYPTO_BUFFER|s.

Change-Id: I0fc7a4e6ab01685347e7a5be0d0579f45b8a4818
Reviewed-on: https://boringssl-review.googlesource.com/13969
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-02-28 22:33:05 +00:00
Adam Langley 34b4c829fd Hold CA names as |CRYPTO_BUFFER|s.
This change converts the CA names that are parsed from a server's
CertificateRequest, as well as the CA names that are configured for
sending to clients in the same, to use |CRYPTO_BUFFER|.

The |X509_NAME|-based interfaces are turned into compatibility wrappers.

Change-Id: I95304ecc988ee39320499739a0866c7f8ff5ed98
Reviewed-on: https://boringssl-review.googlesource.com/13585
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-02-28 22:24:31 +00:00
Adam Langley 2ff7933f22 Add test for |SSL_get_client_CA_list|.
Change-Id: Ibea6a9d52b000876740097f98c6891db4772371b
Reviewed-on: https://boringssl-review.googlesource.com/14008
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-02-28 22:17:39 +00:00
David Benjamin 0d3c96337a Build with -fsanitize-address-use-after-scope if -DASAN=1
This would have caught
https://boringssl-review.googlesource.com/c/12400/ and similar classes
of errors with using CBB. A follow-up change will update the builders
to use -DASAN=1 for ASan.

Change-Id: I37817cb1d6bfd5c82ff0b0afaecc8bbbf506bb92
Reviewed-on: https://boringssl-review.googlesource.com/14025
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-02-28 20:07:09 +00:00
David Benjamin 591f251bf3 Remove direct calls to BN_mod_exp.
Within the library, we never need to exponentiate modulo an even number.
In fact, all the remaining BN_mod_exp calls are modulo an odd prime.
This extends 617804adc5 to the rest of the
library.

Change-Id: I4273439faa6a516c99673b28f8ae38ddfff7e42d
Reviewed-on: https://boringssl-review.googlesource.com/14024
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-02-28 18:00:02 +00:00
Adam Langley ba9557d0ef Benchmark open & seal separately for AES-GCM-SIV.
AES-GCM-SIV (potentially) runs at different speeds for opening and
sealing. (Since sealing is fundamentally two-pass, while opening need
not be.)

This change benchmarks AES-GCM-SIV for each direction.

Change-Id: Ic221c46eea7319ced8ef1f1dec0427b98f6a58ef
Reviewed-on: https://boringssl-review.googlesource.com/14004
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-02-28 17:41:35 +00:00
David Benjamin 218f51bcef Fix Android bots.
Change-Id: I62a14a52237cbcb1706df6ab63014370d9228be1
Reviewed-on: https://boringssl-review.googlesource.com/13946
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-02-27 23:18:25 +00:00
Adam Langley 898be92b67 Support P-224 certificates as a server.
Change-Id: I3bc1e46fb94104c4ae31c1c98fa0d5a931e5f954
Reviewed-on: https://boringssl-review.googlesource.com/13974
Commit-Queue: Adam Langley <agl@google.com>
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>
2017-02-27 21:27:39 +00:00
Adam Langley be2ee342d3 Update AES-GCM-SIV to match revision four of the draft.
This change updates AES-GCM-SIV to match revision four of the draft[1].
See [2] for the reasons behind the changes.

[1] https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-04
[2] https://www.ietf.org/mail-archive/web/cfrg/current/msg08895.html

Change-Id: Icacfefbd2f470186051551ea227c9d6c6dd6e786
Reviewed-on: https://boringssl-review.googlesource.com/13973
Reviewed-by: Adam Langley <alangley@gmail.com>
Commit-Queue: Adam Langley <alangley@gmail.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-02-26 18:37:53 +00:00
Alessandro Ghedini 5ae416528a Allow multiple IDN xn-- indicators
Update the X509v3 name parsing to allow multiple xn-- international
domain name indicators in a name.  Previously, only allowed one at
the beginning of a name, which was wrong.

(Imported from upstream's 31d1d3741f16bd80ec25f72dcdbf6bbdc5664374)

Change-Id: I93f1db7a5920305569af23f9f2b30ab5cc226521
Reviewed-on: https://boringssl-review.googlesource.com/13984
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-02-24 21:52:18 +00:00
David Benjamin adec7726ec Remove SSL_CIPHER_has_MD5_HMAC.
It has no more callers.

Change-Id: I587ccb3b63810ed167febf7a65ba85106d17a300
Reviewed-on: https://boringssl-review.googlesource.com/13911
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>
2017-02-22 22:20:56 +00:00
Michel Lespinasse de5c325e04 Fix SSL_write doc comment
Change-Id: Icb01cd3ff88eb3fa8a7d7a1e9ead568ba20eb748
Reviewed-on: https://boringssl-review.googlesource.com/13965
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>
2017-02-22 14:05:44 +00:00
Matthew Braithwaite a57dcfb69c Add new cipherlist-setting APIs that reject nonsense.
The new APIs are SSL_CTX_set_strict_cipher_list() and
SSL_set_strict_cipher_list().  They have two motivations:

First, typos in cipher lists can go undetected for a long time, and
can have surprising consequences when silently ignored.

Second, there is a tendency to use superstition in the construction of
cipher lists, for example by "turning off" things that do not actually
exist.  This leads to the corrosive belief that DEFAULT and ALL ought
not to be trusted.  This belief is false.

Change-Id: I42909b69186e0b4cf45457e5c0bc968f6bbf231a
Reviewed-on: https://boringssl-review.googlesource.com/13925
Commit-Queue: Matt Braithwaite <mab@google.com>
Reviewed-by: Matt Braithwaite <mab@google.com>
2017-02-22 00:09:27 +00:00
Matthew Braithwaite c4796c92e0 ECDSA: const EC_KEY* arguments where possible.
Change-Id: Ic4bdad4631d603a9944312e13997ec98739a45ab
Reviewed-on: https://boringssl-review.googlesource.com/13924
Commit-Queue: Matt Braithwaite <mab@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: Matt Braithwaite <mab@google.com>
2017-02-18 06:22:01 +00:00
David Benjamin 699e55bb0e Unexport time_support.h.
These are only used by crypto/asn1 and not externally.

Change-Id: I2e6a28828fd81a4e3421eed1e98f0a65197f4b88
Reviewed-on: https://boringssl-review.googlesource.com/13868
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>
2017-02-17 21:41:56 +00:00
David Benjamin fc02b59b27 Move tmp.extended_master_secret to SSL_HANDSHAKE.
The two non-trivial changes are:

1. The public API now queries it out of the session. There is a long
   comment over the old field explaining why the state was separate, but
   this predates EMS being forbidden from changing across resumption. It
   is not possible for established_session and the socket to disagree on
   EMS.

2. Since SSL_HANDSHAKE gets reset on each handshake, the check that EMS
   does not change on renego looks different. I've reworked that function a
   bit, but it should have the same effect.

Change-Id: If72e5291f79681381cf4d8ceab267f76618b7c3d
Reviewed-on: https://boringssl-review.googlesource.com/13910
Commit-Queue: David Benjamin <davidben@google.com>
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>
2017-02-17 21:36:37 +00:00
David Benjamin 45738dd496 Move new_cipher and new_session to SSL_HANDSHAKE.
This lets us trim another two pointers of per-connection state.

Change-Id: I2145d529bc25b7e24a921d01e82ee99f2c98867c
Reviewed-on: https://boringssl-review.googlesource.com/13804
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>
2017-02-17 20:48:31 +00:00
David Benjamin 12709db355 Stop reporting SSL_R_SHUTDOWN_WHILE_IN_INIT.
This effectively reverts b9824e2417. This
error seems to have mostly just caused confusion in logs and the
occasional bug around failing to ERR_clear_error. Consumers tend to
blindly call SSL_shutdown when tearing down an SSL (to avoid
invalidating sessions). This means handshake failures trigger two
errors, which is screwy.

Go back to the old behavior where SSL_shutdown while SSL_in_init
silently succeeds.

Change-Id: I1fcfc92d481b97c840847dc39afe59679cd995f2
Reviewed-on: https://boringssl-review.googlesource.com/13909
Commit-Queue: David Benjamin <davidben@google.com>
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>
2017-02-17 19:49:59 +00:00
David Benjamin c92f29dcc5 Remove freelist_max_len.
Node has since been patched.

Change-Id: If25eecabfc83ef9fd36c531c9ca9db2911de010e
Reviewed-on: https://boringssl-review.googlesource.com/13908
Commit-Queue: David Benjamin <davidben@google.com>
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>
2017-02-17 17:41:42 +00:00
David Benjamin ced1895961 Fix mis-import of upstream cc598f321fbac9c04da5766243ed55d55948637d.
Noticed this comparing our and upstream's ASN.1 code. Somehow I missed
this line in cb852981cd. This change is a
no-op as our only ASN1_EX_COMBINE field is an ASN1_CHOICE which does not
read aclass.

Change-Id: I011f2f6eadd3939ec5f0b346c4eb7d14e406e3cd
Reviewed-on: https://boringssl-review.googlesource.com/13833
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>
2017-02-17 01:21:29 +00:00
David Benjamin c4d5925ca6 Fix various malloc failure checks.
asn1_template_noexp_d2i call ASN1_item_ex_free(&skfield,...) on error.

Reworked error handling in asn1_item_ex_combine_new:
- call ASN1_item_ex_free and return the correct error code if
  ASN1_template_new failed.
- dont call ASN1_item_ex_free if ASN1_OP_NEW_PRE failed.

Reworked error handing in x509_name_ex_d2i and x509_name_encode.

(Imported from upstream's 748cb9a17f4f2b77aad816cf658cd4025dc847ee.)

I believe the tasn1_new.c change is a no-op since we have no
ASN1_OP_NEW_PRE hooks anymore. I'm not sure what the commit message is
referring to with ASN1_template_new. It also seems odd as
ASN1_item_ex_free should probably be able to survive *pval being NULL.
Whatever.

We'd previously tried to fix x509_name_ex_d2i, but I think ours wasn't
quite right. (This thing is a mess...) I've aligned that function with
upstream.

Change-Id: Ie71521cd8a1ec357876caadd13be1ce247110f76
Reviewed-on: https://boringssl-review.googlesource.com/13831
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>
2017-02-17 01:11:21 +00:00
David Benjamin ec1d9637e1 Fix crashes in EVP_CIPHER if cipher_data was not allocated.
(Imported from upstream's 1222d273d36277f56c3603a757240c386d55f318.)

We'd fixed half of these, but the other half are probably unreachable
from code that ran under malloc tests, so we never noticed. It's
puzzling why upstream did both this and
166e365ed84dfabec3274baf8a9ef8aa4e677891. It seems you only need one of
them.

Change-Id: I08074358134180c6661600b66958ba861e7726fb
Reviewed-on: https://boringssl-review.googlesource.com/13832
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>
2017-02-17 01:11:14 +00:00
David Benjamin fb2ac390f5 Convert ec_test to GTest.
BUG=129

Change-Id: Id7a92285601ff4276f4015eaee290bf77aa22b47
Reviewed-on: https://boringssl-review.googlesource.com/13628
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>
2017-02-16 23:33:48 +00:00
David Benjamin c5be327ef9 Tidy up EVP_PKEY_CTX_dup and fix malloc error crash.
If copy fails, we shouldn't call cleanup. Also remove some pointless
NULL checks after EVP_PKEY_up_ref.

See also upstream's 748cb9a17f4f2b77aad816cf658cd4025dc847ee.

Change-Id: I2acb6892cde1ab662ca6a620d87179f9be609cba
Reviewed-on: https://boringssl-review.googlesource.com/13830
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>
2017-02-16 23:24:53 +00:00
David Benjamin 3e8b782c0c Remove "raw" versions of PKCS8_encrypt and PKCS8_decrypt.
These were added in an attempt to deal with the empty vs. NULL confusion
in PKCS#12. Instead, PKCS8_encrypt and PKCS8_decrypt already treated
NULL special. Since we're stuck with supporting APIs like those anyway,
Chromium has been converted to use that feature. This cuts down on the
number of APIs we need to decouple from crypto/asn1.

BUG=54

Change-Id: Ie2d4798d326c5171ea5d731da0a2c11278bc0241
Reviewed-on: https://boringssl-review.googlesource.com/13885
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>
2017-02-16 23:04:15 +00:00
Adam Langley 628f518cdc bn/asm/x86_64*: add DWARF CFI directives.
(Imports upstream's 76e624a003db22db2d99ece04a15e20fe44c1fbe.)

Also includes the following fixes:
https://github.com/openssl/openssl/pull/2582
https://github.com/openssl/openssl/pull/2655

Change-Id: I6086a87a534d152cdbff104c62ad9dcd9b4e012a
Reviewed-on: https://boringssl-review.googlesource.com/13783
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>
2017-02-16 23:03:48 +00:00
David Benjamin b91b9a8967 Convert rsa_test to GTest.
BUG=129

Change-Id: I603054193a20c2bcc3ac1724f9b29d6384d9f62a
Reviewed-on: https://boringssl-review.googlesource.com/13626
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>
2017-02-16 22:23:16 +00:00
David Benjamin 98f5dc30ba perlasm/x86_64-xlate.pl: recognize even offset(%reg) in cfa_expression.
This is handy when "offset(%reg)" is a perl variable.

(Imported from upstream's 1cb35b47db8462f5653803501ed68d33b10c249f.)

Change-Id: I2f03907a7741371a71045f98318e0ab9396a8fc7
Reviewed-on: https://boringssl-review.googlesource.com/13906
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-02-16 22:21:25 +00:00
David Benjamin f3cc7a3366 perlasm/x86_64-xlate.pl: fix pair of typo-bugs in the new cfi_directive.
.cfi_{start|end}proc and .cfi_def_cfa were not tracked.

(Imported from upstream's 88be429f2ed04f0acc71f7fd5456174c274f2f76.)

Change-Id: I6abd480255218890349d139b62f62144b34c700d
Reviewed-on: https://boringssl-review.googlesource.com/13905
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-02-16 22:21:18 +00:00
David Benjamin 4c4053191a perlasm/x86_64-xlate.pl: typo fix in comment.
(Imported from upstream's fa3f83552f53447deced45579865cec9f55a947e.)

Change-Id: I659422a604b9d1d61334e09dff0c1de3aedb2d04
Reviewed-on: https://boringssl-review.googlesource.com/13904
Commit-Queue: David Benjamin <davidben@google.com>
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>
2017-02-16 22:20:33 +00:00
Adam Langley cb1b333c2b x86_64 assembly pack: Win64 SEH face-lift.
(Imports upstream's 384e6de4c7e35e37fb3d6fbeb32ddcb5eb0d3d3f. Changes to
P-256 assembly dropped because we're so different there.)

 - harmonize handlers with guidelines and themselves;
 - fix some bugs in handlers;

Change-Id: Ic0b6a37bed6baedc50448c72fab088327f12898d
Reviewed-on: https://boringssl-review.googlesource.com/13782
Commit-Queue: 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>
Reviewed-by: David Benjamin <davidben@google.com>
2017-02-16 21:55:04 +00:00
David Benjamin dc90e39291 Clear the last GTest warning suppression.
TEST_P didn't work without fixing the suppression, so I went ahead and
fixed it across the entire project.

BUG=129

Change-Id: I5fe417f720040b627acfb3ed2063afdc85dfa908
Reviewed-on: https://boringssl-review.googlesource.com/13824
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-02-16 19:03:32 +00:00
David Benjamin 5960a90964 Move sid_ctx from SSL/SSL_CTX to CERT.
This reduces us from seven different configuration patterns to six (see
comment #2 of linked bug). I do not believe there is any behavior change
here as SSL_set_SSL_CTX already manually copied the field. It now gives
us a nice invariant: SSL_set_SSL_CTX overrides all and only the
dual-SSL/SSL_CTX options hanging off of CERT.

BUG=123

Change-Id: I1ae06b791fb869917a6503cee41afb2d9be53d89
Reviewed-on: https://boringssl-review.googlesource.com/13865
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>
2017-02-16 18:59:24 +00:00
David Benjamin 0f28691d3d Fix a few typos.
(Imported from upstream's 7e12cdb52e3f4beff050caeecf3634870bb9a7c4.)

Change-Id: I9a6bba72c039e45ae5c0302a8a3dff7148cf1897
Reviewed-on: https://boringssl-review.googlesource.com/13869
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>
2017-02-16 18:50:51 +00:00
David Benjamin 26e1ff3dfb Remove some unnecessary return values.
I'm not sure why the SSL versions of these functions return int while
the SSL_CTX version returns void. It looks like this dates to
https://boringssl-review.googlesource.com/c/1491/, of which the initial
upload was an SSL_ctrl macro. I guess one of the ints got accidentally
preserved in conversion.

(No existing caller, aside from bssl_shim, checks the result.)

Change-Id: Id54309c1aa03462d520b9a45cdfdefdd2cdd1298
Reviewed-on: https://boringssl-review.googlesource.com/13866
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>
2017-02-16 18:21:47 +00:00
Steven Valdez 27a9e6ae1b Adding ALPN to session.
0-RTT requires matching the selected ALPN parameters against those in
the session. Stash the ALPN value in the session in TLS 1.3, so we can
recover it.

BUG=76

Change-Id: I8668b287651ae4deb0bf540c0885a02d189adee0
Reviewed-on: https://boringssl-review.googlesource.com/13845
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>
2017-02-16 17:33:23 +00:00
Alessandro Ghedini f6d64efd19 tool: show if server sent SCT staple
Change-Id: I02e33a89345eaa935c06e3e6d88f7611049f1387
Reviewed-on: https://boringssl-review.googlesource.com/13884
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>
2017-02-16 01:20:37 +00:00
David Benjamin b19b6626c5 Convert chacha_test to GTest.
BUG=129

Change-Id: Ibbd6d0804a75cb17ff33f64d4cdf9ae80b26e9df
Reviewed-on: https://boringssl-review.googlesource.com/13867
Reviewed-by: Steven Valdez <svaldez@google.com>
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>
2017-02-15 17:16:44 +00:00
David Benjamin 1d5a570627 Don't hardcode GTest sources.
We've already converted err_test and forgot. Instead, recognize GTest
vs. normal tests by their contents. This hack can be removed later once
all the tests are converted.

BUG=129

Change-Id: Iaa56e0f3c316faaee5458a4bba9b977dc6efb1e8
Reviewed-on: https://boringssl-review.googlesource.com/13844
Reviewed-by: Steven Valdez <svaldez@google.com>
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>
2017-02-15 15:27:01 +00:00
David Benjamin 83a321231b Move SCT lists and OCSP responses to CERT.
Recent changes added SSL-level setters to these APIs. Unfortunately,
this has the side effect of breaking SSL_set_SSL_CTX, which is how SNI
is typically handled. SSL_set_SSL_CTX is kind of a weird function in
that it's very sensitive to which of the hodge-podge of config styles is
in use. I previously listed out all the config styles here, but it was
long and unhelpful. (I counted up to 7.)

Of the various SSL_set_SSL_CTX-visible config styles, the sanest seems
to be to move it to CERT. In this case, it's actually quite reasonable
since they're very certificate-related.

Later we may wish to think about whether we can cut down all 7 kinds of
config styles because this is kinda nuts. I'm wondering we should do
CERT => SSL_CONFIG, move everything there, and make that be the same
structure that is dropped post-handshake (supposing the caller has
disavowed SSL_clear and renego). Fruit for later thought. (Note though
that comes with a behavior change for all the existing config.)

Change-Id: I9aa47d8bd37bf2847869e0b577739d4d579ee4ae
Reviewed-on: https://boringssl-review.googlesource.com/13864
Reviewed-by: Martin Kreichgauer <martinkr@google.com>
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>
2017-02-15 00:42:38 +00:00
Adam Langley 004bff3a14 chacha/asm/chacha-x86_64.pl: add AVX512 path optimized for shorter inputs.
(Imports upstream's 3c274a6e2016b6724fbfe3ff1487efa2a536ece4.)

Change-Id: I2f0c0abff04decd347d4770e6d1d190f1e08afa0
Reviewed-on: https://boringssl-review.googlesource.com/13781
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2017-02-14 01:11:42 +00:00
Adam Langley cf9a98cc0c x86 assembly pack: update performance results.
(Imports upstream's a30b0522cb937be54e172c68b0e9f5fa6ec30bf3.)

Change-Id: I6b9e67f97de935ecaaa9524943c6bdbe3540c0d0
Reviewed-on: https://boringssl-review.googlesource.com/13780
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2017-02-14 00:44:17 +00:00
Adam Langley 51079b4ebe x86_64 assembly pack: add AVX512 ChaCha20 path.
(Imports upstream's abb8c44fbaf6b88f4f4879b89b32e423aa75617b.)

Note that the AVX512 code is disabled for now. This just reduces the
diff with upstream.

Change-Id: I61da414e53747ecc869f27883e6ab12c1f8513ff
Reviewed-on: https://boringssl-review.googlesource.com/13779
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2017-02-14 00:44:01 +00:00
Adam Langley b99dc55f21 chacha/asm/chacha-x86.pl: improve [backward] portability.
(Imports upstream's d89773d659129368a341df746476da445d47ad31.)

In order to minimize dependency on assembler version a number of
post-SSE2 instructions are encoded manually. But in order to simplify
the procedure only register operands are considered. Non-register
operands are passed down to assembler. Module in question uses pshufb
with memory operands, and old [GNU] assembler can't handle it.
Fortunately in this case it's possible skip just the problematic
segment without skipping SSSE3 support altogether.

Change-Id: Ic3ba1eef14170f9922c2cc69e0d57315e99a788b
Reviewed-on: https://boringssl-review.googlesource.com/13778
Commit-Queue: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2017-02-14 00:35:12 +00:00
Adam Langley 5ca18d8a47 chacha-x86.pl: simplify feature setting.
We do pass -DOPENSSL_IA32_SSE2 on the command line, so this just had the
effect of setting both values to 1 anyway.

Change-Id: Ia34714bb2fe51cc79d51ef9ee3ffe0354049ed0c
Reviewed-on: https://boringssl-review.googlesource.com/13777
Commit-Queue: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2017-02-14 00:35:09 +00:00
Adam Langley 766a6fd151 Revert "OpenSSL: make final reduction in Montgomery multiplication constant-time."
This reverts commit 75b833cc81.

Sadly this needs to be redone because upstream never took this change.
Perhaps, once redone, we can try upstreaming it again.

Change-Id: Ic8aaa0728a43936cde1628ca031ff3821f0fbf5b
Reviewed-on: https://boringssl-review.googlesource.com/13776
Commit-Queue: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2017-02-14 00:35:05 +00:00
Adam Langley 0bf9d6d554 bn/asm/x86[_64]-mont*.pl: implement slightly alternative page-walking.
(Imports upstream's 3ba1ef829cf3dd36eaa5e819258d90291c6a1027.)

Original strategy for page-walking was adjust stack pointer and then
touch pages in order. This kind of asks for double-fault, because
if touch fails, then signal will be delivered to frame above adjusted
stack pointer. But touching pages prior adjusting stack pointer would
upset valgrind. As compromise let's adjust stack pointer in pages,
touching top of the stack. This still asks for double-fault, but at
least prevents corruption of neighbour stack if allocation is to
overstep the guard page.

Also omit predict-non-taken hints as they reportedly trigger illegal
instructions in some VM setups.

Change-Id: Ife42935319de79c6c76f8df60a76204c546fd1e0
Reviewed-on: https://boringssl-review.googlesource.com/13775
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2017-02-14 00:14:21 +00:00
Adam Langley ff7fb71ab5 x86_64 assembly pack: add Goldmont performance results.
(Imports upstream's ace05265d2d599e350cf84ed60955b7f2b173bc9.)

Change-Id: I151a03d662f7effe87f22fd9db7e0265368798b8
Reviewed-on: https://boringssl-review.googlesource.com/13774
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2017-02-14 00:14:15 +00:00
Adam Langley 952f7bff7c Spelling fixes in Perl files.
(Imports upstream's 6025001707fd65679d758c877200469d4e72ea88.)

Change-Id: I2f237d675b029cfc7ba3640aa9ce7248cc230013
Reviewed-on: https://boringssl-review.googlesource.com/13773
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2017-02-14 00:14:06 +00:00
Adam Langley 86c0692499 Skylake performance results.
(Imports upstream's b7f5503fa6e1feebec2ac12b8ddcb5b5672452a6.)

Change-Id: Ia8d2a8f71c97265d77ef8f6fc3cdfb7cf411c5ce
Reviewed-on: https://boringssl-review.googlesource.com/13772
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2017-02-14 00:14:00 +00:00
Adam Langley c948d46569 Remove trailing whitespace from Perl files.
Upstream did this in 609b0852e4d50251857dbbac3141ba042e35a9ae and it's
easier to apply patches if we do also.

Change-Id: I5142693ed1e26640987ff16f5ea510e81bba200e
Reviewed-on: https://boringssl-review.googlesource.com/13771
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2017-02-14 00:13:55 +00:00
Adam Langley 073a06d3da On Windows, page walking is known as __chkstk.
(Imports upstream's 0a86f668212acfa6b48abacbc17b99c234eedf33.)

Change-Id: Ie31d99f8cc3e93b6a9c7c5daa066de96941b3f7c
Reviewed-on: https://boringssl-review.googlesource.com/13770
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2017-02-14 00:13:50 +00:00
Adam Langley b8344501d3 Explain *cough*-dows
(Imports upstream's 1bf80d93024e72628d4351c7ad19c0dfe635aa95.)

Change-Id: If1d61336edc7f63cdfd8ac14157376bde2651a31
Reviewed-on: https://boringssl-review.googlesource.com/13769
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2017-02-14 00:13:44 +00:00
Adam Langley edcd8fda65 bn/asm/x86[_64]-mont*.pl: complement alloca with page-walking.
(Imports upstream's adc4f1fc25b2cac90076f1e1695b05b7aeeae501.)

Some OSes, *cough*-dows, insist on stack being "wired" to
physical memory in strictly sequential manner, i.e. if stack
allocation spans two pages, then reference to farmost one can
be punishable by SEGV. But page walking can do good even on
other OSes, because it guarantees that villain thread hits
the guard page before it can make damage to innocent one...

Change-Id: Ie1e278eb5982f26e596783b3d7820a71295688ec
Reviewed-on: https://boringssl-review.googlesource.com/13768
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2017-02-14 00:13:38 +00:00
Adam Langley 689eb3d03a x86_64-xlate.pl: import fix(?) from upstream.
This imports the changes to x86_64-xlate from upstream's
9c940446f614d1294fa197ffd4128206296b04da. It looks like it's a fix,
although it doesn't alter our generated asm at all. Either way, no point
in diverging from upstream on this point.

Change-Id: Iaedf2cdb9580cfccf6380dbc3df36b0e9c148d1c
Reviewed-on: https://boringssl-review.googlesource.com/13767
Commit-Queue: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2017-02-13 21:52:39 +00:00
Adam Langley 9ad43cbf64 x86_64-xlate.pl: drop some whitespace.
This aligns us better with upstream's version of this file.

Change-Id: I771b6a6c57f2e11e30c95c7a5499c39575b16253
Reviewed-on: https://boringssl-review.googlesource.com/13766
Commit-Queue: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2017-02-13 21:51:38 +00:00
Adam Langley 9be3238e18 perlasm/x86_64-xlate.pl: recognize DWARF CFI directives.
(Imports upstream's a3b5684fc1d4f3aabdf68dcf6c577f6dd24d2b2d.)

CFI directives annotate instructions that are significant for stack
unwinding procedure. In addition to directives recognized by GNU
assembler this module implements three synthetic ones:

- .cfi_push annotates push instructions in prologue and translates to
  .cfi_adjust_cfa_offset (if needed) and .cfi_offset;
- .cfi_pop annotates pop instructions in epilogue and translates to
  .cfi_adjust_cfs_offset (if needed) and .cfi_restore;
- .cfi_cfa_expression encodes DW_CFA_def_cfa_expression and passes it
  to .cfi_escape as byte vector;

CFA expression syntax is made up mix of DWARF operator suffixes [subset
of] and references to registers with optional bias. Following example
describes offloaded original stack pointer at specific offset from
current stack pointer:

        .cfi_cfa_expression     %rsp+40,deref,+8

Final +8 has everything to do with the fact that CFA, Canonical Frame
Address, is reference to top of caller's stack, and on x86_64 call to
subroutine pushes 8-byte return address.

Change-Id: Ic675bf52b5405000be34e9da31c9cf1660f4b491
Reviewed-on: https://boringssl-review.googlesource.com/13765
Commit-Queue: 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>
Reviewed-by: David Benjamin <davidben@google.com>
2017-02-13 21:48:43 +00:00
David Benjamin 16b1b1d4d1 Simplify state and info_callback management.
All the business with rewinding hs->state back or skipping states based
on reuse_message or a skip parameter isn't really worth the trouble for
a debugging callback. With SSL_state no longer exposed, we don't have to
worry about breaking things.

BUG=177

Change-Id: I9a0421f01c8b2f24c80a6b3e44de9138ea023f58
Reviewed-on: https://boringssl-review.googlesource.com/13829
Reviewed-by: Steven Valdez <svaldez@google.com>
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>
2017-02-13 19:52:27 +00:00
David Benjamin 35ed5233c2 Remove an unnecessary state transition.
The split was there out of paranoia that some caller may notice the
change in initial state. Now that SSL_state is neutered, simplify.

BUG=177

Change-Id: I7e2138c2b56821b0c79eec98bb09a82fc28238e8
Reviewed-on: https://boringssl-review.googlesource.com/13828
Reviewed-by: Steven Valdez <svaldez@google.com>
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>
2017-02-13 19:52:09 +00:00
David Benjamin 77458a436e Avoid transitioning into SSL_ST_OK and back out.
I doubt this matters, but this seems a little odd. In particular, this
avoids info_callback seeing the SSL_ST_OK once we stop switching
hs->state back and forth.

BUG=177

Change-Id: Ied39c0e94c242af9d5d0f26795d6e0f2f0b12406
Reviewed-on: https://boringssl-review.googlesource.com/13827
Reviewed-by: Steven Valdez <svaldez@google.com>
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>
2017-02-13 19:52:02 +00:00
David Benjamin 9e766d7532 Unexport the handshake's internal state.
Code which manages to constrain itself on this will limit our ability to
rework the handshake. I believe, at this point, we only need to expose
one bit of information (there's some code that compares SSL_state to
SSL_ST_OK), if even that.

BUG=177

Change-Id: Ie1c43006737db0b974811f1819755c629ae68e7b
Reviewed-on: https://boringssl-review.googlesource.com/13826
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
2017-02-13 19:44:30 +00:00
David Benjamin 07ab5d44d9 Stop skipping stray HelloRequests.
This makes sense to do if we are a client and initiate a renegotiation
at the same time as the server requesting one. Since we will never
initiate a renegotiation, this should not be necessary.

Change-Id: I5835944291fdb8dfcc4fed2ebf1064e91ccdbe6a
Reviewed-on: https://boringssl-review.googlesource.com/13825
Reviewed-by: Steven Valdez <svaldez@google.com>
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>
2017-02-13 19:44:22 +00:00
Adam Langley 040bc4944b Enable TLS 1.3 by default in bssl tool.
Change-Id: I4b586dce37f4db0770e516888c2eeeae3ecffd97
Reviewed-on: https://boringssl-review.googlesource.com/13784
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>
2017-02-11 16:12:31 +00:00
David Benjamin 7d7554b6b3 Add a helper for comparing byte strings.
We compare pointer/length pairs constantly. To avoid needing to type it
everywhere and get GTest's output, add a StringPiece-alike for byte
slices which supports ==, !=, and std::ostream.

BUG=129

Change-Id: I108342cbd2c6a58fec0b9cb87ebdf50364bda099
Reviewed-on: https://boringssl-review.googlesource.com/13625
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>
2017-02-11 00:42:00 +00:00
Adam Langley 949628a2ab perlasm/x86_64-xlate.pl: remove obsolete .picmeup synthetic directive.
(Imports upstream's 9d301cfea7181766b79ba31ed257d30fb84b1b0f.)

Change-Id: Ibc384f5ae4879561e2b26b3c9c2a51af5d91a996
Reviewed-on: https://boringssl-review.googlesource.com/13764
Commit-Queue: 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>
Reviewed-by: David Benjamin <davidben@google.com>
2017-02-11 00:00:58 +00:00
Adam Langley 25126633dc perlasm/x86_64-xlate.pl: minor readability updates.
(Imports upstream's e09b6216a5423555271509acf5112da5484ec15d.)

Change-Id: Ie9d785e415271bede1d35d014ac015e6984e3a52
Reviewed-on: https://boringssl-review.googlesource.com/13763
Commit-Queue: Adam Langley <agl@google.com>
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>
2017-02-10 23:58:41 +00:00
Adam Langley 314997902e perlasm/x86_64-xlate.pl: clarify SEH coding guidelines.
(Imported from upstream's e1dbf7f431b996010844e220d3200cbf2122dbb3)

Change-Id: I71933922f597358790e8a4222e9d69c4b121bc19
Reviewed-on: https://boringssl-review.googlesource.com/13762
Commit-Queue: Adam Langley <agl@google.com>
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>
2017-02-10 23:57:09 +00:00
Adam Langley 4229d26b7e perlasm/x86_64-xlate.pl: add support for AVX512 OPMASK-ing.
(Imported from upstream's 526ab896459a58748af198f6703108b79c917f08.)

Change-Id: I975c1a3ffe76e3c3f99ed8286b448b97fd4a8b70
Reviewed-on: https://boringssl-review.googlesource.com/13761
Commit-Queue: Adam Langley <agl@google.com>
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>
2017-02-10 23:56:06 +00:00
Adam Langley 137e2f86cb bn/asm/rsaz-avx2.pl: refine Win64 SE handler.
(This cherry-picks upstream's 53b33100769aa8801d6fd2caf155c7cb04d64dfc)

Change-Id: I88aa1b1b8b4a746c8fa510fb10f781bdd67cddb5
Reviewed-on: https://boringssl-review.googlesource.com/13760
Commit-Queue: Adam Langley <agl@google.com>
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>
2017-02-10 23:46:08 +00:00
Adam Langley 46db7af2c9 Remove |X509| things from SSL_SESSION.
|SSL_SESSION_from_bytes| now takes an |SSL_CTX*|, from which it uses the
|X509_METHOD| and buffer pool. This is our API so we can do this.

This also requires adding an |SSL_CTX*| argument to |SSL_SESSION_new|
for the same reason. However, |SSL_SESSION_new| already has very few
callers (and none in third-party code that I can see) so I think we can
get away with this.

Change-Id: I1337cd2bd8cff03d4b9405ea3146b3b59584aa72
Reviewed-on: https://boringssl-review.googlesource.com/13584
Reviewed-by: Adam Langley <alangley@gmail.com>
Commit-Queue: Adam Langley <alangley@gmail.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-02-10 19:12:04 +00:00
David Benjamin 7ebe61a585 Fix server-side KeyUpdates.
We sized the post-handshake message limit for the older zero-length
KeyUpdate and forgot to update it when it got larger.

Thanks to Matt Caswell for catching this.

Change-Id: I7d2189479e9516fbfb6c195dfa367794d383582c
Reviewed-on: https://boringssl-review.googlesource.com/13805
Reviewed-by: Steven Valdez <svaldez@google.com>
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>
2017-02-10 18:20:52 +00:00
David Benjamin bc6ef7a83f Convert err_test to GTest.
BUG=129

Change-Id: I227ffa2da4e220075de296fb5b94d043f4e032e0
Reviewed-on: https://boringssl-review.googlesource.com/13627
Reviewed-by: Steven Valdez <svaldez@google.com>
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>
2017-02-10 17:38:22 +00:00
Steven Valdez 908ac19e8e Moving transcript and PRF functions to SSL_TRANSCRIPT.
Change-Id: I98903df561bbf8c5739f892d2ad5e89ac0eb8e6f
Reviewed-on: https://boringssl-review.googlesource.com/13369
Reviewed-by: Steven Valdez <svaldez@google.com>
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>
2017-02-10 16:33:42 +00:00
David Benjamin d4c349b56c Test various lengths of ticket session IDs.
In honor of CVE-2016-9244. Although that particular bug BoGo was already
testing since it uses 16 bytes here.

The empty session ID case is particularly worth testing to make sure we
don't get confused somewhere. RFC 5077 allows clients to offer tickets
with no session ID. This is absurd since the client then has no way of
detecting resumption except by lookahead. We'll never do this as a
client, but should handle it correctly as a server.

Change-Id: I49695d19f03c4efdef43749c07372d590a010cda
Reviewed-on: https://boringssl-review.googlesource.com/13740
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-02-09 23:09:16 +00:00
Rob Sloan b987355a10 Add BN_is_pow2, BN_mod_pow2, and BN_nnmod_pow2.
These are meant to make Android libcore's usage of BIGNUMs for java
BigIntegers faster and nicer (specifically, so that it doesn't need
to malloc a bunch of temporary BIGNUMs).

BUG=97
Change-Id: I5f30e14c6d8c66a9848d4935ce27d030829f6923
Reviewed-on: https://boringssl-review.googlesource.com/13387
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>
2017-02-09 22:40:12 +00:00
Adam Langley 5e3777830c Rename ssl_rsa.c to ssl_privkey.c.
ssl_rsa.c now basically deals with private-key functions, so rename to
reflect that.

Change-Id: Ia87ed4c0f9b34af134844e2eeb270fc45ff3f23f
Reviewed-on: https://boringssl-review.googlesource.com/13583
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-02-09 18:45:11 +00:00
Adam Langley 52940c4945 Move a number of certificate-related functions from ssl_rsa.c to ssl_cert.c
This leaves ssl_rsa.c dealing only with private-key matters.

Change-Id: I46aa80abd8374d8cc6d2b0f7a9a345214ec86084
Reviewed-on: https://boringssl-review.googlesource.com/13582
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-02-09 18:36:18 +00:00
Adam Langley 3509dacc3c Add |X509_METHOD| and, using it, move many functions to ssl_x509.c.
Change-Id: I266af0c2bdcebcc1dd1026f816b9ef6ece5a592f
Reviewed-on: https://boringssl-review.googlesource.com/13581
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-02-09 18:30:35 +00:00
Adam Langley 04540a7fa7 Set the default value of a last |alert|.
I even made a note to update my change in light of this but still
managed to forget. With this, grep tells me that all |alert| values have
the correct default value now.

Change-Id: If37c4f2f6b36cf69e53303a3924a8eda4cfffed8
Reviewed-on: https://boringssl-review.googlesource.com/13721
Commit-Queue: Adam Langley <agl@google.com>
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>
2017-02-09 18:19:27 +00:00
Adam Langley c68e5b99a7 Establish that the default value of an out-arg for alerts is SSL_AD_DECODE_ERROR.
We already have some cases where the default is DECODE_ERROR and, rather
than have two defaults, just harmonise on that. (INTERNAL_ERROR might
make more sense in some cases, but we don't want to have to remember
what the default is in each case and nobody really cares what the actual
value is anyway.)

Change-Id: I28007898e8d6e7415219145eb9f43ea875028ab2
Reviewed-on: https://boringssl-review.googlesource.com/13720
Reviewed-by: Adam Langley <agl@google.com>
2017-02-09 18:07:30 +00:00
Brian Smith 644539191b chacha20_poly1305_x86_64.pl: Suppress Yasm non-local label warnings.
Before, attempting to build the code using Yasm as the assembler would
result in warnings like this:

    warning : no non-local label before `.chacha20_consts'

Precede the local labels with a non-local label to suppress these
warnings.

It isn't clear why these labels are defined as local labels instead of
regular labels.  Making them non-local may be a better idea.

For reference, Yasm's interpretation of local labels is described
succinctly at
https://www.tortall.net/projects/yasm/manual/html/nasm-local-label.html.

Change-Id: Ifc92de7fd7379859fe33f1137ab20b6ec282cd0b
Reviewed-on: https://boringssl-review.googlesource.com/13384
Reviewed-by: Adam Langley <agl@google.com>
2017-02-09 18:05:41 +00:00
David Benjamin dc8c1d962e Remove some dead state constants.
Change-Id: If97da565155292d5f0de5c6a8b0fd8508398768a
Reviewed-on: https://boringssl-review.googlesource.com/13564
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-02-09 02:15:44 +00:00
David Benjamin 59bae5aa3a Split TLS 1.2 ClientHello processing into separate functions.
This ABCD thing with multiple ways to enter the same function is
confusing. ClientHello processing is the most egregious of these, so
split it up ahead of time as an intermediate step.

States remain named as-is due to them being exposed as public API. We
should have a story for which subset of states we need to promise as
public API and to intentionally break all other cases (map to some
generic value) before we go too far there.

BUG=128

Change-Id: Id9d28c6de14bd53c3294552691cebe705748f489
Reviewed-on: https://boringssl-review.googlesource.com/13563
Reviewed-by: Adam Langley <agl@google.com>
2017-02-09 02:15:27 +00:00
Adam Langley 7dccc71e08 Set output alert when failing to parse public key.
Previously, the alert was uninitialised.

(Thanks to Robert Swiecki and honggfuzz.)

Change-Id: I2d4eb96b0126f3eb502672b2600ad43ae140acec
Reviewed-on: https://boringssl-review.googlesource.com/13700
Commit-Queue: Adam Langley <agl@google.com>
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>
2017-02-08 17:09:03 +00:00
David Benjamin cdb6fe90cb Test the exporter at all versions + ciphers + side.
The Go side (thankfully not the C side) was not fully updated for the
exporter secret derivation being earlier at some point. Also TLS 1.2
upgrades the PRF hash for pre-1.2 ciphers to SHA-256, so make sure we
cover that.

Change-Id: Ibdf50ef500e7e48a52799ac75577822bc304a613
Reviewed-on: https://boringssl-review.googlesource.com/13663
Reviewed-by: Steven Valdez <svaldez@google.com>
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>
2017-02-07 21:37:44 +00:00
David Benjamin 3bd57e3a6f Remove remnants of non-standard ECDHE_PSK GCM ciphers.
Change-Id: I471880d785c38123e038279f67348bf02b47d091
Reviewed-on: https://boringssl-review.googlesource.com/13662
Reviewed-by: Steven Valdez <svaldez@google.com>
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>
2017-02-07 21:37:22 +00:00
David Benjamin 6b0edfb9e6 Add a common TestEventListener for the error queue.
Replicate the logic in the AllTests targets to dump the error queue on
failure. GTest seems to print to stdout, so we do here too.

BUG=129

Change-Id: I623b695fb9a474945834c3653728f54e5b122187
Reviewed-on: https://boringssl-review.googlesource.com/13623
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>
2017-02-07 21:33:22 +00:00
David Benjamin f0d8e22078 Convert some of ssl_test to GTest more thoroughly.
The more complex ones will want a TEST_P, but here are a few easy ones
to start with.

BUG=129

Change-Id: I2e341d04910c0b05a5bc7afec961c4541ca7db41
Reviewed-on: https://boringssl-review.googlesource.com/13622
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>
2017-02-07 21:33:15 +00:00
David Benjamin 634b0e3c73 Combine stdout and stderr in all_test.go
GTest sends its output to stdout, not stderr. Merge them in the runner
(though eventually we'll teach the bots to run the GTest targets
directly) so we don't lose it.

BUG=129

Change-Id: I7c499cd9572f46f97bd4b7f6c6c9beca057625f2
Reviewed-on: https://boringssl-review.googlesource.com/13624
Reviewed-by: Steven Valdez <svaldez@google.com>
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>
2017-02-07 21:26:05 +00:00
Alessandro Ghedini 8df6766d01 Support setting per-connection SCT list
Right now the only way to set an SCT list is the per-context function
SSL_CTX_set_signed_cert_timestamp_list. However this assumes that all the
SSLs generated from a SSL_CTX share the same SCT list, which is wrong.

In order to avoid memory duplication in case SSL_CTX has its own list, a
CRYPTO_BUFFER is used for both SSL_CTX and SSL.

Change-Id: Id20e6f128c33cf3e5bff1be390645441be6518c6
Reviewed-on: https://boringssl-review.googlesource.com/13642
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>
2017-02-07 17:50:13 +00:00
Alessandro Ghedini 33fe4a0d14 Remove support for setting per-connection default session timeout
As previously discussed, it turns out we don't actually need this, so
there's no point in keeping it.

Change-Id: If549c917b6bd818cd36948e37cb7839c8d122b1a
Reviewed-on: https://boringssl-review.googlesource.com/13641
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>
2017-02-07 17:46:25 +00:00
David Benjamin 5bd8a09f2a Fix a crash with malformed user notice policy numbers
(Imported from upstream's efe8398649a1d7fc9d84d2818592652e0632a8a8.)

Change-Id: I0d04b3e75ec26a7dd3a7af31b0e115723c4b24d9
Reviewed-on: https://boringssl-review.googlesource.com/13661
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-02-07 00:45:22 +00:00
David Benjamin 023d419eae Test that we tolerate server name acknowledgements.
The SNI extension may be ACKed by the server. This is kind of pointless,
but make sure we cover these codepaths.

Change-Id: I14b25ab865dd6e35a30f11ebc9027a1518bbeed9
Reviewed-on: https://boringssl-review.googlesource.com/13633
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>
2017-02-06 23:18:47 +00:00
Nick Harper ab20cec1c1 Read 0-RTT data in Bogo.
Change-Id: I878dfb9f5d3736c3ec0d5fa39052cca58932dbb7
Reviewed-on: https://boringssl-review.googlesource.com/12981
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>
2017-02-06 22:36:53 +00:00
Nick Harper f2511f19b9 Send 0-RTT data in bogo.
Change-Id: I38cd04fa40edde4e4dd31fdc16bbf92985430198
Reviewed-on: https://boringssl-review.googlesource.com/12702
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>
2017-02-06 22:35:45 +00:00
David Benjamin e0ca4879ec Fix EVP_get_digestbyobj for NID-less ASN1_OBJECTs.
The recent rewrite didn't account for the OID being missing but the NID
present.

Change-Id: I335e52324c62ee3ba849c0c385aaf86123a8ffbb
Reviewed-on: https://boringssl-review.googlesource.com/13660
Commit-Queue: David Benjamin <davidben@google.com>
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-02-06 20:19:22 +00:00
David Benjamin 3f2611a98f Hide SSL struct.
BUG=6

Change-Id: I5383ad230f1fdc54f9536c9922bfbf991401a00c
Reviewed-on: https://boringssl-review.googlesource.com/13632
Commit-Queue: David Benjamin <davidben@google.com>
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-02-06 18:45:50 +00:00
Steven Valdez 2f82a0e51b Don't stash tlsext_hostname in ssl_get_new_session.
ssl_get_new_session would stash a copy of the configured hostname
into the SSL_SESSION on the server. Servers have no reason to
configuring that anyway, but, if one did, we'd leak when filling in
the client-supplied SNI later.

Remove this code and guard against this by remembering to OPENSSL_free
when overwriting that field (although it should always be NULL).

Reported-By: Robert Swiecki <swiecki@google.com>
Change-Id: Ib901b5f82e5cf818060ef47a9585363e05dd9932
Reviewed-on: https://boringssl-review.googlesource.com/13631
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>
2017-02-06 18:42:53 +00:00
Adam Langley b7d53ba268 Add “const” to |SSL_SESSION| fuzzer.
(Found by UBSAN.)

Change-Id: Ia11d5edc3c6dd7ac9a05a181ed649a4da2f278b8
2017-02-06 09:37:05 -08:00
David Benjamin 58966a455f Remove legacy ChaCha20-Poly1305 cipher name aliases.
I believe these are now unused.

Change-Id: I438da3d56ca598260fe0f5698ccb6649bd97b859
Reviewed-on: https://boringssl-review.googlesource.com/13630
Reviewed-by: Steven Valdez <svaldez@google.com>
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>
2017-02-06 17:17:34 +00:00
David Benjamin 2056f63bdb Recommend ex_data for SSL_CTX_set_cert_verify_callback.
Using the arg parameter does not work well. This is purely an
SSL_CTX-level callback, not an SSL-level one.

Change-Id: Ib968807efbe7dd08e71cea1c4d8034a52c729d45
Reviewed-on: https://boringssl-review.googlesource.com/13629
Reviewed-by: Steven Valdez <svaldez@google.com>
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>
2017-02-06 17:17:32 +00:00
David Benjamin b2ff2623a8 Add a basic SSL_get_certificate test.
With the CRYPTO_BUFFER stuff, this API is now slightly more complex. Add
some tests as a sanity-check.

Change-Id: I9da20e3eb6391fc86ed215c5fabec71aa32ef56f
Reviewed-on: https://boringssl-review.googlesource.com/13620
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>
2017-02-03 22:19:51 +00:00
David Benjamin e025f30507 Guard the _GNU_SOURCE #define.
It is hard to control what flags consumers may try to build us with.
Account for someone adding _GNU_SOURCE to the build line.

Change-Id: I4c931da70a9dccc89382ce9100c228c29d28d4bf
Reviewed-on: https://boringssl-review.googlesource.com/13621
Commit-Queue: David Benjamin <davidben@google.com>
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-02-03 22:15:09 +00:00
Adam Langley bdcfd1366f Move the SSL BIO into ssl/ from decrepit/.
This is purely to support curl, which now has HTTPS proxy support that,
sadly, uses the BIO SSL. Don't use the BIO SSL for anything else.

Change-Id: I9ef6c9773ec87a11e0b5a93968386ac4b351986d
Reviewed-on: https://boringssl-review.googlesource.com/13600
Commit-Queue: Adam Langley <agl@google.com>
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>
2017-02-03 21:08:10 +00:00
David Benjamin daa0539276 Remove an unnecessary TLS 1.3 ClientHello state.
The TLS 1.2 and 1.3 state machines do the exact same thing at the
beginning. Let them process the ClientHello extensions, etc., and
finalize the certificate in common code. Once we start picking
parameters, we begin to diverge. Everything before this point is
arguably part of setting up the configuration, which is
version-agnostic.

BUG=128

Change-Id: I293ea3087ecbc3267bd8cdaa011c98d26a699789
Reviewed-on: https://boringssl-review.googlesource.com/13562
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-02-03 20:03:37 +00:00
David Benjamin 42bfeb3623 Remove an unnecessary TLS 1.2 ClientHello state.
The version negotiation logic was a little bizarrely wedged in the
middle of the state machine. (We don't support server renegotiation, so
have_version is always false here.)

BUG=128

Change-Id: I9448dce374004b92e8bd5172c36a4e0eea51619c
Reviewed-on: https://boringssl-review.googlesource.com/13561
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-02-03 20:01:31 +00:00
Adam Langley e5dfb52c3b Add -root-certs options to bssl client.
This option allows a file containing PEM root certificates to be given.
It causes the server's certificate to be verified against those roots.

Change-Id: Iaa92581d5834e436bcedf9d4088f7204abc6b95b
Reviewed-on: https://boringssl-review.googlesource.com/13588
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>
2017-02-03 19:19:10 +00:00
Adam Langley e212f27a3e Support running tests under Intel SDE.
Intel SDE is a tool that can simulate many different Intel chips. This
lets us test whether our CPUID-guarding is correct and would have
caught, for example, this morning's ChaCha20-Poly1305 problem.

Change-Id: I39de2bedb1c29b48b02ba30c51fdce57a5cbe640
Reviewed-on: https://boringssl-review.googlesource.com/13587
Commit-Queue: Adam Langley <alangley@gmail.com>
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>
2017-02-03 18:20:28 +00:00
David Benjamin 3c0e037756 Don't reach into SSL in BIO_f_ssl.
We can implement this with the SSL stack's public API fine.

Change-Id: Ia95c9174d7b850b7fed89046d3c351c970855cf3
Reviewed-on: https://boringssl-review.googlesource.com/13565
Commit-Queue: David Benjamin <davidben@google.com>
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-02-03 17:10:12 +00:00
Adam Langley 5fa2cdf1ed Test SSE4.1 before using ChaCha20-Poly1305 asm.
This change guards the ChaCha20-Poly1305 asm on having SSE4.1. The
pinsrb instruction that it uses requires this, which I didn't notice,
and so this would fail on Core 2 and older chips.

BUG=chromium:688384

Change-Id: I177e3492782a1a9974b6df29d26fc4809009ad48
Reviewed-on: https://boringssl-review.googlesource.com/13586
Reviewed-by: Adam Langley <alangley@gmail.com>
Commit-Queue: Adam Langley <alangley@gmail.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-02-03 16:46:26 +00:00
Adam Langley 772a5bed7d Reorder the X25519 ladderstep stack frame on x86-64.
The current X25519 assembly has a 352-byte stack frame and saves the
regsiters at the bottom. This means that the CFI information cannot be
represented in the “compact” form that MacOS seems to want to use (see
linked bug).

The stack frame looked like:

 360 CFA
 352 return address
 ⋮
 56  (296 bytes of scratch space)
 48  saved RBP
 40  saved RBX
 32  saved R15
 24  saved R14
 16  saved R13
 8   saved R12
 0   (hole left from 3f38d80b dropping the superfluous saving of R11)

Now it looks like:

 352 CFA
 344 return address
 336 saved RBP
 328 saved RBX
 320 saved R15
 312 saved R14
 304 saved R13
 296 saved R12
 ⋮
 0   (296 bytes of scratch space)

The bulk of the changes involve subtracting 56 from all the offsets to
RSP when working in the scratch space. This was done in Vim with:
  '<,'>s/\([1-9][0-9]*\)(%rsp)/\=submatch(1)-56."(%rsp)"/

BUG=176

Change-Id: I022830e8f896fe2d877015fa3ecfa1d073207679
Reviewed-on: https://boringssl-review.googlesource.com/13580
Commit-Queue: Adam Langley <agl@google.com>
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>
2017-02-02 22:47:05 +00:00
David Benjamin 8671c47bd8 Fold ssl3_write_bytes into ssl3_write_app_data.
It has no other callers, now that the handshake is written elsewhere.

Change-Id: Ib04bbdc4a54fc7d01405d9b3f765fa9f186244de
Reviewed-on: https://boringssl-review.googlesource.com/13540
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>
2017-02-02 22:23:46 +00:00
David Benjamin 6342111c2e Remove BIO puts hooks.
These are unused. BIO_puts is implemented genericly.

Change-Id: Iecf1b6736291de8c48ce1adbb7401963a120d122
Reviewed-on: https://boringssl-review.googlesource.com/13366
Reviewed-by: Steven Valdez <svaldez@google.com>
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>
2017-02-02 22:22:08 +00:00
David Benjamin 5c9d411e14 Fix some compact unwind errors.
The Mac ld gets unhappy about "weird" unwind directives:

In chacha20_poly1305_x86_64.pl, $keyp is being pushed on the stack
(according to the comment) because it gets clobbered in the computation
somewhere. $keyp is %r9 which is not callee-saved (it's an argument
register), so we don't need to tag it with .cfi_offset.

In x25519-asm-x86_64.S, x25519_x86_64_mul saves %rdi on the stack.
However it too is not callee-saved (it's an argument register) and
should not have a .cfi_offset. %rdi also does not appear to be written
to anywhere in the function, so there's no need to save it at all.

(This does not resolve the "r15 is saved too far from return address"
errors. Just the non-standard register ones.)

BUG=176

Change-Id: I53f3f7db3d1745384fb47cb52cd6536aabb5065e
Reviewed-on: https://boringssl-review.googlesource.com/13560
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-02-02 22:05:06 +00:00
David Benjamin 17b3083373 Use a separate timeout scheme for TLS 1.3.
In TLS 1.2, resumption's benefits are more-or-less subsumed by False
Start. TLS 1.2 resumption lifetime is bounded by how much traffic we are
willing to encrypt without fresh key material, so the lifetime is short.
Renewal uses the same key, so we do not allow it to increase lifetimes.

In TLS 1.3, resumption unlocks 0-RTT. We do not implement psk_ke, so
resumption incorporates fresh key material into both encrypted traffic
(except for early data) and renewed tickets. Thus we are both more
willing to and more interested in longer lifetimes for tickets. Renewal
is also not useless. Thus in TLS 1.3, lifetime is bound separately by
the lifetime of a given secret as a psk_dhe_ke authenticator and the
lifetime of the online signature which authenticated the initial
handshake.

This change maintains two lifetimes on an SSL_SESSION: timeout which is
the renewable lifetime of this ticket, and auth_timeout which is the
non-renewable cliff. It also separates the TLS 1.2 and TLS 1.3 timeouts.
The old session timeout defaults and configuration apply to TLS 1.3, and
we define new ones for TLS 1.3.

Finally, this makes us honor the NewSessionTicket timeout in TLS 1.3.
It's no longer a "hint" in 1.3 and there's probably value in avoiding
known-useless 0-RTT offers.

BUG=120

Change-Id: Iac46d56e5a6a377d8b88b8fa31f492d534cb1b85
Reviewed-on: https://boringssl-review.googlesource.com/13503
Reviewed-by: Adam Langley <agl@google.com>
2017-02-02 19:51:49 +00:00
David Benjamin 0b1bb12ce8 Push the SSL_CTX session_timeout zero logic up.
This special-case is almost unexposed (the timeout is initialized to the
default) except if the caller calls SSL_CTX_set_timeout(0). Preserve
that behavior by mapping 0 to SSL_DEFAULT_SESSION_TIMEOUT in
SSL_CTX_set_timeout but simplify the internal state.

Change-Id: Ice03a519c25284b925f1e0cf485f2d8c54dc5038
Reviewed-on: https://boringssl-review.googlesource.com/13502
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-02-02 17:52:07 +00:00
David Benjamin 0efa7592e3 dispatch_alert is not an incidental write.
It is impossible to have to call dispatch_alert when writing application
data. Now that we don't send warning alerts through ssl3_send_alert, all
alerts are closure alerts, which means attempts to write will fail.

This prunes a lot of dead code, avoiding the re-entrancy in the write
path. With that gone, tracking alert_dispatch is much more
straightforward.

BUG=146

Change-Id: Ie5fe677daee71e463d79562f3d2cea822a92581d
Reviewed-on: https://boringssl-review.googlesource.com/13500
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
2017-02-02 17:49:44 +00:00
David Benjamin e79fe70be9 Bit-pack SSL_AEAD_CTX's various toggles.
Change-Id: Ibb479a0a739a44d0568e37cdfdb30b30e5410c02
Reviewed-on: https://boringssl-review.googlesource.com/13520
Commit-Queue: David Benjamin <davidben@google.com>
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-02-01 23:37:34 +00:00
David Benjamin b5c58db9ff TLS 1.3 sessions should not be added to the server session cache.
Fix this and add a test. Otherwise enabling TLS 1.3 will cause a server
to blow through its session cache.

Change-Id: I67edbc468faedfd94a6c30cf842af085a6543b50
Reviewed-on: https://boringssl-review.googlesource.com/13501
Reviewed-by: Steven Valdez <svaldez@google.com>
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>
2017-02-01 23:07:55 +00:00
Adam Langley c26692cfdd Push the use of X509 upwards, out of |ssl_set_cert|.
This change moves the interface between |X509| and |CRYPTO_BUFFER| a
little further out, towards the API.

Change-Id: I1c014d20f12ad83427575843ca0b3bb22de1a694
Reviewed-on: https://boringssl-review.googlesource.com/13365
Reviewed-by: Adam Langley <agl@google.com>
2017-02-01 20:00:10 +00:00
Adam Langley e1e78130f5 Keep a reference to |X509|s appended to a chain.
The recent CRYPTO_BUFFER changes meant that |X509| objects passed to
SSL_CTX_add_extra_chain_cert would be |free|ed immediately. However,
some third-party code (at least serf and curl) continue to use the
|X509| even after handing over ownership.

In order to unblock things, keep the past |X509| around for a while to
paper over the issues with those libraries while we try and upstream
changes.

Change-Id: I832b458af9b265749fed964658c5c34c84d518df
Reviewed-on: https://boringssl-review.googlesource.com/13480
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-02-01 00:24:24 +00:00
Nick Harper 7cd0a978cc Bogo: Send and receive 0.5-RTT data.
Change-Id: I44202457841f06a899e140f78ae8afa7ac720283
Reviewed-on: https://boringssl-review.googlesource.com/12600
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>
2017-02-01 00:04:04 +00:00
Adam Langley 3f38d80b2f Add CFI information to the x86-64 X25519 asm.
This change serves to check that all our consumers can process assembly
with CFI directives in it.

For the first change I picked a file that's not perlasm to keep things
slightly simplier, but that might have been a mistake:

DJB's tooling always aligns the stack to 32 bytes and it's not possible
to express this in DWARF format (without using a register to store the
old stack pointer).

Since none of the functions here appear to care about that alignment, I
removed it from each of them. I also trimmed the set of saved registers
where possible and used the redzone for functions that didn't need much
stack.

Overall, this appears to have slightly improved the performance (by
about 0.7%):

Before:

Did 46000 Curve25519 base-point multiplication operations in 3023288us (15215.2 ops/sec)
Did 46000 Curve25519 arbitrary point multiplication operations in 3017315us (15245.3 ops/sec)
Did 46000 Curve25519 base-point multiplication operations in 3015346us (15255.3 ops/sec)
Did 46000 Curve25519 arbitrary point multiplication operations in 3018609us (15238.8 ops/sec)
Did 46000 Curve25519 base-point multiplication operations in 3019004us (15236.8 ops/sec)
Did 46000 Curve25519 arbitrary point multiplication operations in 3013135us (15266.5 ops/sec)

After:

Did 46000 Curve25519 base-point multiplication operations in 3007659us (15294.3 ops/sec)
Did 47000 Curve25519 arbitrary point multiplication operations in 3054202us (15388.6 ops/sec)
Did 46000 Curve25519 base-point multiplication operations in 3008714us (15288.9 ops/sec)
Did 46000 Curve25519 arbitrary point multiplication operations in 3004740us (15309.1 ops/sec)
Did 46000 Curve25519 base-point multiplication operations in 3009140us (15286.8 ops/sec)
Did 47000 Curve25519 arbitrary point multiplication operations in 3057518us (15371.9 ops/sec)

Change-Id: I31df11c45b2ea0bf44dde861d52c27f848331691
Reviewed-on: https://boringssl-review.googlesource.com/13200
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
2017-01-31 17:55:19 +00:00
Adam Langley 8c2480f740 Push to error queue in |EVP_PKEY_CTX_ctrl| for wrong keytype.
Change-Id: I81a94be94103d3c763cd6b2c1b8196300808c6fe
Reviewed-on: https://boringssl-review.googlesource.com/13386
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>
2017-01-30 19:16:05 +00:00
David Benjamin f71036e4e3 Remove ssl_hash_message_t from ssl_get_message.
Move to explicit hashing everywhere, matching TLS 1.2 with TLS 1.3. The
ssl_get_message calls between all the handshake states are now all
uniform so, when we're ready, we can rewire the TLS 1.2 state machine to
look like the TLS 1.3 one. (ssl_get_message calls become an
ssl_hs_read_message transition, reuse_message becomes an ssl_hs_ok
transition.)

This avoids some nuisance in processing the ServerHello at the 1.2 / 1.3
transition.

The downside of explicit hashing is we may forget to hash something, but
this will fail to interop with our tests and anyone else, so we should
be able to catch it.

BUG=128

Change-Id: I01393943b14dfaa98eec2a78f62c3a41c29b3a0e
Reviewed-on: https://boringssl-review.googlesource.com/13266
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>
2017-01-27 23:23:57 +00:00
David Benjamin 1a444daca6 Detach V2ClientHello hashing hack from ssl_hash_message_t.
This is kind of annoying (even new state is needed to keep the layering
right). As part of aligning the read paths of the TLS 1.2 and TLS 1.3
state machine, we'll want to move to states calling
ssl_hash_current_message when the process the message, rather than when
the message is read. Right now the TLS 1.2 optional message story
(reuse_message) depends on all messages preceded by an optional message
using ssl_hash_message. For instance, if TLS 1.2 decided to place
CertificateStatus before ServerKeyExchange, we would not be able to
handle it.

However, V2ClientHello, by being handled in the message layer, relies on
ssl_get_message-driven hashing to replace the usual ClientHello hash
with a hash of something custom. This switches things so rather than
ClientHellos being always pre-hashed by the message layer, simulated
ClientHellos no-op ssl_hash_current_message.

This just replaces one hack with another (V2ClientHello is inherently
nasty), but this hack should be more compatible with future plans.

BUG=128

Change-Id: If807ea749d91e306a37bb2362ecc69b84bf224c9
Reviewed-on: https://boringssl-review.googlesource.com/13265
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>
2017-01-27 23:22:14 +00:00
Brian Smith 360a4c2616 chacha20_poly1305_x86_64.pl: Use NASM-compatible syntax for |ldea|.
Cargo-cult the way other Perlasm scripts do it.

Change-Id: I86aaf725e41b601f24595518a8a6bc481fa0c7fc
Reviewed-on: https://boringssl-review.googlesource.com/13382
Reviewed-by: Adam Langley <agl@google.com>
2017-01-27 23:17:13 +00:00
Brian Smith 357a9f23fe chacha20_poly1305_x86_64.pl: Use |imulq| instead of |imul|.
Perlasm requires the size suffix when targeting NASM and Yasm; without
it, the resulting .asm file has |imu| instead of |imul|.

Change-Id: Icb95b8c0b68cf4f93becdc1930dc217398f56bec
Reviewed-on: https://boringssl-review.googlesource.com/13381
Reviewed-by: Adam Langley <agl@google.com>
2017-01-27 23:16:52 +00:00
Brian Smith 3416d28a57 chacha20_poly1305_x86_64.pl: Escape command line args like other PerlAsm scripts.
Use the same quoting used in other files so that this file can be built
the same way as other files on platforms that require the other kind of
quoting.

Change-Id: I808769bf014fbfe526fedcdc1e1f617b3490d03b
Reviewed-on: https://boringssl-review.googlesource.com/13380
Reviewed-by: Adam Langley <agl@google.com>
2017-01-27 23:16:27 +00:00
David Benjamin 276b7e8127 Move optional message type checks out of ssl_get_message.
This aligns the TLS 1.2 state machine closer with the TLS 1.3 state
machine. This is more work for the handshake, but ultimately the
plan is to take the ssl_get_message call out of the handshake (so it is
just the state machine rather than calling into BIO), so the parameters
need to be folded out as in TLS 1.3.

The WrongMessageType-* family of tests should make sure we don't miss
one of these.

BUG=128

Change-Id: I17a1e6177c52a7540b2bc6b0b3f926ab386c4950
Reviewed-on: https://boringssl-review.googlesource.com/13264
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>
2017-01-27 23:15:52 +00:00
Adam Langley 6f07d726c9 Don't up_ref a NULL |CRYPTO_BUFFER|.
If an existing chain had a NULL placeholder for a leaf we could end up
trying to increment its reference count. That results in a crash at
configuration time. Found via the SSL_CTX API fuzzer.

BUG=oss-fuzz:480

Change-Id: I0ddc2cbde2e625015768f1bdc8da625e8a4f05fd
Reviewed-on: https://boringssl-review.googlesource.com/13383
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>
2017-01-27 22:09:49 +00:00
David Benjamin 42e3e191e4 Restore mapping BIO_flush errors to -1.
This was originally changed so that flush_flight could forward BIO_write
errors as-is, but we can and probably should still map BIO_flush errors.
This is unlikely to matter (every relevant BIO likely just has a no-op
flush which returns one), but, e.g., our file BIO returns 0, not -1, on
error.

We possibly should also be mapping BIO_write errors, but I'll leave that
alone for now. It's primarily BIO_read where the BIO return value must
be preserved due to error vs. EOF.

(We probably can just remove the BIO_flush calls altogether, but since
the buffer BIO forwarded the flush signal it would be a user-visible
behavior change to confirm.)

Change-Id: Ib495cc5d043867cf964f99b7ee4535114f7b2230
Reviewed-on: https://boringssl-review.googlesource.com/13367
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-01-27 16:24:19 +00:00
Adam Langley 830f7009eb Rename some single-letter argument names.
(I split this change off to minimise the noise in future diffs that
actually do something meaningful.)

Change-Id: I7a054dcfc90a44ab5bb89b8f46704e5e3410e524
Reviewed-on: https://boringssl-review.googlesource.com/13364
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-01-27 16:21:23 +00:00
Adam Langley 3b3b62f39c X509_parse_from_buffer: reject massive certificates.
Otherwise we could pass a negative value into |d2i_X509|.

Change-Id: I52a35dd9648269094110b69eddd7667a56ec8253
Reviewed-on: https://boringssl-review.googlesource.com/13363
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-01-27 16:21:16 +00:00
Adam Langley 3a2b47ab5b Don't use |X509| objects in |CERT|, by default.
This change converts the |CERT| struct to holding certificates as binary
blobs, rather than in parsed form. The members for holding the parsed
form are still there, however, but are only used as a cache for the
event that someone asks us for a non-owning pointer to the parsed leaf
or chain.

Next steps:
  * Move more functions in to ssl_x509.c
  * Create an X509_OPS struct of function pointers that will hang off
    the |SSL_METHOD| to abstract out the current calls to crypto/x509
    operations.

BUG=chromium:671420

Change-Id: Ifa05d88c49a987fd561b349705c9c48f106ec868
Reviewed-on: https://boringssl-review.googlesource.com/13280
Reviewed-by: Adam Langley <agl@google.com>
2017-01-27 16:21:05 +00:00
David Benjamin 2fe6e227fb Remove mask_a and mask_k from CERT.
This resolves a TODO, trims per-connection memory, and makes more sense.
These masks have nothing to do with certificate configuration.

Change-Id: I783e6158e51f58cce88e3e68dfa0ed965bdc894c
Reviewed-on: https://boringssl-review.googlesource.com/13368
Reviewed-by: Steven Valdez <svaldez@google.com>
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>
2017-01-27 15:44:17 +00:00
David Benjamin 41a26e819f Remove buffer BIOs.
These are completely unused, but for BIO_set_write_buffer_size which is
in some (unreachable) nginx codepath. Keep that around so nginx
continues to build, but otherwise delete it.

Change-Id: I1a50a4f7b23e5fdbc7f132900ecacd74e8775a7f
Reviewed-on: https://boringssl-review.googlesource.com/13362
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>
2017-01-26 23:09:10 +00:00
Adam Langley 71e4aff654 Use |extern| when referencing assembly functions from C.
I don't think that this makes a difference, but it's a little more
consistent with what we've done previously. I made this change when
trying to get the DFSAN build working, although that issue turned out to
be unrelated.

Change-Id: I21041689c5df70ca2bddf33065d687763af8c3c7
Reviewed-on: https://boringssl-review.googlesource.com/13361
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>
2017-01-26 22:12:09 +00:00
David Benjamin 9b16066654 Ignore 0-RTT-capable tickets unless enabled.
Until we've gotten it fully working, we should not mint any of these
SSL_SESSIONs, to avoid constraining future versions of our client code.

Notably, if any of our TLS 1.3 clients today serialized sessions, we
would need to rev the serialization format. Without opting into 0-RTT, a
TLS 1.3 client will create SSL_SESSIONs tagged as 0-RTT-capable but
missing important fields (ALPN, etc.). When that serialized session
makes its way to a future version of our client code, it would disagree
with the server about the ALPN value stored in the ticket and cause
interop failures.

I believe the only client code enabling TLS 1.3 right now is Chrome, and
the window is small, so it should be fine. But fix this now before it
becomes a problem.

Change-Id: Ie2b109f8d158017a6f3b4cb6169050d38a66b31c
Reviewed-on: https://boringssl-review.googlesource.com/13342
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
2017-01-26 21:29:32 +00:00
Steven Valdez 258508fce1 Adding V2ClientHello counter.
Change-Id: I324743e7d1864fbbb9653209ff93e4da872c8d31
Reviewed-on: https://boringssl-review.googlesource.com/13340
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>
2017-01-26 20:32:00 +00:00
David Benjamin d103616db1 bn/asm/x86_64-mont5.pl: fix carry bug in bn_sqr8x_internal.
CVE-2017-3732

(Imported from upstream's 3f4bcf5bb664b47ed369a70b99fac4e0ad141bb3 and
3e7a496307ab1174c1f8f64eed4454c1c9cde1a8.)

Change-Id: I40255fdf4184e3b919758a72c3d3a7486d91ff65
Reviewed-on: https://boringssl-review.googlesource.com/13360
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-01-26 18:29:44 +00:00
Nick Harper 47383aadff Skip over early data in bogo.
Change-Id: Idc93fdca2f1c5c23e4ba48c4efed2edbad1e857b
Reviewed-on: https://boringssl-review.googlesource.com/12521
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>
2017-01-26 02:38:56 +00:00
David Benjamin 16315f7cc7 Remove the rest of write_message.
The TLS 1.2 state machine now looks actually much closer to the TLS 1.3
one on the write side. Although the write states still have a BIO-style
return, they don't actually send anything anymore. Only the BIO flush
state does. Reads are still integrated into the states themselves
though, so I haven't made it match TLS 1.3 yet.

BUG=72

Change-Id: I7708162efca13cd335723efa5080718a5f2808ab
Reviewed-on: https://boringssl-review.googlesource.com/13228
Reviewed-by: Adam Langley <agl@google.com>
2017-01-25 23:39:23 +00:00
David Benjamin 0f24bedb05 Rename tls13_prepare_* to tls13_add_*.
The SSL code suffers from needing too many verbs for variations on
writing things without actually writing them. We used to have queuing
the message up to be written to the buffer BIO, writing to the buffer
BIO, and flushing the buffer BIO. (Reading, conversely, has a similar
mess of verbs.)

Now we just have adding to the pending flight and flushing the pending
flight, match the SSL_PROTOCOL_METHOD naming.

BUG=72

Change-Id: I332966928bf13f03dfb8eddd519c2fefdd7f24d4
Reviewed-on: https://boringssl-review.googlesource.com/13227
Reviewed-by: Adam Langley <agl@google.com>
2017-01-25 23:37:30 +00:00
David Benjamin 81b7bc3979 Trim unnecessary TLS 1.3 states.
Large chunks of contiguous messages can now be sent in a row. Notably,
the ServerHello flight involves a number of optional messages which can
now be collapsed into straight-line code.

BUG=72

Change-Id: I1429d22a12401aa0f811a04e495bd5d754c084a4
Reviewed-on: https://boringssl-review.googlesource.com/13226
Reviewed-by: Adam Langley <agl@google.com>
2017-01-25 23:36:19 +00:00
David Benjamin 25ac251a1d Remove write_message from TLS 1.3 handshakes.
BUG=72

Change-Id: I4aad718762925191d85f0a468eeec4aa5d85d1e8
Reviewed-on: https://boringssl-review.googlesource.com/13225
Reviewed-by: Adam Langley <agl@google.com>
2017-01-25 23:36:02 +00:00
David Benjamin daf207a52a Don't use the buffer BIO in TLS.
On the TLS side, we introduce a running buffer of ciphertext. Queuing up
pending data consists of encrypting the record into the buffer. This
effectively reimplements what the buffer BIO was doing previously, but
this resizes to fit the whole flight.

As part of this, rename all the functions to add to the pending flight
to be more uniform. This CL proposes "add_foo" to add to the pending
flight and "flush_flight" to drain it.

We add an add_alert hook for alerts but, for now, only the SSL 3.0
warning alert (sent mid-handshake) uses this mechanism.  Later work will
push this down to the rest of the write path so closure alerts use it
too, as in DTLS. The intended end state is that all the ssl_buffer.c and
wpend_ret logic will only be used for application data and eventually
optionally replaced by the in-place API, while all "incidental" data
will be handled internally.

For now, the two buffers are mutually exclusive. Moving closure alerts
to "incidentals" will change this, but flushing application data early
is tricky due to wpend_ret. (If we call ssl_write_buffer_flush,
do_ssl3_write doesn't realize it still has a wpend_ret to replay.) That
too is all left alone in this change.

To keep the diff down, write_message is retained for now and will be
removed from the state machines in a follow-up change.

BUG=72

Change-Id: Ibce882f5f7196880648f25d5005322ca4055c71d
Reviewed-on: https://boringssl-review.googlesource.com/13224
Reviewed-by: Adam Langley <agl@google.com>
2017-01-25 23:35:47 +00:00
David Benjamin 1a999cf54d Don't use the buffer BIO in DTLS.
Instead, "writing" a message merely adds it to the outgoing_messages
structure. The code to write the flight then loops over it all and now
shares code with retransmission. The verbs here are all a little odd,
but they'll be fixed in later commits.

In doing so, this fixes a slight miscalculation of the record-layer
overhead when retransmitting a flight that spans two epochs. (We'd use
the encrypted epoch's overhead for the unencrypted epoch.)

BUG=72

Change-Id: I8ac897c955cc74799f8b5ca6923906e97d6dad17
Reviewed-on: https://boringssl-review.googlesource.com/13223
Reviewed-by: Adam Langley <agl@google.com>
2017-01-25 23:35:32 +00:00
David Benjamin 330282a654 Remove SHA_LBLOCK and SHA_LONG.
These are no longer used anywhere.

Change-Id: Id79299f92c705f6bb7aed7acb48994d4498bd2d8
Reviewed-on: https://boringssl-review.googlesource.com/13341
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-01-25 23:30:13 +00:00
David Benjamin 6d50f475e3 Remove support for RSA premaster logging.
This was replaced by the more general CLIENT_RANDOM scheme that records
the master secret. Support was added in Wireshark 1.8.0, released in
June 2012. At this point, ECDHE is sufficiently widely deployed that
anyone that cares about this feature must have upgraded their Wireshark
by now.

Change-Id: I9b708f245ec8728c1999daf91aca663be7d25661
Reviewed-on: https://boringssl-review.googlesource.com/13263
Reviewed-by: David Benjamin <davidben@google.com>
2017-01-25 16:48:35 +00:00
David Benjamin a772b16f9f Allow dtls_seal_record to work in-place.
This will let us avoid a scratch buffer when assembling DTLS handshake
packets in the write_message-less flow.

BUG=72

Change-Id: I15e78efe3a9e3933c307e599f0043427330f4a9e
Reviewed-on: https://boringssl-review.googlesource.com/13262
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-01-25 16:27:32 +00:00
David Benjamin 3b584332ee Fix ssl_test with BORINGSSL_ANDROID_SYSTEM.
We need to suppress a few tests on the system Android build until
RSA-PSS is shipped there.

Change-Id: I5843997aae9fa499ec08d76f44fdf3b523599e1c
Reviewed-on: https://boringssl-review.googlesource.com/13267
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-01-25 16:23:10 +00:00
David Benjamin c0263ab4c8 Don't leave ARCH unset for mips.
CMake's language is a little dumb about string interpolation. Set it to
"generic", which is the value OPENSSL_NO_ASM uses.

Change-Id: Id98a0309e24465f10bcd7dab4a2000d1038edac0
Reviewed-on: https://boringssl-review.googlesource.com/13261
Reviewed-by: Kenny Root <kroot@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
2017-01-24 22:27:11 +00:00
David Benjamin 5db7c9b8c2 Get OPENSSL_COMPILE_ASSERT working in function bodies.
Change-Id: Ifc28887cbf91c7a80bdaf56e3bf80b2f8cfa7d53
Reviewed-on: https://boringssl-review.googlesource.com/13260
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-01-24 21:30:33 +00:00
Adam Langley d1515a3b0a Move a number of X.509 functions from ssl_lib.c to ssl_x509.c
Eventually, all uses of crypto/x509 will be from ssl_x509.c, but this is
just a start.

Change-Id: I2f38cdcbf18b1f26add0aac10a70af10a79dee0e
Reviewed-on: https://boringssl-review.googlesource.com/13242
Reviewed-by: Adam Langley <agl@google.com>
2017-01-24 17:53:07 +00:00
Adam Langley 03b96d70f9 Remove unused |ssl_parse_x509|.
Change-Id: Id81297add5dcba8b861ca107a57a322df4c41c3d
Reviewed-on: https://boringssl-review.googlesource.com/13241
Reviewed-by: Adam Langley <agl@google.com>
2017-01-24 17:51:04 +00:00
David Benjamin 8d5f9da2e3 Abstract away BIO_flush calls in the handshake.
This is the first part to removing the buffer BIO. The eventual end
state is the SSL_PROTOCOL_METHOD is responsible for maintaining one
flight's worth of messages. In TLS, it will just be a buffer containing
the flight's ciphertext. In DTLS, it's the existing structure for
retransmit purposes. There will be hooks:

- add_message (synchronous)
- add_change_cipher_spec (synchronous)
- add_warning_alert (synchronous; needed until we lose SSLv3 client auth
  and TLS 1.3 draft 18; draft 19 will switch end_of_early_data to a
  handshake message)
- write_flight (BIO; flush_flight will be renamed to this)

This also preserves the exact return value of BIO_flush. Eventually all
the BIO_write calls will be hidden behind BIO_flush to, to be consistent
with other BIO-based calls, preserve the return value.

BUG=72

Change-Id: I74cd23759a17356aab3bb475a8ea42bd2cd115c9
Reviewed-on: https://boringssl-review.googlesource.com/13222
Reviewed-by: Adam Langley <agl@google.com>
2017-01-24 16:16:02 +00:00
Nick Harper 44c1a65760 Run go fmt on bogo code.
Change-Id: I15363a9c9ebb4e08bd9cf45ba2c95368766bb19b
Reviewed-on: https://boringssl-review.googlesource.com/13240
Reviewed-by: David Benjamin <davidben@google.com>
2017-01-24 00:29:38 +00:00
Adam Langley 1da9c67a99 Use a Perlasm variable rather than an #if to exclude the ChaCha20-Poly1305 asm on Windows.
The Windows assembler doesn't appear to do preprocessor macros but nor
can it cope with this style of label.

Change-Id: I0b8ca7372bb9ea0f20101ed138681d379944658e
Reviewed-on: https://boringssl-review.googlesource.com/13207
Reviewed-by: David Benjamin <davidben@google.com>
2017-01-23 22:05:06 +00:00
Adam Langley feca9e562c Emit ssl_[c|cc]_sources for Bazel.
Bazel doesn't allow one to give different flags for C and C++ files, so
trying to set -std=c11 for all ssl/ sources (which now include C++)
blows up.

This change splits the lists for Bazel so that they can be put in
different cc_library targets and thus have different flags.

Change-Id: I1e3dee01b6558de59246bc470527d44c9c86b188
Reviewed-on: https://boringssl-review.googlesource.com/13206
Reviewed-by: Adam Langley <agl@google.com>
2017-01-23 21:36:37 +00:00
vkrasnov 8d56558031 Optimized Seal/Open routines for ChaCha20-Poly1305 for x86-64
This is basically the same implementation I wrote for Go

The Go implementation:
https://github.com/golang/crypto/blob/master/chacha20poly1305/chacha20poly1305_amd64.s
The Cloudflare patch for OpenSSL:
https://github.com/cloudflare/sslconfig/blob/master/patches/openssl__chacha20_poly1305_draft_and_rfc_ossl102j.patch

The Seal/Open is only available for the new version, the old one uses
the bundled Poly1305, and the existing ChaCha20 implementations

The benefits of this code, compared to the optimized code currently
disabled in BoringSSL:

* Passes test vectors
* Faster performance: The AVX2 code (on Haswell), is 55% faster for 16B,
  15% for 1350 and 6% for 8192 byte buffers
* Even faster on pre-AVX2 CPUs

Feel free to put whatever license, etc. is appropriate, under the
existing CLA.

Benchmarks are for 16/1350/8192 chunk sizes and given in MB/s:

Before (Ivy Bridge): 34.2   589.5  739.4
After:               68.4   692.1  799.4
Before (Skylake):    50    1233   1649
After:              119.4  1736   2196
After (Andy's):      63.6  1608   2261

Change-Id: I9186f721812655011fc17698b67ddbe8a1c7203b
Reviewed-on: https://boringssl-review.googlesource.com/13142
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-01-23 21:12:44 +00:00
David Benjamin 358baeb9a4 Add missing src/ prefix to GTest sources.
Change-Id: I2ceb88f745db6fd16b30fe6f3f8fd9c29f0d3b8d
Reviewed-on: https://boringssl-review.googlesource.com/13234
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-01-23 20:19:40 +00:00
David Benjamin 5b410b6bec Remove unnecessary CBS_get_asn1_element.
EVP_parse_public_key already acts like CBS_get_* in that it peels one
element off and leaves a remainder.

Change-Id: Ic90952785005ed81664a6f46503b13ecd293176c
Reviewed-on: https://boringssl-review.googlesource.com/13045
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
2017-01-21 00:50:13 +00:00
Adam Langley 1aa4a5bdbd Delete unused Poly1305 assembly.
(These files weren't being built anyway.)

Change-Id: Id6c8d211b9ef867bdb7d83153458f9ad4e29e525
Reviewed-on: https://boringssl-review.googlesource.com/13205
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2017-01-21 00:17:30 +00:00
David Benjamin 966284337d Do a cursory conversion of a few tests to GTest.
For now, this is the laziest conversion possible. The intent is to just
get the build setup ready so that we can get everything working in our
consumers. The intended end state is:

- The standalone build produces three test targets, one per library:
  {crypto,ssl,decrepit}_tests.

- Each FOO_test is made up of:
    FOO/**/*_test.cc
    crypto/test/gtest_main.cc
    test_support

- generate_build_files.py emits variables crypto_test_sources and
  ssl_test_sources. These variables are populated with FindCFiles,
  looking for *_test.cc.

- The consuming file assembles those variables into the two test targets
  (plus decrepit) from there. This avoids having generate_build_files.py
  emit actual build rules.

- Our standalone builders, Chromium, and Android just run the top-level
  test targets using whatever GTest-based reporting story they have.

In transition, we start by converting one of two tests in each library
to populate the three test targets. Those are added to all_tests.json
and all_tests.go hacked to handle them transparently. This keeps our
standalone builder working.

generate_build_files.py, to start with, populates the new source lists
manually and subtracts them out of the old machinery. We emit both for
the time being. When this change rolls in, we'll write all the build
glue needed to build the GTest-based tests and add it to consumers'
continuous builders.

Next, we'll subsume a file-based test and get the consumers working with
that. (I.e. make sure the GTest targets can depend on a data file.)

Once that's all done, we'll be sure all this will work. At that point,
we start subsuming the remaining tests into the GTest targets and,
asynchronously, rewriting tests to use GTest properly rather than
cursory conversion here.

When all non-GTest tests are gone, the old generate_build_files.py hooks
will be removed, consumers updated to not depend on them, and standalone
builders converted to not rely on all_tests.go, which can then be
removed. (Unless bits end up being needed as a malloc test driver. I'm
thinking we'll want to do something with --gtest_filter.)

As part of this CL, I've bumped the CMake requirements (for
target_include_directories) and added a few suppressions for warnings
that GTest doesn't pass.

BUG=129

Change-Id: I881b26b07a8739cc0b52dbb51a30956908e1b71a
Reviewed-on: https://boringssl-review.googlesource.com/13232
Reviewed-by: Adam Langley <agl@google.com>
2017-01-21 00:17:05 +00:00
David Benjamin d1263b05a9 Stop emitting tests for gyp.
Chromium hasn't used gyp for a while. Get this out of the way for the
googletest transition.

BUG=129

Change-Id: Ic8808391d9f7de3e95cfc68654acf825389f6829
Reviewed-on: https://boringssl-review.googlesource.com/13231
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-01-21 00:12:22 +00:00
David Benjamin 9fb326d47e Fix MSVC C4826 issues in googletest.
This applies https://github.com/google/googletest/pull/991.

BUG=129

Change-Id: I3df7e265652f2a337721634b5ba8adf76ff7d828
Reviewed-on: https://boringssl-review.googlesource.com/13233
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-01-21 00:12:17 +00:00
David Benjamin c10c29861d Fix ColorPrintf issues in googletest.
This applies https://github.com/google/googletest/pull/965.

BUG=129

Change-Id: Id5fda923b0d3c26e6e004dc292c8d2cbd3729b45
Reviewed-on: https://boringssl-review.googlesource.com/13230
Reviewed-by: David Benjamin <davidben@google.com>
2017-01-21 00:12:10 +00:00
David Benjamin 9b5028523f Check in a pristine copy of googletest.
Snapshotted from 5e7fd50e17b6edf1cadff973d0ec68966cf3265e in the
upstream repository:
https://github.com/google/googletest

Since standalone builds and bots will need this, checking in a copy
rather than require everyone use gclient, repo, git submodules or scary
CMake scripts is probably simplest.

Consumers with their own copies of googletest will likely wish to ignore
or even exclude this directory.

BUG=129

Change-Id: If9f4cec5ae0d7a3976dcfffd1ead6950ef7b7c4e
Reviewed-on: https://boringssl-review.googlesource.com/13229
Reviewed-by: David Benjamin <davidben@google.com>
2017-01-21 00:10:13 +00:00
Alessandro Ghedini 958346a5e7 Run select_certificate_cb multiple times
It's not completely clear to me why select_cetificate_cb behaves the way it
does, however not only is it confusing, but it makes assumptions about the
application using BoringSSL (it's not always possible to implement custom
logic outside of the callbacks provided by libssl), that make this callback
somewhat useless.

Case in point, the callback can be used for changing min/max protocol versions
based on per-site policies, and select_certificate_cb is the only place where
SSL_set_min/max_proto_version() can be used (e.g. you can't call them in
cert_cb because it's too late), but the decision on the specific versions to
use might depend on configuration that needs retrieving asynchronously from
over the network, which requires re-running the callback multiple times.

Change-Id: Ia8e151b163628545373e7fd1f327e9af207478a6
Reviewed-on: https://boringssl-review.googlesource.com/13000
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
2017-01-20 23:55:50 +00:00
Adam Langley 5c7a4b8c2f Add test for truncated AEAD tags.
Several of our AEADs support truncated tags, but I don't believe that we
had a test for them previously.

Change-Id: I63fdd194c47c17b3d816b912a568534c393df9d8
Reviewed-on: https://boringssl-review.googlesource.com/13204
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-01-20 21:45:47 +00:00
David Benjamin 07820b5cee Add a getter for SSL_set_session_id_context.
We have a test somewhere which tries to read off of it. Align the getter
roughly with upstream's SSL_SESSION_get0_id_context (which we don't
currently expose).

BUG=6

Change-Id: Iab240868838ba56c1f08d112888d9536574347b4
Reviewed-on: https://boringssl-review.googlesource.com/12636
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>
2017-01-20 04:39:42 +00:00
Adam Langley 2e839244b0 Remove old ChaCha20-Poly1305 AEAD.
Before RFC 7539 we had a ChaCha20-Poly1305 cipher suite that had a 64/64
nonce/counter split (as DJB's original ChaCha20 did). RFC 7539 changed
that to 96/32 and we've supported both for some time.

This change removes the old version and the TLS cipher suites that used
it.

BUG=chromium:682816

Change-Id: I2345d6db83441691fe0c1ab6d7c6da4d24777849
Reviewed-on: https://boringssl-review.googlesource.com/13203
Reviewed-by: Adam Langley <agl@google.com>
2017-01-19 23:27:54 +00:00
Adam Langley 5322010405 Revert "Remove old ChaCha20-Poly1305 AEAD."
This reverts commit def9b46801.

(I should have uploaded a new version before sending to the commit queue.)

Change-Id: Iaead89c8d7fc1f56e6294d869db9238b467f520a
Reviewed-on: https://boringssl-review.googlesource.com/13202
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-01-19 23:07:06 +00:00
David Benjamin 6752efdeaf Never send SNI warning alerts.
TLS 1.3 forbids warning alerts, and sending these is a bad idea. Per RFC
6066:

   If the server understood the ClientHello extension but
   does not recognize the server name, the server SHOULD take one of two
   actions: either abort the handshake by sending a fatal-level
   unrecognized_name(112) alert or continue the handshake.  It is NOT
   RECOMMENDED to send a warning-level unrecognized_name(112) alert,
   because the client's behavior in response to warning-level alerts is
   unpredictable.

The motivation is to cut down on the number of places where we send
non-closing alerts. We can't remove them yet (SSL 3.0 and TLS 1.3 draft
18 need to go), but eventually this can be a simplifying assumption.
Already this means DTLS never sends warning alerts, which is good
because DTLS can't retransmit them.

Change-Id: I577a1eb9c23e66d28235c0fbe913f00965e19486
Reviewed-on: https://boringssl-review.googlesource.com/13221
Reviewed-by: Adam Langley <agl@google.com>
2017-01-19 23:03:11 +00:00
David Benjamin a8c8b387f1 Don't call the SNI callback as a client.
This doesn't do anything useful. Every caller either never sets the
callback as a client or goes out of their way to filter out clients in
the callback.

Change-Id: I6f07d000a727f9ccba080f812e6b8e7a38e04350
Reviewed-on: https://boringssl-review.googlesource.com/13220
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-01-19 22:57:46 +00:00
Adam Langley def9b46801 Remove old ChaCha20-Poly1305 AEAD.
Before RFC 7539 we had a ChaCha20-Poly1305 cipher suite that had a 64/64
nonce/counter split (as DJB's original ChaCha20 did). RFC 7539 changed
that to 96/32 and we've supported both for some time.

This change removes the old version and the TLS cipher suites that used
it.

Change-Id: Icd9c2117c657f3aa6df55990c618d562194ef0e8
Reviewed-on: https://boringssl-review.googlesource.com/13201
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
2017-01-19 22:54:50 +00:00
David Benjamin 1252f8758a Convert one libssl function to C++11.
This is to make sure all of libssl's consumers' have sufficiently
reasonable toolchains. Once this bakes, we can go about moving
libssl to C++.

This is just starting with libssl for now because libcrypto has more
consumers and libssl would benefit more from C++ than libcrypto (though
libcrypto also has code that would benefit).

BUG=132

Change-Id: Ie02f7b0a8a95defd289cc7e62451d4b16408ca2a
Reviewed-on: https://boringssl-review.googlesource.com/13161
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-01-17 21:51:06 +00:00
Alessandro Ghedini 0726fb76eb Add SSL_CIPHER_is_AEAD.
Change-Id: Ia6598ee4b2d4623abfc140d6a5c0eca4bcb30427
Reviewed-on: https://boringssl-review.googlesource.com/13180
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>
2017-01-17 16:41:49 +00:00
Brian Smith a26d4c3f43 Enable stitched x86-64 AES-NI AES-GCM implementation.
Measured on a SkyLake processor:

Before:

Did 11373750 AES-128-GCM (16 bytes) seal operations in 1016000us (11194635.8 ops/sec): 179.1 MB/s
Did 2253000 AES-128-GCM (1350 bytes) seal operations in 1016000us (2217519.7 ops/sec): 2993.7 MB/s
Did 453750 AES-128-GCM (8192 bytes) seal operations in 1015000us (447044.3 ops/sec): 3662.2 MB/s
Did 10753500 AES-256-GCM (16 bytes) seal operations in 1016000us (10584153.5 ops/sec): 169.3 MB/s
Did 1898750 AES-256-GCM (1350 bytes) seal operations in 1015000us (1870689.7 ops/sec): 2525.4 MB/s
Did 374000 AES-256-GCM (8192 bytes) seal operations in 1016000us (368110.2 ops/sec): 3015.6 MB/s

After:

Did 11074000 AES-128-GCM (16 bytes) seal operations in 1015000us (10910344.8 ops/sec): 174.6 MB/s
Did 3178250 AES-128-GCM (1350 bytes) seal operations in 1016000us (3128198.8 ops/sec): 4223.1 MB/s
Did 734500 AES-128-GCM (8192 bytes) seal operations in 1016000us (722933.1 ops/sec): 5922.3 MB/s
Did 10394750 AES-256-GCM (16 bytes) seal operations in 1015000us (10241133.0 ops/sec): 163.9 MB/s
Did 2502250 AES-256-GCM (1350 bytes) seal operations in 1016000us (2462844.5 ops/sec): 3324.8 MB/s
Did 544500 AES-256-GCM (8192 bytes) seal operations in 1015000us (536453.2 ops/sec): 4394.6 MB/s

Change-Id: If058935796441ed4e577b9a72d3aa43422edba58
Reviewed-on: https://boringssl-review.googlesource.com/7273
Reviewed-by: Adam Langley <alangley@gmail.com>
2017-01-16 16:54:13 +00:00
Adam Langley abb32cc00d Restore H (the key) in the GHASH context.
This was removed in a00cafc50c because
none of the assembly actually appeared to need it. However, we found the
assembly the uses it: the MOVBE-based, x86-64 code.

Needing H seems silly since Htable is there, but rather than mess with
the assembly, it's easier to put H back in the structure—now with a
better comment.

Change-Id: Ie038cc4482387264d5e0821664fb41f575826d6f
Reviewed-on: https://boringssl-review.googlesource.com/13122
Reviewed-by: Adam Langley <alangley@gmail.com>
2017-01-16 16:53:32 +00:00
Aaron Green 67ccf59161 Fix crypto/rand/urandom header guards for Fuchsia.
Fuchsia uses crypto/rand/fuchsia.c for CRYPTO_sysrand, and so must be
excluded from the Linux/Apple/POSIX variant.

Change-Id: Ide9f0aa2547d52ce0579cd0a1882b2cdcc7b95c6
Reviewed-on: https://boringssl-review.googlesource.com/13141
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-01-14 01:03:01 +00:00
David Benjamin c253864993 Remove some node.js hacks.
These are no longer needed.

Change-Id: I909f7d690f57dafcdad6254948b5683757da69f4
Reviewed-on: https://boringssl-review.googlesource.com/13160
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-01-13 21:50:39 +00:00
Aaron Green c80e416353 Add support for Fuchsia in crypto/rand.
This change adds the OS-specific routines to get random bytes when using
BoringSSL on Fuchsia.  Fuchsia uses the Magenta kernel, which provides
random bytes via a syscall rather than via a file or library function.

Change-Id: I32f858246425309d643d142214c7b8de0c62250a
Reviewed-on: https://boringssl-review.googlesource.com/13140
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>
2017-01-13 21:47:11 +00:00
Brian Smith b4cc925c30 Remove specialized assembly language |ecp_nistz256_from_mont|.
This function is only called twice per ECDH or ECDSA operation, and
it only saves a few scalar multiplications and additions compared to
the alternative, so it doesn't need to be specialized.

As the TODO comment above the callers notes, the two calls can be
reduced to one. Implementing |ecp_nistz256_from_mont| in terms of
|ecp_nistz256_mul_mont| helps show that that change is safe.

This also saves a small amount of code size and improves testing and
verification efficiency.

Note that this is already how the function is implemented for targets
other than x86-64 in OpenSSL.

Change-Id: If1404951f1a787d2618c853afd1f0e99a019e012
Reviewed-on: https://boringssl-review.googlesource.com/13021
Reviewed-by: Adam Langley <alangley@gmail.com>
2017-01-13 17:27:13 +00:00
Brian Smith a2bdbb60ec Remove unused cp_nistz256_mul_by_2.
Change-Id: I7fbe3effec27a18c5c42e6140df9ebd6229e06df
Reviewed-on: https://boringssl-review.googlesource.com/13020
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-01-13 01:28:33 +00:00
Brian Smith cb42354ac3 Clarify x86 GCM asm implementation dispatching.
There is no AVX implementation for x86. Previously on x86 the code
checked to see if AVX and MOVBE are available, and if so, then it
uses the CLMUL implementation. Otherwise it fell back to the same
CLMUL implementation. Thus, there is no reason to check if AVX + MOVBE
are enabled on x86.

Change-Id: Id4983d5d38d6b3269a40e288bca6cc51d2d13966
Reviewed-on: https://boringssl-review.googlesource.com/13024
Reviewed-by: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <alangley@gmail.com>
2017-01-13 01:22:26 +00:00
Brian Smith 18a37a4211 Remove unused "pure" MMX x86 GCM implementation.
BoringSSL will always use the SSE version so this is all dead code.

Change-Id: I0f3b51ee29144b5c83d2553c92bebae901b6366f
Reviewed-on: https://boringssl-review.googlesource.com/13023
Reviewed-by: Adam Langley <alangley@gmail.com>
2017-01-13 01:19:01 +00:00
Brian Smith ac153bded3 Remove unused non-MMX/SSE GCM assembly code.
BoringSSL can assume that MMX, SSE, and SSE2 is always supported so
there is no need for a runtime check and there's no need for this
fallback code. Removing the code improves coverage analysis and shrinks
code size.

Change-Id: I782a1bae228f700895ada0bc56687e53cd02b5df
Reviewed-on: https://boringssl-review.googlesource.com/13022
Reviewed-by: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <alangley@gmail.com>
Commit-Queue: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <alangley@gmail.com>
2017-01-13 01:11:11 +00:00
David Benjamin 6a0888dd52 Save one call to |ecp_nistz256_from_mont| in |ecp_nistz256_get_affine|.
This re-applies 3f3358ac15 which was
reverted in c7fe3b9ac5 because the field
operations did not fully-reduce operands. This was fixed in
2f1482706fadf51610a529be216fde0721709e66.

Change-Id: I3913af4b282238dbc21044454324123f961a58af
Reviewed-on: https://boringssl-review.googlesource.com/12227
Reviewed-by: Adam Langley <agl@google.com>
2017-01-12 21:10:17 +00:00
David Benjamin 745745df03 Add SSL_CIPHER_is_static_RSA.
Change-Id: Id0013a2441da206b051a05a39aa13e4eca937e03
Reviewed-on: https://boringssl-review.googlesource.com/13109
Reviewed-by: Adam Langley <agl@google.com>
2017-01-12 18:37:19 +00:00
David Benjamin 5fc99c6603 There are no more MD5 ciphers.
The last one was an RC4 cipher and those are gone.

Change-Id: I3473937ff6f0634296fc75a346627513c5970ddb
Reviewed-on: https://boringssl-review.googlesource.com/13108
Reviewed-by: Adam Langley <agl@google.com>
2017-01-12 18:36:54 +00:00
Adam Langley dcecdfd620 Fix a couple of missing spaces in comments.
Change-Id: If8b5dea31d7f37b3b33ea41e7a6a33240cb5ee5b
Reviewed-on: https://boringssl-review.googlesource.com/13121
Reviewed-by: Adam Langley <agl@google.com>
2017-01-12 18:35:25 +00:00
David Benjamin 1d6eeb3b85 Spellcheck our public headers.
Also fix some formatting.

Change-Id: I8fb1a95d4a55e40127433f0114fd08a82a4c3d41
Reviewed-on: https://boringssl-review.googlesource.com/13103
Reviewed-by: Adam Langley <agl@google.com>
2017-01-12 18:24:27 +00:00
David Benjamin e3fbb36005 Test SSL_set_max_send_fragment.
This gives coverage over needing to fragment something over multiple
records.

Change-Id: I2373613608ef669358d48f4e12f68577fa5a40dc
Reviewed-on: https://boringssl-review.googlesource.com/13101
Reviewed-by: Adam Langley <agl@google.com>
2017-01-12 18:22:08 +00:00
David Benjamin 8b8d22c961 Parse PKCS#12 files more accurately.
Mercifully, PKCS#12 does not actually make ContentInfo and SafeBag
mutually recursive. The top-level object in a PKCS#12 is a SEQUENCE of
data or encrypted data ContentInfos. Their payloads are a SEQUENCE of
SafeBags (aka SafeContents).

SafeBag is a similar structure to ContentInfo but not identical (it has
attributes in it which we ignore) and actually carries the objects.
There is only recursion if the SafeContents bag type is used, which we
do not process.

This means we don't need to manage recursion depth. This also no longer
allows trailing data after the SEQUENCE and removes the comment about
NSS. The test file still passes, so I'm guessing something else was
going on?

Change-Id: I68e2f8a5cc4b339597429d15dc3588bd39267e0a
Reviewed-on: https://boringssl-review.googlesource.com/13071
Reviewed-by: Adam Langley <agl@google.com>
2017-01-12 16:56:05 +00:00
David Benjamin 2df010e4f4 Remove 'pivot element' from wNAF code.
Resolving the TODO here will be messier than the other implementations
but, to start with, remove this 'pivot element' thing. All that is just
to free some array contents without having to memset the whole thing to
zero.

Change-Id: Ifd6ee0b3815006d4f1f19c9db085cb842671c6dc
Reviewed-on: https://boringssl-review.googlesource.com/13057
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-01-12 16:45:23 +00:00
David Benjamin 0a211dfe91 Remove BN_FLG_CONSTTIME.
BN_FLG_CONSTTIME is a ridiculous API and easy to mess up
(CVE-2016-2178). Instead, code that needs a particular algorithm which
preserves secrecy of some arguemnt should call into that algorithm
directly.

This is never set outside the library and is finally unused within the
library! Credit for all this goes almost entirely to Brian Smith. I just
took care of the last bits.

Note there was one BN_FLG_CONSTTIME check that was still reachable, the
BN_mod_inverse in RSA key generation. However, it used the same code in
both cases for even moduli and φ(n) is even if n is not a power of two.
Traditionally, RSA keys are not powers of two, even though it would make
the modular reductions a lot easier.

When reviewing, check that I didn't remove a BN_FLG_CONSTTIME that led
to a BN_mod_exp(_mont) or BN_mod_inverse call (with the exception of the
RSA one mentioned above). They should all go to functions for the
algorithms themselves like BN_mod_exp_mont_consttime.

This CL shows the checks are a no-op for all our tests:
https://boringssl-review.googlesource.com/c/12927/

BUG=125

Change-Id: I19cbb375cc75aac202bd76b51ca098841d84f337
Reviewed-on: https://boringssl-review.googlesource.com/12926
Reviewed-by: Adam Langley <alangley@gmail.com>
2017-01-12 02:00:44 +00:00
David Benjamin d261004048 Report TLS 1.3 as supporting secure renegotiation.
TLS 1.3 doesn't support renegotiation in the first place, but so callers
don't report TLS 1.3 servers as missing it, always report it as
(vacuously) protected against this bug.

BUG=chromium:680281

Change-Id: Ibfec03102b2aec7eaa773c331d6844292e7bb685
Reviewed-on: https://boringssl-review.googlesource.com/13046
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>
2017-01-11 22:19:17 +00:00
David Benjamin 7f539fa008 Handle overflow in ascii_to_ucs2.
Change-Id: Ie9a0039931a1a8d48a82c11ef5c58d6ee084ca4c
Reviewed-on: https://boringssl-review.googlesource.com/13070
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <alangley@gmail.com>
2017-01-11 01:27:18 +00:00
David Benjamin 9d0e7fb6e7 Rework PKCS{5,8,12} code.
Avoid the X509_ALGOR dependency entirely. The public API is still using
the legacy ASN.1 structures for now, but the conversions are lifted to
the API boundary. Once we resolve that and the OID table dependency,
this module will no longer block unshipping crypto/asn1 and friends from
Chromium.

This changes the calling convention around the two kinds of PBE suites
we support. Each PBE suite provides a free-form encrypt_init function to
setup an EVP_CIPHER_CTX and write the AlgorithmIdentifer to a CBB. It
then provides a common decrypt_init function which sets up an
EVP_CIPHER_CTX given a CBS of the parameter. The common encrypt code
determines how to call which encrypt_init function. The common decrypt
code parses the OID out of the AlgorithmIdentifer and then dispatches to
decrypt_init.

Note this means the encryption codepath no longer involves parsing back
out a AlgorithmIdentifier it just serialized. We don't have a good story
to access an already serialized piece of a CBB in progress (reallocs can
invalidate the pointer in a CBS), so it's easier to cut this step out
entirely.

Also note this renames the "PBES1" schemes from PKCS#5 to PKCS#12. This
makes it easier to get at the PKCS#12 key derivation hooks. Although
PKCS#12 claims these are variants of PKCS#5's PBES1, they're not very
related. PKCS#12 swaps out the key derivation and even defines its own
AlgorithmIdentifier parameter structure (identical to the PKCS#5 PBES1
one). The only thing of PBES1 that survives is the CBC mode padding
scheme, which is deep in EVP_CIPHER for us. (Of course, all this musing
on layering is moot because we don't implement non-PKCS#12 PBES1 schemes
anyway.)

This also moves some of the random API features (default iteration
count, default salt generation) out of the PBE suites and into the
common code.

BUG=54

Change-Id: Ie96924c73a229be2915be98eab680cadd17326db
Reviewed-on: https://boringssl-review.googlesource.com/13069
Reviewed-by: Adam Langley <alangley@gmail.com>
2017-01-11 01:25:14 +00:00
David Benjamin 314d81420c Reimplement pkcs12_pbe_keyivgen with CBS.
BUG=54

Change-Id: Ie003a9635b33ad6f7e430684f0eb6975c613ebf3
Reviewed-on: https://boringssl-review.googlesource.com/13068
Reviewed-by: Adam Langley <alangley@gmail.com>
2017-01-11 00:54:08 +00:00
David Benjamin d1afc41869 Reimplement PKCS5_pbe_set with CBB.
BUG=54

Change-Id: I41bd43948140037c8e5c1b6502e1c882293befec
Reviewed-on: https://boringssl-review.googlesource.com/13067
Reviewed-by: Adam Langley <alangley@gmail.com>
2017-01-11 00:51:52 +00:00
Adam Langley 2a25aae0f5 Ensure that CBB is |CBB_zero|ed before possibly calling |CBB_cleanup|.
Change-Id: Ic1f58f87c67104c8a51af59086a1bb1e5ccb0e5b
Reviewed-on: https://boringssl-review.googlesource.com/13084
Reviewed-by: Adam Langley <alangley@gmail.com>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Adam Langley <alangley@gmail.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-01-11 00:49:37 +00:00
David Benjamin 4fae069c00 Reimplement PKCS5_v2_PBE_keyivgen.
This gets us closer to decoupling from crypto/asn1.

BUG=54

Change-Id: I06ec04ed3cb47c2f56a94c6defa97398bfd0e013
Reviewed-on: https://boringssl-review.googlesource.com/13066
Reviewed-by: Adam Langley <alangley@gmail.com>
2017-01-11 00:37:56 +00:00
David Benjamin e464e81f89 Reimplement PKCS5_pbe2_set with CBB.
This is not quite an end state (it still outputs an X509_ALGOR, the way
the generated salt is fed into key derivation is odd, and it uses the
giant OID table), but replaces a large chunk of it.

BUG=54

Change-Id: I0a0cca13e44e6a09dfaf6aed3b357cb077dc46d1
Reviewed-on: https://boringssl-review.googlesource.com/13065
Reviewed-by: Adam Langley <alangley@gmail.com>
Commit-Queue: Adam Langley <alangley@gmail.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-01-11 00:34:25 +00:00
David Benjamin ac83bea85d Trim dead code from PKCS#5 PBE2 bits.
Many of these parameters are constants.

Change-Id: I148dbea0063e478a132253f4e9dc71d5d20320c2
Reviewed-on: https://boringssl-review.googlesource.com/13064
Reviewed-by: Adam Langley <alangley@gmail.com>
Commit-Queue: Adam Langley <alangley@gmail.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-01-11 00:13:59 +00:00
David Benjamin 9ba19b8e88 Test we can round-trip PKCS8_{encrypt,decrypt}.
This is a very basic test, but it's something.

Change-Id: Ic044297e97ce5719673869113ce581de4621ebbd
Reviewed-on: https://boringssl-review.googlesource.com/13061
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <alangley@gmail.com>
2017-01-10 23:49:37 +00:00
David Benjamin a5eee1c7f3 Decouple EVP_get_digestbyobj from the giant OID table.
libcrypto can now be split in two, with everything that depends on
crypto/asn1 in a separate library. That said, Chromium still needs
crypto/pkcs8 to be implemented with CBS/CBB first. (Also libssl and
anything which uses X509* directly.)

BUG=54

Change-Id: Iec976ae637209882408457e94a1eb2465bce8d56
Reviewed-on: https://boringssl-review.googlesource.com/13059
Reviewed-by: Adam Langley <alangley@gmail.com>
Commit-Queue: Adam Langley <alangley@gmail.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-01-10 23:45:00 +00:00
David Benjamin 8f3f6be0d5 Const-correct the PKCS8 salt parameter.
Change-Id: Iad9b0898b3a602fc2e554c4fd59a599c61cd8ef7
Reviewed-on: https://boringssl-review.googlesource.com/13063
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <alangley@gmail.com>
2017-01-10 23:42:10 +00:00
David Benjamin 35349e9fac Unexport PKCS5 functions.
They're not called externally. Unexporting these will make it easier to
rewrite the PKCS{5,8,12} code to use CBS/CBB rather than X509_ALGOR.
Getting rid of those callers in Chromium probably won't happen for a
while since it's in our on-disk formats. (And a unit test for some NSS
client cert glue uses it.)

BUG=54

Change-Id: Id4148a2ad567484782a6e0322b68dde0619159fc
Reviewed-on: https://boringssl-review.googlesource.com/13062
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <alangley@gmail.com>
2017-01-10 23:41:44 +00:00
David Benjamin 20dbc1ff20 Import some PKCS8_decrypt test vectors from Chromium.
This includes examples with both the NULL and empty passwords, thanks to
PKCS#12's password ambiguity.

Change-Id: Iae31840c1d31929fa9ac231509acaa80ef5b74bb
Reviewed-on: https://boringssl-review.googlesource.com/13060
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <alangley@gmail.com>
2017-01-10 23:40:54 +00:00
Matthew Braithwaite e2c083dfd6 ASN1_UTCTIME_print: fix, comment, test.
The motiviation is that M2Crypto passes an ASN1_GENERALIZEDTIME to
this function.  This is not distinct from ASN1_UTCTIME (both are
asn1_string_st), but ASN1_GENERALIZEDTIME uses a 4-digit year in its
string representation, whereas ASN1_UTCTIME uses a 2-digit year.

ASN1_UTCTIME_print previously did not return an error on such inputs.
So, stricten (?) the function, ensuring that it checks for trailing
data, and rejects values that are invalid for their place.  Along the
way, clean it up and add tests.

Change-Id: Ia8298bed573f2acfdab96638ea69c78b5bba4e4b
Reviewed-on: https://boringssl-review.googlesource.com/13082
Reviewed-by: Adam Langley <alangley@gmail.com>
Commit-Queue: Adam Langley <alangley@gmail.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-01-10 23:32:12 +00:00
David Benjamin 7c7ab21781 Guard a winsock2.h include under the usual pragmas.
We missed this one. Microsoft doesn't usually pass their own level 4
warnings. Kenny Root reports this otherwise trips warnings on some
version of the Windows SDK.

Change-Id: I71dc837ff8ee52321483d26c3a2cd8676393d999
Reviewed-on: https://boringssl-review.googlesource.com/13110
Reviewed-by: Kenny Root <kroot@google.com>
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>
2017-01-10 20:30:48 +00:00
David Benjamin 9c33ae8562 Fix TLS 1.3 NewSessionTicket processing.
08b65f4e31 introduced a memory leak and
also got enums confused. Also fix a codepath that was missing an error
code.

Thanks to OSS-Fuzz which appears to have found it in a matter of hours.

Change-Id: Ia9e926c28a01daab3e6154d363d0acda91209a22
Reviewed-on: https://boringssl-review.googlesource.com/13104
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-01-09 03:37:19 +00:00
David Benjamin 6add9f172c Fix setsockopt call.
Neither Windows nor POSIX uses a char for SO_REUSEADDR. Windows uses
BOOL (which is actually int) and POSIX uses int. Windows also requires a
cast due to using char* instead of void*. Thanks to Daniel Hirche for
reporting.

Change-Id: I01c847c8da285f27f3c3cdf5ff58b53899098b82
Reviewed-on: https://boringssl-review.googlesource.com/13100
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>
2017-01-06 21:15:28 +00:00
Rob Sloan 45573cc04d Add Little-endian BIGNUM conversions
Towards an eventual goal of opaquifying BoringSSL structs, we want
our consumers -- in this case, Android's libcore -- to not directly
manipulate BigNums; and it would be convenient for them if we would
perform the appropriate gymnastics to interpret little-endian byte
streams.

It also seems a priori a bit strange to have only big-endian varieties
of BN byte-conversions.

This CL provides little-endian equivalents of BN_bn2bin_padded
and BN_bin2bn.

BUG=97
Change-Id: I0e92483286def86d9bd71a46d6a967a3be50f80b
Reviewed-on: https://boringssl-review.googlesource.com/12641
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>
2017-01-06 18:20:09 +00:00
Steven Valdez 08b65f4e31 Enabling 0-RTT on new Session Tickets.
This adds support for setting 0-RTT mode on tickets minted by
BoringSSL, allowing for testing of the initial handshake knowledge.

BUG=76

Change-Id: Ic199842c03b5401ef122a537fdb7ed9e9a5c635a
Reviewed-on: https://boringssl-review.googlesource.com/12740
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>
2017-01-06 16:24:43 +00:00
David Benjamin c0c7019282 Simplify ec_GFp_nistp224_points_mul logic.
Passing in an array of scalars was removed some time ago, but a few
remnants of it remain.

Change-Id: Id75abedf60b1eab59f24bf7232187675b63291ab
Reviewed-on: https://boringssl-review.googlesource.com/13056
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-01-05 23:32:59 +00:00
David Benjamin d2242407bb Don't accept signature OIDs in EVP_get_digestby{nid,obj}.
This is a remnant of signature EVP_MDs. Detach them from
EVP_get_digestby{nid,obj}. Nothing appears to rely on this for those two
functions. Alas, Node.js appears to rely on it for EVP_get_digestbyname,
so keep that working.

This avoids causing every consumer's parsing to be unintentionally lax.
It also means fewer OIDs to transcribe when detaching the last of
libcrypto from the legacy ASN.1 stack and its giant OID table.

Note this is an externally visible change. There was one consumer I had
to fix, but otherwise everything handled things incorrectly due to this
quirk, so it seemed better to just fix the API rather than fork off a
second set.

Change-Id: I705e073bc05d946e71cd1c38acfa5e3c6b0a22b4
Reviewed-on: https://boringssl-review.googlesource.com/13058
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-01-05 23:30:48 +00:00
David Benjamin 9cbd55994f Simplify ec_GFp_nistp256_points_mul logic.
Passing in an array of scalars was removed some time ago, but a few
remnants of it remain.

Change-Id: Ia51dcf1f85116ec663e657cc8dbef7f23ffa2edb
Reviewed-on: https://boringssl-review.googlesource.com/13055
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-01-05 23:23:46 +00:00
Steven Valdez bf5bda37cf Adding socket reuse to bssl server.
This allows a server to be restarted immediately with the same port
without having to wait for socket timeout on crash/failure.

Change-Id: Ifcf58d46067f157dd504946f71b0b99d7fbad10c
Reviewed-on: https://boringssl-review.googlesource.com/13044
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>
2017-01-04 14:21:45 +00:00
David Benjamin 0b8dc30932 Don't use BN_mod_inverse for inverses mod p in RSA keygen.
Instead, use BN_mod_exp_mont_consttime of p - 2. This removes two more
call sites sensitive to BN_FLG_CONSTTIME. We're down to just that last
BN_mod_inverse modulo φ(n). (Sort of. It's actually not sensitive
because even mod inverses always hit the other codepath. Perhaps we
should just leave it alone.)

Note this comes with a slight behavior change. The BN_MONT_CTXs are
initialized a little earlier. If a caller calls RSA_generate_* and then
reaches into the struct to scrap all the fields on it, they'll get
confused. Before, they had to perform an operation on it to get
confused. This is a completely ridiculous thing to do.

Since we do this a lot, this introduces some convenience functions for
doing the Fermat's Little Theorem mod inverse and fixes a leak in the
DSA code should computing kinv hit a malloc error.

BUG=125

Change-Id: Iafcae2fc6fd379d161f015c90ff7050e2282e905
Reviewed-on: https://boringssl-review.googlesource.com/12925
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2017-01-04 13:56:11 +00:00
David Benjamin 053fee9f79 Enforce the SSL 3.0 no_certificate alert in tests.
As long as we still have this code, we should make sure it doesn't
regress.

Change-Id: I0290792aedcf667ec49b251d747ffbc141c0cec4
Reviewed-on: https://boringssl-review.googlesource.com/13053
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-01-04 13:41:56 +00:00
David Benjamin 48063c2aea Add tests around SSL_write's retry behavior.
SSL_write is remarkably complicated.

Change-Id: I1cb8d00af1b4c5e2d90187d5f87951f25e27f224
Reviewed-on: https://boringssl-review.googlesource.com/13050
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>
2017-01-04 04:54:04 +00:00
David Benjamin a660e7ab67 Don't clear cert_request in ssl3_send_client_certificate.
Instead, add ssl_has_certificate to the ssl3_send_cert_verify check. If
writing the empty Certificate does not complete synchronously (it almost
always does due to the buffer BIO), but if the buffer boundary is at
exactly the wrong place, write_message will need a retry but, having
cleared cert_request, we never re-enter ssl3_send_client_certificate.

This will later be moot when we've gotten rid of the buffer BIO, but
this is cleaner anyway and is closer to the TLS 1.3 code.

With this change, blindly taking away the BIO buffer in TLS (which is
not what we want since we want the entire flight in one write but is a
nice sanity check), only the SSL 3.0 no client certificate tests fail.
They too rely on some writes completing synchronously due to SSL 3.0
sending a warning alert. There is a similar bug when
tlsext_servername_callback returns SSL_TLSEXT_ERR_ALERT_WARNING.

Those will be resolved after reworking the write path since it's a bit
of a mess.

Change-Id: I56b4df6163cae1df263cf36f0d93046d0375a5ac
Reviewed-on: https://boringssl-review.googlesource.com/13052
Reviewed-by: David Benjamin <davidben@google.com>
2017-01-04 04:50:00 +00:00
David Benjamin 2be4aa7164 Add a helper function for resetting SSL_get_error state.
We repeat this in a bunch of places.

Change-Id: Iee2c95a13e1645453f101d8be4be9ac78d520387
Reviewed-on: https://boringssl-review.googlesource.com/13051
Reviewed-by: David Benjamin <davidben@google.com>
2017-01-04 04:48:44 +00:00
David Benjamin 3fa1e21be4 Test invalid inputs for AES_unwrap_key.
There's an authenticator, so test that AES_unwrap_key notices invalid
inputs.

Change-Id: Icbb941f91ffd9c91118f956fd74058d241f91ecb
Reviewed-on: https://boringssl-review.googlesource.com/13047
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>
2017-01-04 04:37:46 +00:00
David Benjamin a1eaba1dc6 Add a test for renegotiation on busy write buffer.
The write path for TLS is going to need some work. There are some fiddly
cases when there is a write in progress. Start adding tests to cover
this logic.

Later I'm hoping we can extend this flag so it drains the unfinished
write and thus test the interaction of read/write paths in 0-RTT. (We
may discover 1-RTT keys while we're in the middle of writing data.)

Change-Id: Iac2c417e4b5e84794fb699dd7cbba26a883b64ef
Reviewed-on: https://boringssl-review.googlesource.com/13049
Reviewed-by: Adam Langley <agl@google.com>
2017-01-04 01:54:57 +00:00
David Benjamin f53e390962 Import RSA decryption tests from upstream.
(Imported from upstream's 13ab87083af862e4af752efa4b0552149ed2cc19.)

Change-Id: I2f7cf8454d28d47f5ca19544479b2ab98143a3ef
Reviewed-on: https://boringssl-review.googlesource.com/13048
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-01-04 01:47:53 +00:00
David Benjamin 322f431b20 Fix API-CONVENTIONS.md typos.
Change-Id: Iba299b1bcfe7de53bb0fa6b6cc4e607129905fd0
Reviewed-on: https://boringssl-review.googlesource.com/13054
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-01-04 01:46:32 +00:00
David Benjamin 2214f4e422 Remove call to SSL_CTX_set_tls_channel_id_enabled in bssl_shim.
Channel ID is already enabled on the SSL. This dates to
49c7af1c42 which converted an instance of
tlsext_channel_id_enabled_new to it, but tlsext_channel_id_enabled_new
meant "if Channel ID is enabled, use the new one", not "enable Channel
ID".

Thanks to Eric Rescorla for catching this.

Change-Id: I2d5a82b930ffcbe5527a62a9aa5605ebb71a6b9f
Reviewed-on: https://boringssl-review.googlesource.com/13042
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-01-04 01:46:10 +00:00
David Benjamin 14e18ca257 Fix AES-GCM-SIV on large inputs.
This was noticed by observing we had one line of missing test coverage
in polyval.c. CRYPTO_POLYVAL_update_blocks acts 32 blocks at a time and
all existing test vectors are smaller than that.

Test vector obtained by just picking random values and seeing what our
existing implementation did if I modified CRYPTO_POLYVAL_update_blocks
to consume many more blocks at a time. Then I fixed the bug and ensured
the answer was still the same.

Change-Id: Ib7002dbc10952229ff42a17132c30d0e290d4be5
Reviewed-on: https://boringssl-review.googlesource.com/13041
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-01-04 01:45:31 +00:00
David Benjamin 55696cecde Remove lh_new's default hash and comparator.
This is a memory error for anything other than LHASH_OF(char), which
does not exist.

No code outside the library creates (or even queries) an LHASH, so we
can change this module freely.

Change-Id: Ifbc7a1c69a859e07650fcfaa067bdfc68d83fbbc
Reviewed-on: https://boringssl-review.googlesource.com/12978
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-01-04 01:44:10 +00:00
David Benjamin c42a771d7d Test LHASH contents with lh_doall_arg.
Use it to compare the contents of lh and dummy_lh are identical. Leave a
TODO for testing other LHASH cases.

Change-Id: Ifbaf17c196070fdff1530ba0e284030527855f5d
Reviewed-on: https://boringssl-review.googlesource.com/12977
Reviewed-by: Adam Langley <agl@google.com>
2017-01-04 01:41:55 +00:00
David Benjamin a17eb5601d Convert hkdf_test to C++.
Change-Id: I0e8a24367cd33fa4aed2ca15bd369b8697f538e6
Reviewed-on: https://boringssl-review.googlesource.com/12974
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-01-04 01:40:44 +00:00
David Benjamin d17d1dae84 Convert dsa_test to C++.
Change-Id: Ib26050e1e8decdcd2744fa9ea6130f3265fb140b
Reviewed-on: https://boringssl-review.googlesource.com/12973
Reviewed-by: Adam Langley <agl@google.com>
2017-01-04 01:40:08 +00:00
David Benjamin ca0642287d Rewrite lhash_test in C++.
Use a std::map as the dummy lhash and use unique_ptr. This also improves
the test to check on pointer equality; we wish to ensure the lhash
stores the particular pointer value we asked for.

dummy_lh now also owns the pointers. It makes things simpler and since
LHASH doesn't free things, we weren't getting anything out of testing
that.

Change-Id: I97159175ca79a5874586650f272a7846100395e1
Reviewed-on: https://boringssl-review.googlesource.com/12976
Reviewed-by: Adam Langley <agl@google.com>
2017-01-04 01:38:45 +00:00
David Benjamin c96a888194 Convert constant_time_test and refcount_test to C++.
No source changes, just a rename.

Change-Id: Iaef406d2a04dc8c68c94eb2a98eec6378eaeab66
Reviewed-on: https://boringssl-review.googlesource.com/12975
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2017-01-04 01:36:49 +00:00
David Benjamin 650aa1c80a Clean up certificate auto-chaining.
Rather than doing it right before outputing, treat this as a part of the
pipeline to finalize the certificate chain, and run it right after
cert_cb to modify the certificate configuration itself. This means
nothing else in the stack needs to worry about this case existing.

It also makes it easy to support in both TLS 1.2 and TLS 1.3.

Change-Id: I6a088297a54449f1f5f5bb8b5385caa4e8665eb6
Reviewed-on: https://boringssl-review.googlesource.com/12966
Reviewed-by: Adam Langley <agl@google.com>
2017-01-04 01:36:26 +00:00
Raullen Chai d31148b175 update required cmake version to 2.8.10
Change-Id: Ibba0271efa86e1b1af97f2a08b73677dfd236b7a
Reviewed-on: https://boringssl-review.googlesource.com/12986
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
2017-01-03 14:27:21 +00:00
Rob Sloan 2ee1edfb7e Add BN_get_u64 so that Android doesn't have to reach into the BIGNUM structs
BUG=97

Change-Id: I4799cc99511e73af44def1d4daa36a8b4699f62d
Reviewed-on: https://boringssl-review.googlesource.com/12904
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>
2017-01-03 14:23:09 +00:00
David Benjamin d035ab3bba Add a GCOV option to CMakeLists.txt.
Get us a little closer to productionizing the coverage generation, which
will require taking all the logic out of the coverage script.

Change-Id: If410cc198a888ee87a84b1c2d532322682d3c44e
Reviewed-on: https://boringssl-review.googlesource.com/13043
Reviewed-by: Steven Valdez <svaldez@google.com>
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>
2017-01-03 13:17:57 +00:00
David Benjamin f650c71ac0 Use SSL_CTX_up_ref to up-ref an SSL_CTX.
We have this function now. Probably good to use it.

Change-Id: I00fe1f4cf5c8cb6f61a8f6600cac4667e95ad7f3
Reviewed-on: https://boringssl-review.googlesource.com/13040
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>
2017-01-03 13:15:30 +00:00
David Benjamin a81967b47c Add tests for the point format extension.
Upstream accidentally started rejecting server-sent point formats in
https://github.com/openssl/openssl/issues/2133. Our own test coverage
here is also lacking, so flesh it out.

Change-Id: I99059558bd28d3a540c9687649d6db7e16579d29
Reviewed-on: https://boringssl-review.googlesource.com/12979
Reviewed-by: Steven Valdez <svaldez@google.com>
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>
2016-12-22 15:33:40 +00:00
David Benjamin 235944126f Refresh fuzzer corpus.
This picks up the short header stuff and any changes made in the
meantime.

Change-Id: Ia2ea680632f3f6c6c759a8f0606a9394ae85c92d
Reviewed-on: https://boringssl-review.googlesource.com/12972
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-12-22 03:19:35 +00:00
David Benjamin 4c592d8f33 Enable short header negotiation in fuzzers.
Change-Id: Ib777dcc80c7acd6dc1eda1c211b91e5428b83df1
Reviewed-on: https://boringssl-review.googlesource.com/12971
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-12-22 03:19:23 +00:00
David Benjamin 9c70b89d0b Update fuzzer mode suppressions.
Change-Id: Ie4c566c29c20faac7a9a5e04c88503fc2e1ff4db
Reviewed-on: https://boringssl-review.googlesource.com/12970
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-12-22 03:18:19 +00:00
David Benjamin 3e3495130c Fix fuzzer mode build.
Change-Id: If565a5fdfa0f314422aa26c2e8f869965ca08c1b
Reviewed-on: https://boringssl-review.googlesource.com/12969
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-12-22 03:17:59 +00:00
David Benjamin 1444c3ace0 Add tests for auto-chaining.
Alas, wpa_supplicant relies on the auto-chaining feature, so we can't
easily remove it. Write tests for it to ensure it stays working.

These test currently do not work for TLS 1.3 because the feature is
broken in 1.3. A follow-up change will fix this.

BUG=70

Change-Id: I2c04f55b712d66f5af1556254a5b017ebc3244f7
Reviewed-on: https://boringssl-review.googlesource.com/12965
Reviewed-by: Adam Langley <agl@google.com>
2016-12-21 23:10:07 +00:00
David Benjamin c7df7967fa Don't chain to next_bio for buffer BIO BIO_[w]pending.
Chaining doesn't make much sense. This means we have a discontinuity
when buffer BIOs are empty. For a general filter BIO, this isn't even
meaningful. E.g., the base64 BIO's next_bio doesn't use the same units

(There's one consumer which does call BIO_pending on a base64 BIO, hits
this case, and is only working on accident, I've left it alone for this
CL until we can fix that consumer.)

The DTLS code, notably, assumes BIO_wpending to only report what's in
the buffer BIO. Ideally we'd get rid of the buffer BIO (I'll work on
this next), but, in the meantime, get the sizing right. The immediate
motivation is ssl_test using a BIO pair for DTLS doesn't work.  We've
just been lucky none of the tests have been near the MTU.

The buffer BIO is actually unused outside of the SSL stack, so this
shouldn't break external consumers. But for the base64 BIO consumer
mentioned above, I see nothing else which relies on this BIO_[w]pending
chaining.

Change-Id: I6764df8ede0f89fe73c774a8f7c9ae4c054d4184
Reviewed-on: https://boringssl-review.googlesource.com/12964
Reviewed-by: Adam Langley <agl@google.com>
2016-12-21 23:08:22 +00:00
David Benjamin 6cc903880d Reimplement objects.pl in Go.
The perl script is a little nuts. obj_dat.pl actually parses the header
file that objects.pl emits to figure out what all the objects are.
Replace it all with a single Go script.

BUG=16

Change-Id: Ib1492e22dbe4cf9cf84db7648612b156bcec8e63
Reviewed-on: https://boringssl-review.googlesource.com/12963
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-12-21 22:14:13 +00:00
David Benjamin 6f600d6bae Add experimental TLS 1.3 short record header extension.
This extension will be used to test whether
https://github.com/tlswg/tls13-spec/pull/762 is deployable against
middleboxes. For simplicity, it is mutually exclusive with 0-RTT. If
client and server agree on the extension, TLS 1.3 records will use the
format in the PR rather than what is in draft 18.

BUG=119

Change-Id: I1372ddf7b328ddf73d496df54ac03a95ede961e1
Reviewed-on: https://boringssl-review.googlesource.com/12684
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>
2016-12-21 22:06:44 +00:00
David Benjamin ec6b530683 Fix comment on OPENSSL_memcmp, etc.
I thought I'd rewritten this, but apparently didn't. The old version
dated to a prior iteration which used macros.

Change-Id: Idefbdb2c11700a44dd5b0733b98efec102b10dd2
Reviewed-on: https://boringssl-review.googlesource.com/12968
Reviewed-by: Adam Langley <agl@google.com>
2016-12-21 21:47:24 +00:00
David Benjamin 17cf2cb1d2 Work around language and compiler bug in memcpy, etc.
Most C standard library functions are undefined if passed NULL, even
when the corresponding length is zero. This gives them (and, in turn,
all functions which call them) surprising behavior on empty arrays.
Some compilers will miscompile code due to this rule. See also
https://www.imperialviolet.org/2016/06/26/nonnull.html

Add OPENSSL_memcpy, etc., wrappers which avoid this problem.

BUG=23

Change-Id: I95f42b23e92945af0e681264fffaf578e7f8465e
Reviewed-on: https://boringssl-review.googlesource.com/12928
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-12-21 20:34:47 +00:00
David Benjamin 56cadc3daf Assert on the alert sent on FALLBACK_SCSV.
We were only asserting on the shim-side error code.

Change-Id: Idc08c253a7723a2a7fd489da761a56c72f7a3b96
Reviewed-on: https://boringssl-review.googlesource.com/12923
Reviewed-by: Adam Langley <agl@google.com>
2016-12-21 20:12:19 +00:00
David Benjamin 720ff53d07 Trim and simplify obj_xref.c.
This avoids having more generated bits. The table is quite small,
especially so when we take out anything we don't implement. There's no
real need to do the binary search. (Exotic things like GOST, the legacy
NID_rsa and NID_dsa_2 spellings of RSA and DSA, and hash functions we
don't implement.)

Mostly this saves me from having to reimplement obj_xref.pl.
(obj_xref.pl processes nid.h, formerly obj_mac.h, so we can't just use
the existing one and still change nid.h.)

Change-Id: I90911277e691a8b04ea8930f3f314d517f314d29
Reviewed-on: https://boringssl-review.googlesource.com/12962
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-12-21 19:39:41 +00:00
David Benjamin 48e2be247a Include the type in empty vector literals.
Chromium on Linux builds against libstdc++'s debug mode which makes
clang unhappy due to:

../crypto/bytestring/bytestring_test.cc:910:7: error: chosen constructor
is explicit in copy-initialization
      {},
      ^~
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/debug/vector:79:7:
note: constructor declared here
      vector(const _Allocator& __a = _Allocator())
      ^

I believe this was fixed here, but it's too recent:
https://github.com/gcc-mirror/gcc/commit/36f540c70ba27e441bd07111a2107b8993382905

Change-Id: I2942d153e1278785c3b81294bc99b86f297cf719
Reviewed-on: https://boringssl-review.googlesource.com/12967
Reviewed-by: Adam Langley <agl@google.com>
2016-12-21 18:11:25 +00:00
Adam Langley 28feb92a5b Add |X509_STORE_set0_additional_untrusted|.
X509_STORE_set0_additional_untrusted allows one to set a stack of
additional untrusted certificates that can be used during chain
building. These will be merged with the untrusted certificates set on
the |X509_STORE_CTX|.

Change-Id: I3f011fb0854e16a883a798356af0a24cbc5a9d68
Reviewed-on: https://boringssl-review.googlesource.com/12980
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-12-21 00:20:43 +00:00
David Benjamin b442dee388 Rename FallbackSCSV-MatchVersion.
It should probably have a TLS 1.3 in the name to be clear that's what
it's testing.

Change-Id: I50b5f503a8038715114136179bde83e7da064e9b
Reviewed-on: https://boringssl-review.googlesource.com/12961
Reviewed-by: Steven Valdez <svaldez@google.com>
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>
2016-12-20 20:47:30 +00:00
David Benjamin 458334a159 Test name-based version APIs are reported as expected.
Notably, Conscrypt uses SSL_SESSION_get_version, so we should have tests
for it.

Change-Id: I670f1b1b9951f840f27cb62dd36ef4f05042c974
Reviewed-on: https://boringssl-review.googlesource.com/12881
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
2016-12-19 21:50:06 +00:00
Adam Langley e6620af176 Remove rsaz-x86_64.pl from CMake inputs.
593b6a44 removed this file but the perlasm line remained in the
CMakeLists.txt for crypto/bn.

Change-Id: I13098b7920c78a3c65e490f57916fc86a94256e3
2016-12-19 08:39:37 -08:00
Brian Smith 9f05de4ebb Remove the non-no_branch branch of BN_div.
Simplify the code, and in particular make |BN_div|, |BN_mod|, and
|BN_nnmod| insensitive to |BN_FLG_CONSTTIME|. This improves the
effectiveness of testing by reducing the number of branches that are
likely to go untested or less tested.

There is no performance-sensitive code that uses BN_div but doesn't
already use BN_FLG_CONSTTIME except RSA signature verification and
EC_GROUP creation. RSA signature verification, ECDH, and ECDSA
performance aren't significantly different with this change.

Change-Id: Ie34c4ce925b939150529400cc60e1f414c7676cd
Reviewed-on: https://boringssl-review.googlesource.com/9105
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
2016-12-17 19:11:19 +00:00
Steven Valdez 4cb8494d25 Splitting handshake traffic derivation from key change.
This is in preparation for implementing 0-RTT where, like
with client_traffic_secret_0, client_handshake_secret must
be derived slightly earlier than it is used. (The secret is
derived at ServerHello, but used at server Finished.)

Change-Id: I6a186b84829800704a62fda412992ac730422110
Reviewed-on: https://boringssl-review.googlesource.com/12920
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>
2016-12-16 20:29:23 +00:00
Adam Langley 1bcd10c557 Add CMake support for ASAN and MSAN.
This only works with Clang, and MSAN seems to have a false-positive for
me in libstdc++, but it can be helpful to test with these

Change-Id: I068edabcda69c9239ee4f0247f5d8f873dea77bb
Reviewed-on: https://boringssl-review.googlesource.com/12940
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>
2016-12-16 19:27:49 +00:00
David Benjamin 65fb425811 Remove version-specific cipher lists.
There are no longer any consumers of these APIs.

These were useful back when the CBC vs. RC4 tradeoff varied by version
and it was worth carefully tuning this cutoff. Nowadays RC4 is
completely gone and there's no use in configuring these anymore.

To avoid invalidating the existing ssl_ctx_api corpus and requiring it
regenerated, I've left the entries in there. It's probably reasonable
for new API fuzzers to reuse those slots.

Change-Id: I02bf950e3828062341e4e45c8871a44597ae93d5
Reviewed-on: https://boringssl-review.googlesource.com/12880
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-12-16 19:11:02 +00:00
Adam Langley 2d58482004 Call __msan_unpoison on the output of getrandom.
MSAN doesn't hook |syscall| and thus doesn't know that the kernel has
filled the output buffer when |getrandom| is called.

This change tells MSAN to trust that the memory that |getrandom| writes
to has been initialised. This should avoid false-positives when code
operates on |RAND_bytes| output.

Change-Id: I0a74ebb21bcd1de1f28eda69558ee27f82db807a
Reviewed-on: https://boringssl-review.googlesource.com/12903
Reviewed-by: Adam Langley <alangley@gmail.com>
Commit-Queue: Adam Langley <alangley@gmail.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-12-16 18:59:27 +00:00
Adam Langley 39ae144759 Revert "Revert "crypto/rand: Fix a crash bug in RAND_enable_fork_unsafe_buffering." and "Enable getrandom for entropy gathering.""
This reverts commit 97db926cf7,
effectively unreverting the two changes that it contained. A subsequent
change will fix this code for MSAN.

Change-Id: I54a82b667b7a4208c7a960aa28b01cb246bc78c7
Reviewed-on: https://boringssl-review.googlesource.com/12902
Commit-Queue: Adam Langley <alangley@gmail.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-12-16 18:21:41 +00:00
Brian Smith 16bfff7169 Calculate Montgomery RR without division.
Get one step closer to removing the dependency on |BN_div| from most
programs. Also get one step closer to a constant-time implementation of
|BN_MONT_CTX_set|; we now "just" need to create a constant-time variant
of |BN_mod_lshift1_quick|.

Note that this version might actually increase the side channel signal,
since the variance in timing in |BN_div| is probably less than the variance
from the many conditional reductions in the new method.

On one Windows x64 machine, the speed of RSA verification using the new
version is not too different from the speed of the old code. However,
|BN_div| is generally slow on Windows x64 so I expect this isn't faster
on all platforms. Regardless, we generally consider ECDSA/EdDSA
signature verification performance to be adaquate and RSA signature
verification is much, much faster even with this change.

For RSA signing the performance is not a significant factor since
performance-sensitive applications will cache the |RSA| structure and
the |RSA| structure will cache the Montgomery contexts.

Change-Id: Ib14f1a35c99b8da435e190342657f6a839381a1a
Reviewed-on: https://boringssl-review.googlesource.com/10520
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-12-16 17:41:01 +00:00
Brian Smith febf77190f Verify consistency of RSA keys after generation & parsing.
Call |RSA_check_key| after parsing an RSA private key in order to
verify that the key is consistent. This is consistent with ECC key
parsing, which does a similar key check.

Call |RSA_check_key| after key generation mostly as a way of
double-checking the key generation was done correctly. A similar check
was not added to |EC_KEY_generate| because |EC_KEY_generate| is used
for generating ephemeral ECDH keys, and the check would be too
expensive for that use.

Change-Id: I5759d0d101c00711bbc30f81a3759f8bff01427c
Reviewed-on: https://boringssl-review.googlesource.com/7522
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-12-16 17:37:03 +00:00
David Benjamin a36255cd4d Fix RSA-PSS documentation.
-2 is really weird. On sign, it's maximal length. On verify, it actually
accepts all lengths. This sounds somewhat questionable to me, but just
document the state of the world for now. Also add a recommendation to
use -1 (match digest length) to align with TLS 1.3, tokbind, and QUIC
Crypto. Hopefully the first two is sufficient that the IETF will forever
use this option and stop the proliferation of RSA-PSS parameters.

Change-Id: Ie0ad7ad451089df0e18d6413d1b21c5aaad9d0f2
Reviewed-on: https://boringssl-review.googlesource.com/12823
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-12-16 17:17:38 +00:00
David Benjamin 4f57074bfa Check input length to pkey_rsa_verify and add initial tests.
This is imported from upstream's
71bbc79b7d3b1195a7a7dd5f547d52ddce32d6f0 and test vectors taken
initially from 2d7bbd6c9fb6865e0df480602c3612652189e182 (with a handful
more added).

The tests are a little odd because OpenSSL supports this "salt length
recovery" mode and they go through that codepath for all verifications.

Change-Id: I220104fe87e2a1a1458c99656f9791d8abfbbb98
Reviewed-on: https://boringssl-review.googlesource.com/12822
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-12-16 17:16:57 +00:00
Adam Langley 97db926cf7 Revert "crypto/rand: Fix a crash bug in RAND_enable_fork_unsafe_buffering." and "Enable getrandom for entropy gathering."
This reverts commits 36ca21415a and
7b668a873e. We believe that we need to
update ASAN to be aware of getrandom before we can use it. Otherwise it
believes that the memory with the entropy from this syscall is
uninitialised.

Change-Id: I1ea1c4d3038b3b2cd080be23d7d8b60fc0c83df2
Reviewed-on: https://boringssl-review.googlesource.com/12901
Reviewed-by: Adam Langley <alangley@gmail.com>
Commit-Queue: Adam Langley <alangley@gmail.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-12-15 20:17:27 +00:00
Adam Langley b479c5df34 Revert "Include some C versions of the x86-64 P-256 code."
This reverts commit ba84265c48.

No semantic change; the reverted code was commented out.
2016-12-15 10:35:12 -08:00
Adam Langley ba84265c48 Include some C versions of the x86-64 P-256 code.
This change includes C versions of some of the functions from the x86-64
P-256 code that are currently implemented in assembly. These functions
were part of the original submission by Intel and are covered by the ISC
license.

No semantic change; code is commented out.

Change-Id: Ifdd2fac6caeb73d375d6b125fac98f3945003b32
Reviewed-on: https://boringssl-review.googlesource.com/12861
Reviewed-by: Adam Langley <agl@google.com>
2016-12-15 18:34:54 +00:00
Steven Valdez 87c0bb2939 Adding new options for bssl tool.
* -loop on the server allows it to keep accepting connections.
* -resume on the client waits to receive a session from the server
    and starts a new connection using the previous session.

Change-Id: I27a413c7c1d64edbca94aecc6f112d8d15afbce2
Reviewed-on: https://boringssl-review.googlesource.com/12630
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>
2016-12-15 16:49:08 +00:00
David Benjamin 76bb1411ac Remove the BORINGSSL_ANDROID_SYSTEM P-521 special-case.
This dates to
https://android.googlesource.com/platform/external/boringssl/+/62d05888d1cf178d900b54e7e035928abea512b1
which intended to be removed in a later Android release once X25519 was
added. That has since happened.

This intentionally leaves the P-521 hooked up for now. Detaching it
completely is a more aggressive change (since it's slightly tied up with
SHA-512) that should wait until removing ECDSA+SHA512 has stuck in Chrome.

Change-Id: I04553c3eddf33a13b6e3e9a6e7ac4c4725676cb0
Reviewed-on: https://boringssl-review.googlesource.com/10923
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>
2016-12-15 15:47:39 +00:00
David Benjamin 593b6a44fe Remove RSAZ-512.
This gives a 15-16% perf boost for 1024-bit RSA keys, but 1024-bit RSA
keys are no longer important enough for this code to carry its weight.

Change-Id: Ia9f0e7fec512c28e90754ababade394c1f11984d
Reviewed-on: https://boringssl-review.googlesource.com/12841
Commit-Queue: David Benjamin <davidben@google.com>
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-12-14 22:12:50 +00:00
David Benjamin d9d36b2771 Add RSAZ-512 versions of RSAZ-1024 test vectors.
These are regression tests for
https://boringssl-review.googlesource.com/c/12525/ that target the
RSAZ-512 code rather than the disabled RSAZ-1024 code.

These were created by extracting p and dmp1 from
ssl/test/rsa_1024_key.pem and creating similar test vectors as with the
AVX2 test vectors. They currently fail, but pass if the RSAZ-512 code is
disabled.

Change-Id: I99dd3f385941ddbb1cc64b5351f4411081b42dd7
Reviewed-on: https://boringssl-review.googlesource.com/12840
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-12-14 22:09:16 +00:00
Brian Smith 61a7ef4f2b Reduce the input base |a| in BN_mod_exp_mont_consttime for RSAZ.
Note that this adds new non-constant-time code into the RSAZ-based
code path.

Change-Id: Ibca3bc523ede131b55c70ac5066c0014df1f5a70
Reviewed-on: https://boringssl-review.googlesource.com/12525
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>
2016-12-14 22:05:12 +00:00
Martin Kreichgauer 36ca21415a crypto/rand: Fix a crash bug in RAND_enable_fork_unsafe_buffering.
Change-Id: Ifff59b1518f513c1be70e4e0d4ed3430741d0a5e
Reviewed-on: https://boringssl-review.googlesource.com/12860
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-12-14 21:59:18 +00:00
Brian Smith 4cc1ccd3fc Add minimal tests for 1024-bit RSAZ BN_mod_exp_mont_consttime.
The input base, |a|, isn't reduced mod |m| in the RSAZ case so
incorrect results are given for out-of-range |a| when the RSAZ
implementation is used. On the other hand, the RSAZ implementation is
more correct as far as constant-time operation w.r.t. |a| is concerned.

Change-Id: Iec4d0195cc303ce442ce687a4b7ea42fb19cfd06
Reviewed-on: https://boringssl-review.googlesource.com/12524
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>
2016-12-14 20:41:19 +00:00
Adam Langley 629db8cd0c Add |SSL_get_peer_full_cert_chain|.
This function always returns the full chain and will hopefully eliminate
the need for some code in Conscrypt.

Change-Id: Ib662005322c40824edf09d100a784ff00492896a
Reviewed-on: https://boringssl-review.googlesource.com/12780
Reviewed-by: Adam Langley <agl@google.com>
2016-12-14 18:01:10 +00:00
Adam Langley a4b91981f8 Make TLS 1.3 check ECDSA KeyUsage and add test.
Change-Id: Ibb5c5f6b945f72585f58c457158a386dfb4dae98
Reviewed-on: https://boringssl-review.googlesource.com/12710
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-12-14 17:56:55 +00:00
Adam Langley 0567220b8b Don't use X.509 functions to check ECDSA keyUsage.
This removes another dependency on the crypto/x509 code.

Change-Id: Ia72da4d47192954c2b9a32cf4bcfd7498213c0c7
Reviewed-on: https://boringssl-review.googlesource.com/12709
Reviewed-by: Adam Langley <agl@google.com>
2016-12-14 17:51:03 +00:00
Adam Langley 0c294254b5 Don't use |X509_get_pubkey| in TLS 1.3 code either.
Change-Id: I7050c74ac38503f450760a857442e6fc0863d5df
Reviewed-on: https://boringssl-review.googlesource.com/12708
Reviewed-by: Adam Langley <agl@google.com>
2016-12-14 17:49:10 +00:00
David Benjamin 703aa16003 Import a test vector from upstream.
The original bug only affected their big-endian code which we don't
have, but import the test vector anyway. Imported from upstream's
b47f116b1e02d20b1f8a7488be5a04f7cf5bc712.

Change-Id: I349e41d87006533da0e18c948f9cc7dd15f42a44
Reviewed-on: https://boringssl-review.googlesource.com/12820
Reviewed-by: Steven Valdez <svaldez@google.com>
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>
2016-12-14 17:48:36 +00:00
David Benjamin fa99197b9d perlasm/x86_64-xlate.pl: refine sign extension in ea package.
$1<<32>>32 worked fine with either 32- or 64-bit perl for a good while,
relying on quirk that [pure] 32-bit perl performed it as $1<<0>>0.  But
this apparently changed in some version past minimally required 5.10,
and operation result became 0. Yet, it went unnoticed for another while,
because most perl package providers configure their packages with
-Duse64bitint option.

(Imported from upstream's 82e089308bd9a7794a45f0fa3973d7659420fbd8.)

Change-Id: Ie9708bb521c8d7d01afd2e064576f46be2a811a5
Reviewed-on: https://boringssl-review.googlesource.com/12821
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
2016-12-14 17:36:29 +00:00
David Benjamin fcd714d52b Add CBS functions for working with BIT STRINGs.
Querying a bit in a BIT STRING is a little finicky. Add some functions
to help with this.

Change-Id: I813b9b6f2d952d61d8717b47bca1344f0ad4b7d1
Reviewed-on: https://boringssl-review.googlesource.com/12800
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-12-14 17:25:30 +00:00
David Benjamin aa01204175 Move per-cipher-suite tests into a separate function.
The loop is getting a little deeply nested and hard to read.

Change-Id: I3a99fba54c2f352850b83aef91ab72d5d9aabfb8
Reviewed-on: https://boringssl-review.googlesource.com/12685
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>
2016-12-14 01:51:37 +00:00
David Benjamin db5bd72152 Move key_share extension check with ECDHE code.
Also fix the error code. It's a missing extension, not an unexpected
one.

Change-Id: I48e48c37e27173f6d7ac5e993779948ead3706f2
Reviewed-on: https://boringssl-review.googlesource.com/12683
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>
2016-12-14 01:46:34 +00:00
David Benjamin f1050fd79a Preserve the peer signature algorithm across resumes.
So we can report it cleanly out of DevTools, it should behave like
SSL_get_curve_id and be reported on resumption too.

BUG=chromium:658905

Change-Id: I0402e540a1e722e09eaebadf7fb4785d8880c389
Reviewed-on: https://boringssl-review.googlesource.com/12694
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>
2016-12-14 01:12:40 +00:00
David Benjamin 8a55ce4954 Test SSL_get_curve_id behavior on resume.
Also test that TLS 1.3 can be resumed at a different curve.

Change-Id: Ic58e03ad858c861958b7c934813c3e448fb2829c
Reviewed-on: https://boringssl-review.googlesource.com/12692
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>
2016-12-14 01:08:02 +00:00
David Benjamin 4882a6c50b Replace key_exchange_info with group_id.
The only accessor for this field is the group/curve ID. Switch to only
storing that so no cipher checks are needed to interpret it. Instead,
ignore older values at parse time.

Change-Id: Id0946d4ac9e7482c69e64cc368a9d0cddf328bd3
Reviewed-on: https://boringssl-review.googlesource.com/12693
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>
2016-12-14 01:07:20 +00:00
David Benjamin 54881224e8 Remove SSL_get_dhe_group_size.
Nothing calls this anymore. DHE is nearly gone. This unblocks us from
making key_exchange_info only apply to the curve.

Change-Id: I3099e7222a62441df6e01411767d48166a0729b1
Reviewed-on: https://boringssl-review.googlesource.com/12691
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>
2016-12-14 01:06:22 +00:00
Adam Langley d515722d22 Don't depend on the X509 code for getting public keys.
This change removes the use of |X509_get_pubkey| from the TLS <= 1.2
code. That function is replaced with a shallow parse of the certificate
to extract the public key instead.

Change-Id: I8938c6c5a01b32038c6b6fa58eb065e5b44ca6d2
Reviewed-on: https://boringssl-review.googlesource.com/12707
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-12-13 21:27:31 +00:00
Adam Langley d519bf6be0 Add |SSL_CTX_set0_buffer_pool|.
This currently only works for certificates parsed from the network, but
if making several connections that share certificates, some KB of memory
might be saved.

BUG=chromium:671420

Change-Id: I1c7a71d84e1976138641f71830aafff87f795f9d
Reviewed-on: https://boringssl-review.googlesource.com/12706
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>
2016-12-13 18:54:22 +00:00
Adam Langley 68e7124ddf Hold certificates in an SSL_SESSION as CRYPTO_BUFFERSs as well.
This change adds a STACK_OF(CRYPTO_BUFFER) to an SSL_SESSION which
contains the raw form of the received certificates. The X509-based
members still exist, but their |enc| buffer will alias the
CRYPTO_BUFFERs.

(This is a second attempt at
https://boringssl-review.googlesource.com/#/c/12163/.)

BUG=chromium:671420

Change-Id: I508a8a46cab89a5a3fcc0c1224185d63e3d59cb8
Reviewed-on: https://boringssl-review.googlesource.com/12705
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-12-13 17:28:25 +00:00
Adam Langley 364f7a6d21 Push the difference in chain semantics to the edge.
OpenSSL includes a leaf certificate in a certificate chain when it's a
client, but doesn't when it's a server. This is also reflected in the
serialisation of sessions.

This change makes the internal semantics consistent: the leaf is always
included in the chain in memory, and never duplicated when serialised.
To maintain the same API, SSL_get_peer_cert_chain will construct a copy
of the chain without the leaf if needed.

Since the serialised format of a client session has changed, an
|is_server| boolean is added to the ASN.1 that defaults to true. Thus
any old client sessions will be parsed as server sessions and (silently)
discarded by a client.

Change-Id: Ibcf72bc8a130cedb423bc0fd3417868e0af3ca3e
Reviewed-on: https://boringssl-review.googlesource.com/12704
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-12-13 17:18:53 +00:00
David Benjamin cb0c29ff75 Move state and next_state to SSL_HANDSHAKE.
state is now initialized to SSL_ST_INIT in SSL_HANDSHAKE. If there is no
handshake present, we report SSL_ST_OK. This saves 8 bytes of
per-connection post-handshake memory.

Change-Id: Idb3f7031045caed005bd7712bc8c4b42c81a1d04
Reviewed-on: https://boringssl-review.googlesource.com/12697
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>
2016-12-12 22:09:01 +00:00
David Benjamin 2644a13d71 Set up the SSL_HANDSHAKE object earlier.
This is to free up moving ssl->state into SSL_HANDSHAKE. ssl->state
serves two purposes right now. First, it is the state tracking for
SSL_HANDSHAKE. Second, it lets the system know there is a handshake
waiting to complete.

Instead, arrange things so that, if there is a handshake waiting to
complete, hs is not NULL. That means we need to initialize it when
creating a new connection and when discovering a renego.

Note this means we cannot make initializing an SSL_HANDSHAKE depend on
client vs. server.

Change-Id: I585a8d7e700c4ffe4d372248d34c44106ad7e7a0
Reviewed-on: https://boringssl-review.googlesource.com/12696
Reviewed-by: David Benjamin <davidben@google.com>
2016-12-12 21:59:06 +00:00
David Benjamin 5edfc8cc17 Emulate the client_cert_cb with cert_cb.
This avoids needing a extra state around client certificates to avoid
calling the callbacks twice. This does, however, come with a behavior
change: configuring both callbacks won't work. No consumer does this.

(Except bssl_shim which needed slight tweaks.)

Change-Id: Ia5426ed2620e40eecdcf352216c4a46764e31a9a
Reviewed-on: https://boringssl-review.googlesource.com/12690
Reviewed-by: Adam Langley <agl@google.com>
2016-12-12 21:58:24 +00:00
David Benjamin 5888946777 Remove SSL_CTX_get_client_cert_cb.
This is never used. Removing it allows us to implement the old callback
using the new one.

Change-Id: I4be70cc16e609ce79b51836c19fec565c67ff3d6
Reviewed-on: https://boringssl-review.googlesource.com/12689
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-12-12 21:43:32 +00:00
David Benjamin 888d5ccde3 Remove unused SSL_want_* macros.
Callers doing more interesting things than read and write tend to use
SSL_get_error. SSL_want_{read,write} are still used, however.

Change-Id: I21e83cc8046742857051f755868d86deffd23d81
Reviewed-on: https://boringssl-review.googlesource.com/12688
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-12-12 21:43:06 +00:00
David Benjamin 287fc4ff7b Don't use SSL_want_* macros internally.
Reduce the amount of boilerplate needed to add more of these. Also tidy
things up a little.

Change-Id: I90ea7f70dba5a2b38a1fb716faff97eb4f6afafc
Reviewed-on: https://boringssl-review.googlesource.com/12687
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-12-12 21:42:44 +00:00
David Benjamin 5b1f07e9e7 Remove unused BIO_RR_* values.
One of them is used in the new minimal SSL BIO, but cURL doesn't consume
it, so let's just leave it out. A consumer using asynchronous
certificate lookup is unlikely to be doing anything with SSL BIOs.

Change-Id: I10e7bfd643d3a531d42a96a8d675611d13722bd2
Reviewed-on: https://boringssl-review.googlesource.com/12686
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-12-12 21:41:41 +00:00
David Benjamin 2ad3c989e8 Merge in upstream's certificate corpus.
This was done by running:

  ./fuzz/cert -merge=1 ../fuzz/cert_corpus ~/openssl/fuzz/corpora/x509

I bumped the max_len while doing so because some of those are rather
large.

Change-Id: Ic2caa09d5ff9ab05b46363940a91a03f270cbad8
Reviewed-on: https://boringssl-review.googlesource.com/12682
Reviewed-by: Adam Langley <agl@google.com>
2016-12-12 21:41:00 +00:00
David Benjamin 9434b6bb5b Fix BN_kronecker on unreachable BN_rshift error.
The error value is -2, but at this point ret has already been set to
some running answer and must be reset to -2.

(This is unreachable. BN_rshift only fails on caller or malloc error,
and it doesn't need to malloc when running in-place.)

Change-Id: I33930da84b00d1906bdee9d09b9504ea8121fac4
Reviewed-on: https://boringssl-review.googlesource.com/12681
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-12-12 21:40:20 +00:00
David Benjamin edb4c796e0 Add yet another way to spell 32.
For folks who prefer the named length constants, the current ones aren't
sufficient because the shared key isn't the private key or a public
value.

Well, it does have the same type as a public value, but it looks silly
to write:

  uint8_t secret_key[X25519_PUBLIC_VALUE_LEN];

Change-Id: I391db8ee73e2b4305d0ddd22f6d99f6abbc6b45b
Reviewed-on: https://boringssl-review.googlesource.com/12680
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-12-12 21:39:34 +00:00
David Benjamin 3977f30317 Rename hs->state to hs->tls13_state.
This is to free up the hs->state name for the upper-level handshake
state.

Change-Id: I1183a329f698c56911f3879a91809edad5b5e94e
Reviewed-on: https://boringssl-review.googlesource.com/12695
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>
2016-12-12 21:15:28 +00:00
Alessandro Ghedini 1149ee1d38 tool: show if server sent OCSP staple
Change-Id: Ib9df4e8f797c9af3362354cc6716171fd65600de
Reviewed-on: https://boringssl-review.googlesource.com/12720
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>
2016-12-12 18:10:25 +00:00
Matthew Braithwaite f440e827f1 Remove New Hope key agreement.
Change-Id: Iaac633616a54ba1ed04c14e4778865c169a68621
Reviewed-on: https://boringssl-review.googlesource.com/12703
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>
2016-12-10 01:06:31 +00:00
Adam Langley c0fc7a1385 Revert "Add |SSL_CTX_set0_buffer_pool|." and "Hold certificates in an SSL_SESSION as CRYPTO_BUFFERSs as well."
This reverts commits 5a6e616961 and
e8509090cf. I'm going to unify how the
chains are kept in memory between client and server first otherwise the
mess just keeps growing.

Change-Id: I76df0d94c9053b2454821d22a3c97951b6419831
Reviewed-on: https://boringssl-review.googlesource.com/12701
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>
2016-12-09 23:31:12 +00:00
Matthew Braithwaite 651aaefb44 Remove CECPQ1 (experimental post-quantum key agreement).
Change-Id: Ie947ab176d10feb709c6e135d5241c6cf605b8e8
Reviewed-on: https://boringssl-review.googlesource.com/12700
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>
2016-12-09 19:16:56 +00:00
Adam Langley 5a6e616961 Add |SSL_CTX_set0_buffer_pool|.
This currently only works for certificates parsed from the network, but
if making several connections that share certificates, some KB of memory
might be saved.

Change-Id: I0ea4589d7a8b5c41df225ad7f282b6d1376a8db4
Reviewed-on: https://boringssl-review.googlesource.com/12164
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-12-09 18:22:06 +00:00
Adam Langley e8509090cf Hold certificates in an SSL_SESSION as CRYPTO_BUFFERSs as well.
This change adds a STACK_OF(CRYPTO_BUFFER) to an SSL_SESSION which
contains the raw form of the received certificates. The X509-based
members still exist, but their |enc| buffer will alias the
CRYPTO_BUFFERs.

The serialisation format of SSL_SESSIONs is also changed, in a backwards
compatible way. Previously, some sessions would duplicate the leaf
certificate in the certificate chain. These sessions can still be read,
but will be written in a way incompatible with older versions of the
code. This should be fine because the situation where multiple versions
exchange serialised sessions is at the server, and the server doesn't
duplicate the leaf certifiate in the chain anyway.

Change-Id: Id3b75d24f1745795315cb7f8089a4ee4263fa938
Reviewed-on: https://boringssl-review.googlesource.com/12163
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-12-09 18:12:40 +00:00
Adam Langley f5b30cc28c Add a simplified SSL BIO for curl.
A recent change to curl[1] added support for HTTPS proxies, which
involves running a TLS connection inside another TLS connection. This
was done by using SSL BIOs, which we removed from BoringSSL for being
crazy.

This change adds a stripped-down version of the SSL BIO to decrepit in
order to suport curl.

[1] https://github.com/curl/curl/commit/cb4e2be7c6d42ca0780f8e0a747cecf9ba45f151

Change-Id: I9cb8f2db5b28a5a70724f6f93544297c380ac124
Reviewed-on: https://boringssl-review.googlesource.com/12631
Reviewed-by: Adam Langley <agl@google.com>
2016-12-08 20:33:22 +00:00
Alessandro Ghedini 559f0644a5 Support setting per-connection OCSP staple
Right now the only way to set an OCSP response is SSL_CTX_set_ocsp_response
however this assumes that all the SSLs generated from a SSL_CTX share the
same OCSP response, which is wrong.

This is similar to the OpenSSL "function" SSL_get_tlsext_status_ocsp_resp,
the main difference being that this doesn't take ownership of the OCSP buffer.

In order to avoid memory duplication in case SSL_CTX has its own response,
a CRYPTO_BUFFER is used for both SSL_CTX and SSL.

Change-Id: I3a0697f82b805ac42a22be9b6bb596aa0b530025
Reviewed-on: https://boringssl-review.googlesource.com/12660
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>
2016-12-08 20:29:43 +00:00
David Benjamin 7c5728649a Remove SSL_set_reject_peer_renegotiations.
All callers were long since updated.

Change-Id: Ibdc9b186076dfbcbc3bd7dcc72610c8d5a522cfc
Reviewed-on: https://boringssl-review.googlesource.com/12624
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-12-08 17:23:10 +00:00
David Benjamin b79cc84635 Fix SSL_clear's interaction with session resumption.
Prior to 87eab4902d, due to some
confusions between configuration and connection state, SSL_clear had the
side effect of offering the previously established session on the new
connection.

wpa_supplicant relies on this behavior, so restore it for TLS 1.2 and
below and add a test. (This behavior is largely incompatible with TLS
1.3's post-handshake tickets, so it won't work in 1.3. It'll act as if
we configured an unresumable session instead.)

Change-Id: Iaee8c0afc1cb65c0ab7397435602732b901b1c2d
Reviewed-on: https://boringssl-review.googlesource.com/12632
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>
2016-12-08 16:57:57 +00:00
David Benjamin 30c4c30d4a Revise some integer sizes.
size_t at the public API, uint8_t on the SSL structs since everything
fits in there comfortably.

Change-Id: I837c3b21e04e03dfb957c1a3e6770300d0b49c0b
Reviewed-on: https://boringssl-review.googlesource.com/12638
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>
2016-12-08 16:48:44 +00:00
David Benjamin 813fc01ff1 Remove unreachable check.
It is impossible to have an SSL* without a corresponding method.

Change-Id: Icaf826a06aaaa2c7caf98b1e4a950f9c1d48e6bd
Reviewed-on: https://boringssl-review.googlesource.com/12621
Reviewed-by: Adam Langley <agl@google.com>
2016-12-08 16:40:15 +00:00
David Benjamin f04c2e9878 Move client_version into SSL_HANDSHAKE.
There is no need to retain it beyond this point.

Change-Id: Ib5722ab30fc013380198b1582d1240f0fe0aa770
Reviewed-on: https://boringssl-review.googlesource.com/12620
Reviewed-by: Adam Langley <agl@google.com>
2016-12-08 16:39:52 +00:00
David Benjamin a2bda9fb95 Make more functions static.
These too have no reason to be called across files.

Change-Id: Iee477e71f956c2fa0d8817bf2777cb3a81e1c853
Reviewed-on: https://boringssl-review.googlesource.com/12585
Reviewed-by: Adam Langley <agl@google.com>
2016-12-08 16:29:58 +00:00
David Benjamin 0be6fc4c98 Move a few more functions into *_method.c.
s3_lib.c is nearly gone. ssl_get_cipher_preferences will fall away once
we remove the version-specific cipher lists. ssl_get_algorithm_prf and
the PRF stuff in general needs some revising (it was the motivation for
all the SSL_HANDSHAKE business). I've left ssl3_new / ssl3_free alone
for now because we don't have a good separation between common TLS/DTLS
connection state and state internal to the TLS SSL_PROTOCOL_METHOD.
Leaving that alone for now as there's lower-hanging fruit.

Change-Id: Idf7989123a387938aa89b6a052161c9fff4cbfb3
Reviewed-on: https://boringssl-review.googlesource.com/12584
Reviewed-by: Adam Langley <agl@google.com>
2016-12-08 16:29:19 +00:00
Adam Langley c8006be227 Fix X509_parse_from_buffer when failing to parse.
d2i_X509 will free an existing |X509*| on parse failure. Thus
|X509_parse_from_buffer| would double-free the result on error.

Change-Id: If2bca2f1e1895bc426079f6ade4b82008707888d
Reviewed-on: https://boringssl-review.googlesource.com/12635
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-12-08 16:20:49 +00:00
David Benjamin 9d125dcdec Remove SSL_OP_DISABLE_NPN.
This was useful when we were transitioning NPN off in Chromium, but now
there are no callers remaining.

Change-Id: Ic619613d6d475eea6bc258c4a90148f129ea4a81
Reviewed-on: https://boringssl-review.googlesource.com/12637
Reviewed-by: Steven Valdez <svaldez@google.com>
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>
2016-12-08 16:05:02 +00:00
David Benjamin 82bbe5503d Add tests for BIO pairs.
Change-Id: I6514d68435ac4b7e2c638c7612b57bde5886bbba
Reviewed-on: https://boringssl-review.googlesource.com/12629
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>
2016-12-08 00:55:17 +00:00
David Benjamin aac1e2dd73 Remove the remaining bssl::Main wrappers.
We've taken to writing bssl::UniquePtr in full, so it's not buying
us much.

Change-Id: Ia2689366cbb17282c8063608dddcc675518ec0ca
Reviewed-on: https://boringssl-review.googlesource.com/12628
Reviewed-by: David Benjamin <davidben@google.com>
2016-12-08 00:54:17 +00:00
Adam Langley 4ba6e19640 Better pack ssl_handshake_st and ssl3_state_st.
This is a second attempt at
https://boringssl-review.googlesource.com/#/c/11460/.

Change-Id: Ief0eba1501d87168a2354560199722f036a3e529
Reviewed-on: https://boringssl-review.googlesource.com/12634
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>
2016-12-08 00:46:03 +00:00
David Benjamin 93c332b086 Tighten BIO_new_bio_pair.
This can be a bit shorter.

Change-Id: Ibccd1e90e7c0842d0d3951a070a68e075136657c
Reviewed-on: https://boringssl-review.googlesource.com/12627
Reviewed-by: Adam Langley <agl@google.com>
2016-12-07 23:58:40 +00:00
David Benjamin ed1d288a91 Unwind all the zero-copy BIO pair machinery.
This was only used by Chromium and was since replaced with a custom BIO.
Though it meant a new ring buffer implementation, custom BIOs seem a
better solution for folks who wish to do particularly complicated
things, until the new SSL API is available. External-buffer BIO pairs
were effectively a really confusing and leaky abstraction over a ring
buffer anyway.

Change-Id: I0e201317ff87cdccb17b2f8c260ee5bb06c74771
Reviewed-on: https://boringssl-review.googlesource.com/12626
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-12-07 23:56:11 +00:00
Adam Langley 33b1d4f575 Check that tests with a version in the name do something with versions.
Change-Id: Ida26e32a700c68e1899f9f6ccff73e2fa5252313
Reviewed-on: https://boringssl-review.googlesource.com/12633
Commit-Queue: Adam Langley <agl@google.com>
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>
2016-12-07 23:25:59 +00:00
David Benjamin eebd3c88ac Add SSL_(CTX_)set_tls_channel_id_enabled.
This allows a consumer to disable Channel ID (for instance, it may be
enabled on the SSL_CTX and later disabled on the SSL) without reaching
into the SSL struct directly.

Deprecate the old APIs in favor of these.

BUG=6

Change-Id: I193bf94bc1f537e1a81602a39fc2b9a73f44c73b
Reviewed-on: https://boringssl-review.googlesource.com/12623
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-12-07 23:11:12 +00:00
David Benjamin 8db920ad5d Remove SSL_ctrl compatibility macros for Channel ID.
This is an API which we added, so only first-party code could be
conditioning on it.

Change-Id: I08217fcae47585b22142df05622e31b6dfb6e4d6
Reviewed-on: https://boringssl-review.googlesource.com/12622
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-12-07 21:28:55 +00:00
David Benjamin 2578b29126 Make ssl3_choose_cipher and dependencies static.
Each of these functions is called only once, but they're interspersed
between s3_lib.c and ssl_lib.c.

Change-Id: Ic496e364b091fc8e01fc0653fe73c83c47f690d9
Reviewed-on: https://boringssl-review.googlesource.com/12583
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-12-07 20:13:49 +00:00
David Benjamin 731058ec8e Typedef ssl_early_callback_ctx to SSL_CLIENT_HELLO.
It's our ClientHello representation. May as well name it accordingly.
Also switch away from calling the variable name ctx as that conflicts
with SSL_CTX.

Change-Id: Iec0e597af37137270339e9754c6e08116198899e
Reviewed-on: https://boringssl-review.googlesource.com/12581
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-12-07 19:52:11 +00:00
David Benjamin 91e9b0de02 Remove tls_record_type_t.
The various key schedule cleanups have removed the need for this enum.

Change-Id: I3269aa19b834815926ad56b2d919e21b5e2603fe
Reviewed-on: https://boringssl-review.googlesource.com/12582
Reviewed-by: Adam Langley <agl@google.com>
2016-12-07 19:43:50 +00:00
Adam Langley df447ba3a9 Add generic AES-GCM-SIV support.
AES-GCM-SIV is an AEAD with nonce-misuse resistance. It can reuse
hardware support for AES-GCM and thus encrypt at ~66% the speed, and
decrypt at 100% the speed, of AES-GCM.

See https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-02

This implementation is generic, not optimised, and reuses existing AES
and GHASH support as much as possible. It is guarded by !OPENSSL_SMALL,
at least for now.

Change-Id: Ia9f77b256ef5dfb8588bb9ecfe6ee0e827626f57
Reviewed-on: https://boringssl-review.googlesource.com/12541
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-12-07 00:13:50 +00:00
Adam Langley cd6cfb070d Test SendReceiveIntermediate* with expected version.
Change-Id: I1e28ba84de59336cab432d1db3dd9c6023909081
Reviewed-on: https://boringssl-review.googlesource.com/12625
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>
2016-12-07 00:05:02 +00:00
Nick Harper dfec182af4 Remove Fake TLS 1.3 code from prf.go.
Change-Id: Ie46d45cdb07c692a789594e13040a1ce9d6cf83d
Reviewed-on: https://boringssl-review.googlesource.com/12640
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>
2016-12-06 22:11:09 +00:00
David Benjamin f3c8f8d19d Pass explicit parameters elsewhere.
The remaining direct accesses are in functions which expect to be called
in and out of the handshake. Accordingly, they are NULL-checked.

Change-Id: I07a7de6bdca7b6f8d09e22da11b8863ebf41389a
Reviewed-on: https://boringssl-review.googlesource.com/12343
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>
2016-12-06 19:54:58 +00:00
David Benjamin 8baf963523 Pass explicit hs parameters to ssl_ext_*.
Change-Id: I84a8ff1d717f3291403f6fc49668c84f89b910da
Reviewed-on: https://boringssl-review.googlesource.com/12342
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>
2016-12-06 19:53:25 +00:00
David Benjamin 6773972ff6 Pass explicit hs parameters into t1_enc.c.
Change-Id: I5ef0fe5cc3ae0d5029ae41db36e66d22d76f6158
Reviewed-on: https://boringssl-review.googlesource.com/12341
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>
2016-12-06 19:49:46 +00:00
David Benjamin 2bd1917866 Pass explicit hs parameters into custom_extensions.c.
Change-Id: Id8543a88929091eb004a5205a30b483253cdaa25
Reviewed-on: https://boringssl-review.googlesource.com/12319
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>
2016-12-06 19:49:36 +00:00
David Benjamin 6e4fc336c4 Pass explicit hs parameters to tls13_*.c.
This removes all explicit ssl->s3->hs access in those files.

Change-Id: I801ca1c894936aecef21e56ec7e7acb9d1b99688
Reviewed-on: https://boringssl-review.googlesource.com/12318
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>
2016-12-06 19:49:24 +00:00
David Benjamin 8c880a2b95 Pass explicit hs parameters to kExtensions callbacks.
This takes care of many of the explicit ssl->s3->hs accesses.

Change-Id: I380fae959f3a7021d6de9d19a4ca451b9a0aefe5
Reviewed-on: https://boringssl-review.googlesource.com/12317
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>
2016-12-06 19:48:37 +00:00
Adam Langley 7b668a873e Enable getrandom for entropy gathering.
This change will cause getrandom to be used in preference to
/dev/urandom when supported by the kernel.

This will also cause BoringSSL-using processes to block until the
entropy pool is initialised on systems that support getrandom(2).

Change-Id: I2d3a17891502c85884c77138ef0f3a719d7ecfe6
Reviewed-on: https://boringssl-review.googlesource.com/12421
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-12-06 19:37:08 +00:00
David Benjamin c3c8882918 Match state machine functions with new calling convention.
This cuts down on a lot of unchecked ssl->s3->hs accesses. Next is
probably the mass of extensions callbacks, and then we can play
whack-a-mole with git grep.

Change-Id: I81c506ea25c2569a51ceda903853465b8b567b0f
Reviewed-on: https://boringssl-review.googlesource.com/12237
Reviewed-by: Steven Valdez <svaldez@google.com>
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>
2016-12-06 19:36:45 +00:00
David Benjamin ce8c9d2b41 Maintain SSL_HANDSHAKE lifetime outside of handshake_func.
We currently look up SSL_HANDSHAKE off of ssl->s3->hs everywhere, but
this is a little dangerous. Unlike ssl->s3->tmp, ssl->s3->hs may not be
present. Right now we just know not to call some functions outside the
handshake.

Instead, code which expects to only be called during a handshake should
take an explicit SSL_HANDSHAKE * parameter and can assume it non-NULL.
This replaces the SSL * parameter. Instead, that is looked up from
hs->ssl.

Code which is called in both cases, reads from ssl->s3->hs. Ultimately,
we should get to the point that all direct access of ssl->s3->hs needs
to be NULL-checked.

As a start, manage the lifetime of the ssl->s3->hs in SSL_do_handshake.
This allows the top-level handshake_func hooks to be passed in the
SSL_HANDSHAKE *. Later work will route it through the stack. False Start
is a little wonky, but I think this is cleaner overall.

Change-Id: I26dfeb95f1bc5a0a630b5c442c90c26a6b9e2efe
Reviewed-on: https://boringssl-review.googlesource.com/12236
Reviewed-by: Steven Valdez <svaldez@google.com>
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>
2016-12-06 19:36:27 +00:00
David Benjamin 7d7597840f Fix x509v3_cache_extensions locking.
Change-Id: Id976e5e5c03e9af7b59fda2429111e189b188f37
Reviewed-on: https://boringssl-review.googlesource.com/11245
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-12-05 23:12:49 +00:00
Adam Langley 5fa2538162 Clean up the GHASH init function a little.
There only needs to be a single place where we do the generic
initialisation. All the processor-specific implementations can just
return early.

Change-Id: Ifd8a9c3bd7bec1ee8307aaa7bbeb9afe575e8a47
Reviewed-on: https://boringssl-review.googlesource.com/12540
Reviewed-by: Adam Langley <alangley@gmail.com>
Commit-Queue: Adam Langley <alangley@gmail.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-12-05 21:49:47 +00:00
Adam Langley abd36dd284 Set needed defines for UINT64_C in gcm_test.cc.
Change-Id: Ia38acd73e18a78b6bf9b9d10339f920b7f105c85
Reviewed-on: https://boringssl-review.googlesource.com/12601
Reviewed-by: Adam Langley <agl@google.com>
2016-12-05 21:46:52 +00:00
Adam Langley 64a8659b89 Rename BSWAP[48] to CRYPTO_bswap[48] and always define them.
Previously, gcm.c contained a lot of workarounds for cases where BSWAP8
wasn't defined. Rather than handle this in each place, just make it
always available.

While we're here, make these macros inline functions instead and rename
them to something less likely to collide.

Change-Id: I9f2602f8b9965c63a86b177a8a084afb8b53a253
Reviewed-on: https://boringssl-review.googlesource.com/12479
Commit-Queue: Adam Langley <alangley@gmail.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-12-05 21:37:16 +00:00
David Benjamin 48891ad07c Simplify BoGo's TLS 1.3 key derivation.
finishedHash should keep a running secret and incorporate entropy as is
available.

Change-Id: I2d245897e7520b2317bc0051fa4d821c32eeaa10
Reviewed-on: https://boringssl-review.googlesource.com/12586
Reviewed-by: Nick Harper <nharper@chromium.org>
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>
2016-12-05 18:45:09 +00:00
David Benjamin 0d1faefdde Also add util/bot/golang to .gitignore.
I missed this one.

Change-Id: I642fb5878568870743727579126f63246ff179c5
Reviewed-on: https://boringssl-review.googlesource.com/12580
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-12-02 23:39:35 +00:00
Adam Langley c629e8b688 Split CRYPTO_ghash_init from CRYPTO_gcm128_init.
CRYPTO_ghash_init exposes the (often hardware accelerated) internals for
evaluating GHASH. These can be used for evaluating POLYVAL[1] on
platforms where we don't have dedicated code for it.

[1] https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-02#section-3

Change-Id: Ida49ce4911f8657fa384b0bca968daa2ac6b26c1
Reviewed-on: https://boringssl-review.googlesource.com/12478
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>
2016-12-02 21:09:11 +00:00
Adam Langley a00cafc50c Drop H (the key) from the GCM context.
The key is only needed during initialisation because after that point it
is implicit in the table of powers. So no need to keep it around. There
was a non-specific “haunted house” comment about not changing this, but
I've successfully tested with all the assembly versions so I think that
comment is no longer true.

Change-Id: Id110156afb528904f114d9a4ff2440e03a1a69b8
Reviewed-on: https://boringssl-review.googlesource.com/12477
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
2016-12-02 20:59:47 +00:00
Adam Langley e8bbc6cf6c Assume little-endian in GCM code.
The GCM code has lots of cases of big-endian support left over from
OpenSSL. Since we don't support big-endian systems, drop that code.

Change-Id: I28eb95a9c235c6f705a145fbea72e7569dad2c70
Reviewed-on: https://boringssl-review.googlesource.com/12476
Commit-Queue: Adam Langley <agl@google.com>
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>
2016-12-02 20:46:35 +00:00
David Benjamin 0ec5639092 Don't extract archives if unchanged.
This should shave 20% (40 seconds) off our Windows cycle times, going by
the graphs. It's 15% off our Linux ones, but that 15% is only 11
seconds.

Change-Id: I077c3924c722d597f66fc6dec72932ed0c81660a
Reviewed-on: https://boringssl-review.googlesource.com/12562
Reviewed-by: Adam Langley <agl@google.com>
2016-12-02 18:36:32 +00:00
David Benjamin 65241cf555 Add util/bot files to .gitignore.
bot_update does a git clean -dff before each run, so we were
redownloading all the utilities on each run. This should make the bots
only download them when the change. (Chromium's setup is similar.)

Change-Id: I7eb83217761ceabe58b5480242a7df93d9bfaa52
Reviewed-on: https://boringssl-review.googlesource.com/12561
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-12-02 18:35:32 +00:00
Adam Langley f18ad089f1 tool: don't generate negative serial numbers.
MSVC, on 32-bit systems, defines sizeof(long)=4 which means that a
uint32_t could end up negative when passed to |ASN1_INTEGER_set| on
Windows.

Change-Id: Ib07487ab524550c832909bf10521aae61d654416
Reviewed-on: https://boringssl-review.googlesource.com/12560
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: Martin Kreichgauer <martinkr@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-12-01 23:32:49 +00:00
David Benjamin d8a268261d Simplify rotate_offset computation in EVP_tls_cbc_copy_mac.
Rather than Barrett reduction, we can just sample rotate_offset at the
point where we save the first byte of the MAC. Thanks to Andy Polyakov
for the idea in
https://github.com/openssl/openssl/pull/1027#issuecomment-263218179

Change-Id: If3a7c2d176406fc332ac512648e6f5ef4dc8b7e5
Reviewed-on: https://boringssl-review.googlesource.com/12475
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-12-01 22:02:03 +00:00
David Benjamin a4ddb6e212 Remove unnecessary constant-time operation.
j and md_size are public values, so this can just be done directly. (If
they weren't, we'd have worse problems.) This makes the loop look the
same as the rotation loop below.

Change-Id: Ic75550ad4e40b2015668cb12c26ca2d20bd285b6
Reviewed-on: https://boringssl-review.googlesource.com/12474
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-12-01 21:54:45 +00:00
David Benjamin 029cce5cfd Tidy up EVP_tls_cbc_copy_mac a little.
Some declarations can be moved closer to use, etc.

Change-Id: Ifa9a51ad77639b94020b15478af234c82466390f
Reviewed-on: https://boringssl-review.googlesource.com/12473
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-12-01 21:53:29 +00:00
David Benjamin aedf303cc2 Parse the entire PSK extension.
Although we ignore all but the first identity, keep clients honest by
parsing the whole thing. Also explicitly check that the binder and
identity counts match.

Change-Id: Ib9c4caae18398360f3b80f8db1b22d4549bd5746
Reviewed-on: https://boringssl-review.googlesource.com/12469
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>
2016-12-01 21:53:13 +00:00
Alessandro Ghedini bf48364a8c Support setting per-connection default session lifetime value
Due to recent changes, changing the SSL session timeout from cert_cb is
not possible anymore since the new |SSL_SESSION| is initialized *after*
cert_cb is run. The alternative would be using |SSL_CTX_set_timeout| but
the specific |SSL_CTX| could be shared by multiple |SSL|s.

Setting a value on a per-connection basis is useful in case timeouts
need to be calculated dynamically based on specific certificate/domain
information that would be retrieved from inside cert_cb (or other
callbacks).

It would also be possible to set the value to 0 to prevent session
resumption, which is not otherwise doable in the handshake callbacks.

Change-Id: I730a528c647f83f7f77f59b5b21d7e060e4c9843
Reviewed-on: https://boringssl-review.googlesource.com/12440
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>
2016-12-01 21:01:30 +00:00
Robert Sloan 15073af5b7 Adding a fuzzer for Sessions
Change-Id: I69cbb0679e1dbb6292a8f4737851736e58c17508
Reviewed-on: https://boringssl-review.googlesource.com/12481
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>
2016-12-01 20:22:56 +00:00
Steven Valdez a4ee74dadf Skipping early data on 0RTT rejection.
BUG=101

Change-Id: Ia1edbccee535b0bc3a0e18465286d5bcca240035
Reviewed-on: https://boringssl-review.googlesource.com/12470
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>
2016-12-01 20:16:08 +00:00
David Benjamin 8f820b4e43 Clean up resumption secret "derivation" step.
There is no more derivation step. We just use the resumption secret
directly. This saves us an unnecessary memcpy.

Change-Id: I203bdcc0463780c47cce655046aa1be560bb5b18
Reviewed-on: https://boringssl-review.googlesource.com/12472
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
2016-12-01 19:26:14 +00:00
Martin Kreichgauer ce1f62c3be Make bssl server generate a self-signed cert if none is provided.
Change-Id: I99e63341110151fc5584aa2ed874bc0441984eea
Reviewed-on: https://boringssl-review.googlesource.com/12471
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-12-01 17:54:47 +00:00
Adam Langley 509889d3d0 Sync with upstream's version of sha256-armv4.pl.
This change imports sha256-armv4.pl from upstream at rev 8d1ebff4. This
includes changes to remove the use of adrl, which is not supported by
Clang.

Change-Id: I429e7051d63b59acad21601e40883fc3bd8dd2f5
Reviewed-on: https://boringssl-review.googlesource.com/12480
Commit-Queue: Adam Langley <alangley@gmail.com>
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>
2016-11-30 17:37:24 +00:00
David Benjamin f086df9f5f signed char => int8_t.
This code wants something which can represent -128..127 or so, not
something about characters.

Change-Id: Icdbfec370317a5e03803939a3b8d1555f8efff1d
Reviewed-on: https://boringssl-review.googlesource.com/12468
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-11-29 01:03:52 +00:00
David Benjamin e4a9dbcf02 Minor formatting fixups.
clang-format mangled this a little.

Change-Id: Ic4d8de0e1f6e926efbe8d14e390fe874b4a7cdcb
Reviewed-on: https://boringssl-review.googlesource.com/12467
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-11-29 01:03:28 +00:00
David Benjamin bfe5f08170 Rewrite EC_window_bits_for_scalar_size into a function.
The compiler should be plenty smart enough to decide whether to inline a
static function called only once. We don't need to resort to so
unreadable a ternary chain.

Change-Id: Iacc8e0c4147fc69008806a0cc36d9e632169601a
Reviewed-on: https://boringssl-review.googlesource.com/12466
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-11-29 01:01:28 +00:00
David Benjamin c6d09e83c7 Check for BN_lshift failure in BN_sqrt.
Change-Id: I3350ff0e4ffe7495a83211b89c675a0125fb2f06
Reviewed-on: https://boringssl-review.googlesource.com/12465
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-11-29 00:55:56 +00:00
David Benjamin 1c68effac9 Fix error code for unreduced x.
EC_R_INVALID_COMPRESSED_POINT makes more sense than
EC_R_INVALID_COMPRESSION_BIT here.

Change-Id: I0dbdc91bab59843d5c04f2d0e97600fe7644753e
Reviewed-on: https://boringssl-review.googlesource.com/12464
Reviewed-by: Adam Langley <agl@google.com>
2016-11-29 00:55:04 +00:00
David Benjamin 14ebb4ff27 Don't compute the Kronecker symbol in ec_GFp_simple_set_compressed_coordinates.
If y is zero, there is no point with odd y, so the odd bit may not be
set, hence EC_R_INVALID_COMPRESSION_BIT. This code instead computed the
Kronecker symbol of x and changed the error code to
EC_R_INVALID_COMPRESSED_POINT if not a square.

As the comment says, this was (intended to be) unreachable. But it
seems x was a typo for tmp1. It dates to before upstream's
6fb60a84dd1ec81953917e0444dab50186617432, when BN_mod_sqrt gave
garbage if its input was not square. Now it emits BN_R_NOT_A_SQUARE.
Upstream's 48fe4d6233ac2d60745742a27f820dd88bc6689d then mapped
BN_R_NOT_A_SQUARE to EC_R_INVALID_COMPRESSED_POINT.

Change-Id: Id9e02fa1c154b61cc0c3a768c9cfe6bd9674c378
Reviewed-on: https://boringssl-review.googlesource.com/12463
Reviewed-by: Adam Langley <agl@google.com>
2016-11-29 00:36:04 +00:00
David Benjamin bd691756f2 Test that BN_mod_sqrt detects quadratic non-residues.
Change-Id: I99abb8f99c060f0830c1df9cdbde159c85ccfe92
Reviewed-on: https://boringssl-review.googlesource.com/12462
Reviewed-by: Adam Langley <agl@google.com>
2016-11-29 00:24:43 +00:00
David Benjamin 55a1eccc0c Don't allow BN_mod_sqrt(0) to return P in tests.
Zero only has one allowed square root, not two.

Change-Id: I1dbd2137a7011d2f327b271b267099771e5499c3
Reviewed-on: https://boringssl-review.googlesource.com/12461
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-11-29 00:23:07 +00:00
David Benjamin 3d622e554e Add missing bounds check in tls13_derive_resumption_secret.
This is fine because TLS PRFs only go up to SHA-384, but since
SSL_SESSION::master_key is sized to 48, not EVP_MAX_MD_SIZE, this should
explicitly check the bounds.

Change-Id: I2b1bcaab5cdfc3ce4d7a8b8ed5cc4c6d15d10270
Reviewed-on: https://boringssl-review.googlesource.com/12460
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
2016-11-28 20:36:32 +00:00
David Benjamin 68f37b7a3f Run TestOneSidedShutdown at all versions.
Change-Id: I3a5d949eec9241ea43da40ce23e0e7f2a25e30e5
Reviewed-on: https://boringssl-review.googlesource.com/12381
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
2016-11-21 18:56:48 +00:00
David Benjamin 0fef3056eb Add a ForEachVersion function to ssl_test.
This aligns with ec_test which has a ForEachCurve helper and avoids
writing these loops all the time. As a bonus, these tests start working
in DTLS now.

Change-Id: I613fc08b641ddc12a819d8a1268a1e6a29043663
Reviewed-on: https://boringssl-review.googlesource.com/12380
Reviewed-by: Steven Valdez <svaldez@google.com>
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>
2016-11-21 18:56:34 +00:00
Adam Langley 9b885c5d0f Don't allow invalid SCT lists to be set.
This change causes SSL_CTX_set_signed_cert_timestamp_list to check the
SCT list for shallow validity before allowing it to be set.

Change-Id: Ib8a1fe185224ff02ed4ce53a0109e60d934e96b3
Reviewed-on: https://boringssl-review.googlesource.com/12401
Commit-Queue: 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>
Reviewed-by: David Benjamin <davidben@google.com>
2016-11-19 00:24:18 +00:00
Adam Langley 6f5f49f33d Flush TLS 1.3 certificate extensions.
(Otherwise we end up touching potentially unwound stack.)

I looked into why our builders didn't catch this and it appears that, at
least with Clang 3.7, ASAN doesn't notice this. Perhaps Clang at that
version is being lazy about destructing the scoped CBB and so doesn't
actually go wrong.

Change-Id: Ia0f73e7eb662676439f024805fc8287a4e991ce0
Reviewed-on: https://boringssl-review.googlesource.com/12400
Reviewed-by: Adam Langley <agl@google.com>
2016-11-18 22:01:38 +00:00
Adam Langley cfa08c3b77 Enforce basic sanity of SCT lists.
According to the RFC[1], SCT lists may not be empty and nor may any SCT
itself be empty.

[1] https://tools.ietf.org/html/rfc6962#section-3.3

Change-Id: Ia1f855907588b36a4fea60872f87e25dc20782b4
Reviewed-on: https://boringssl-review.googlesource.com/12362
Reviewed-by: Adam Langley <agl@google.com>
2016-11-18 19:19:48 +00:00
David Benjamin b5172a722c Make tls1_setup_key_block static.
It is not called outside of t1_enc.c.

Change-Id: Ifd9d109eeb432e931361ebdf456243c490b93ecf
Reviewed-on: https://boringssl-review.googlesource.com/12340
Reviewed-by: Steven Valdez <svaldez@chromium.org>
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>
2016-11-18 03:58:26 +00:00
Doug Kwan 7da8ea72a6 Add forward declaration to avoid a compiler warning
This prevents a compiler warning from breaking ppc64le build.

Change-Id: I6752109bd02c6d078e656f89327093f8fb13a125
Reviewed-on: https://boringssl-review.googlesource.com/12363
Reviewed-by: Adam Langley <agl@google.com>
2016-11-18 00:25:50 +00:00
Adam Langley fbbef12918 Don't put a colon in the extra error message.
Since the printed format for errors uses colons to separate different
parts of the error message, this was confusing.

Change-Id: I4742becec2bcb56ad8dc2fdb9a3bb23e4452d1b2
Reviewed-on: https://boringssl-review.googlesource.com/12361
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Commit-Queue: Adam Langley <alangley@gmail.com>
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-11-17 21:46:34 +00:00
Adam Langley d7b9002aa5 Define BORINGSSL_SHARED_LIBRARY when building tests with Bazel.
Bazel builds tests as shared libraries and the new p256-x86_64_test
depends on accessing unexported symbols. Thus we need to define
BORINGSSL_SHARED_LIBRARY when building tests.

Change-Id: I1270c69ac9d1bcf6baa05ef6666078bd368d80cf
Reviewed-on: https://boringssl-review.googlesource.com/12360
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>
2016-11-17 20:49:27 +00:00
Doug Kwan 5f04b6bc3a Add ppc64le vector implementation of SHA-1.
This change contains a C implementation of SHA-1 for POWER using
AltiVec. It is almost as fast as the scalar-only assembly implementation
for POWER/POWERPC family in OpenSSL but it is easier to maintain and it
allows error checking with tools like ASAN.

This is tested only for ppc64le. It may nor may not work for other
platforms in the POWER/POWERPC familiy.

Before:

SHA-1 @ 16 bytes: ~30 MB/s
SHA-1 @ 8K: ~140 MB/s

After:

SHA-1 @ 16 bytes: ~70 MB/s
SHA-1 @ 8K: ~480 MB/s

Change-Id: I790352e86d9c0cc4e1e57d11c5a0aa5b0780ca6b
Reviewed-on: https://boringssl-review.googlesource.com/12203
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-11-17 18:38:14 +00:00
David Benjamin 35598ae8dd Remove ext_alpn_init.
We do not change ALPN on renego, so the value should carry over and not
be cleared.

Change-Id: Id54a083945542b4457d9c2787f0fe7c30239b76f
Reviewed-on: https://boringssl-review.googlesource.com/12306
Reviewed-by: David Benjamin <davidben@google.com>
2016-11-17 06:46:48 +00:00
David Benjamin e7f60a2852 Fix alert on tls1_process_alert failure.
If the function fails, it's an internal_error.

Change-Id: I4b7cf7a6ca2527f04b708303ab1bc71df762b55b
Reviewed-on: https://boringssl-review.googlesource.com/12312
Reviewed-by: David Benjamin <davidben@google.com>
2016-11-17 06:45:38 +00:00
David Benjamin 12d6bafed8 Make ssl_ext_pre_shared_key_add_clienthello static.
It doesn't need to be exported out of t1_lib.c.

Change-Id: I000493e1e330457051da1719ca9f8152a4ff845a
Reviewed-on: https://boringssl-review.googlesource.com/12316
Reviewed-by: Steven Valdez <svaldez@chromium.org>
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>
2016-11-17 06:33:30 +00:00
David Benjamin 2aaaa16251 Depend all_tests on p256-x86_64_test.
Otherwise the run_tests target sometimes gets confused.

Change-Id: If49e945bf5137c68db4927ab0f9845d25be63bac
Reviewed-on: https://boringssl-review.googlesource.com/12315
Reviewed-by: Steven Valdez <svaldez@chromium.org>
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>
2016-11-17 02:56:51 +00:00
David Benjamin bbaf367969 Add |SSL_set_retain_only_sha256_of_client_certs|.
Previously the option to retain only the SHA-256 hash of client
certificates could only be set at the |SSL_CTX| level. This change makes
|SSL| objects inherit the setting from the |SSL_CTX|, but allows it to
be overridden on a per-|SSL| basis.

Change-Id: Id435934af3d425d5f008d2f3b9751d1d0884ee55
Reviewed-on: https://boringssl-review.googlesource.com/12182
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>
2016-11-17 02:49:19 +00:00
David Benjamin a933c38f1a Test setting session ID context in early or SNI callback.
The former has always worked. The latter is new to the revised
processing order.

Change-Id: I993d29ccaca091725524847695df4d1944b609cf
Reviewed-on: https://boringssl-review.googlesource.com/11848
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-11-17 01:22:05 +00:00
David Benjamin f01f42a2ce Negotiate ciphers before resumption.
This changes our resumption strategy. Before, we would negotiate ciphers
only on fresh handshakes. On resumption, we would blindly use whatever
was in the session.

Instead, evaluate cipher suite preferences on every handshake.
Resumption requires that the saved cipher suite match the one that would
have been negotiated anyway. If client or server preferences changed
sufficiently, we decline the session.

This is much easier to reason about (we always pick the best cipher
suite), simpler, and avoids getting stuck under old preferences if
tickets are continuously renewed. Notably, although TLS 1.2 ticket
renewal does not work in practice, TLS 1.3 will renew tickets like
there's no tomorrow.

It also means we don't need dedicated code to avoid resuming a cipher
which has since been disabled. (That dedicated code was a little odd
anyway since the mask_k, etc., checks didn't occur. When cert_cb was
skipped on resumption, one could resume without ever configuring a
certificate! So we couldn't know whether to mask off RSA or ECDSA cipher
suites.)

Add tests which assert on this new arrangement.

BUG=116

Change-Id: Id40d851ccd87e06c46c6ec272527fd8ece8abfc6
Reviewed-on: https://boringssl-review.googlesource.com/11847
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-11-17 01:02:42 +00:00
David Benjamin 34202b93b6 Call cert_cb before resolving resumption.
This is in preparation for determining the cipher suite (which, in TLS
1.2, requires the certificate be known) before resumption.

Note this has caller-visible effects:

- cert_cb is now called whether resumption occurs or not. Our only
  consumer which uses this as a server is Node which will require a
  patch to fix up their mucking about with SSL_get_session. (But the
  patch should be quite upstreamable. More 1.1.0-compatible and
  generally saner.)

- cert_cb is now called before new_session_cb and dos_protection_cb.

BUG=116

Change-Id: I6cc745757f63281fad714d4548f23880570204b0
Reviewed-on: https://boringssl-review.googlesource.com/11846
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-11-17 00:29:46 +00:00
David Benjamin 4eb95ccfd6 Parse ClientHello extensions before deciding on resumption.
This simplifies a little code around EMS and PSK KE modes, but requires
tweaking the SNI code.

The extensions that are more tightly integrated with the handshake are
still processed inline for now. It does, however, require an extra state
in 1.2 so the asynchronous session callback does not cause extensions to
be processed twice. Tweak a test enforce this.

This and a follow-up to move cert_cb before resumption are done in
preparation for resolving the cipher suite before resumption and only
resuming on match.

Note this has caller-visible effects:

- The legacy SNI callback happens before resumption.

- The ALPN callback happens before resumption.

- Custom extension ClientHello parsing callbacks also cannot depend on
  resumption state.

- The DoS protection callback now runs after all the extension callbacks
  as it is documented to be called after the resumption decision.

BUG=116

Change-Id: I1281a3b61789b95c370314aaed4f04c1babbc65f
Reviewed-on: https://boringssl-review.googlesource.com/11845
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-11-16 23:58:02 +00:00
Alessandro Ghedini 8d3f130c55 tool: print client's SNI value, if any.
Change-Id: I4fbce046090f0b0e78c9de923643268cfe6f142f
Reviewed-on: https://boringssl-review.googlesource.com/12241
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-11-16 19:32:16 +00:00
David Benjamin 4008c7a80d Fix some more negative zeros and add tests for each case.
See https://github.com/openssl/openssl/pull/1672.

Change-Id: I4c93a568b9b7ce582b03e955d3aa9cb6b0e89794
Reviewed-on: https://boringssl-review.googlesource.com/12314
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-11-16 19:20:27 +00:00
David Benjamin ca0b603153 Remove unnecessary BN_is_negative check in p256-x86_64_test.
A BN_ULONG[P256_LIMBS] can't represent a negative number and
bn_set_words won't produce one. We only need to compare against P.

Change-Id: I7bd1c9e8c162751637459f23f3cfc56884d85864
Reviewed-on: https://boringssl-review.googlesource.com/12304
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-11-16 19:19:38 +00:00
David Benjamin dc16f38685 ec/ecp_nistz256: harmonize is_infinity with ec_GFp_simple_is_at_infinity.
RT#4625

(Imported from upstream's e3057a57caf4274ea1fb074518e4714059dfcabf.)

Add a test in ec_test to cover the ecp_nistz256_points_mul change. Also
revise the low-level infinity tests to cover the changes in
ecp_nistz256_point_add. Upstream's 'infty' logic was also cleaned up to
be simpler and take advantage of the only cases where |p| is infinity.

Change-Id: Ie22de834bf79ecb6191e824ad9fc1bd6f9681b8b
Reviewed-on: https://boringssl-review.googlesource.com/12225
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
2016-11-16 18:16:54 +00:00
1451 changed files with 129426 additions and 42462 deletions
+15
View File
@@ -4,3 +4,18 @@ ssl/test/runner/runner
*.swo
doc/*.html
doc/doc.css
util/bot/android_tools
util/bot/cmake-linux64
util/bot/cmake-linux64.tar.gz
util/bot/cmake-mac
util/bot/cmake-mac.tar.gz
util/bot/cmake-win32
util/bot/cmake-win32.zip
util/bot/golang
util/bot/gyp
util/bot/llvm-build
util/bot/perl-win32
util/bot/perl-win32.zip
util/bot/win_toolchain.json
util/bot/yasm-win32.exe
+2 -2
View File
@@ -14,10 +14,10 @@ All supported public APIs are documented in the public header files, found in
Some headers lack documention comments. These are functions and structures from
OpenSSL's legacy ASN.1, X.509, and PEM implementation. If possible, avoid using
them. These are left largely unmodified from upstream and are retained only for
compatibilty with existing OpenSSL consumers.
compatibility with existing OpenSSL consumers.
# Forward declarations
## Forward declarations
Do not write `typedef struct foo_st FOO` or try otherwise to define BoringSSL's
types. Including `openssl/base.h` (or `openssl/ossl_typ.h` for consumers who
+2 -2
View File
@@ -2,7 +2,7 @@
## Build Prerequisites
* [CMake](https://cmake.org/download/) 2.8.8 or later is required.
* [CMake](https://cmake.org/download/) 2.8.11 or later is required.
* Perl 5.6.1 or later is required. On Windows,
[Active State Perl](http://www.activestate.com/activeperl/) has been
@@ -33,7 +33,7 @@
executable may be configured explicitly by setting `GO_EXECUTABLE`.
* To build the x86 and x86\_64 assembly, your assembler must support AVX2
instructions. If using GNU binutils, you must have 2.22 or later.
instructions and MOVBE. If using GNU binutils, you must have 2.22 or later.
## Building
+47 -1
View File
@@ -1,4 +1,4 @@
cmake_minimum_required (VERSION 2.8.10)
cmake_minimum_required (VERSION 2.8.11)
# Defer enabling C and CXX languages.
project (BoringSSL NONE)
@@ -43,6 +43,9 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
endif()
elseif(MSVC)
set(MSVC_DISABLED_WARNINGS_LIST
"C4061" # enumerator 'identifier' in switch of enum 'enumeration' is not
# explicitly handled by a case label
# Disable this because it flags even when there is a default.
"C4100" # 'exarg' : unreferenced formal parameter
"C4127" # conditional expression is constant
"C4200" # nonstandard extension used : zero-sized array in
@@ -78,12 +81,16 @@ elseif(MSVC)
# copy constructor is inaccessible or deleted
"C4626" # assignment operator could not be generated because a base class
# assignment operator is inaccessible or deleted
"C4668" # 'symbol' is not defined as a preprocessor macro, replacing with
# '0' for 'directives'
# Disable this because GTest uses it everywhere.
"C4706" # assignment within conditional expression
"C4710" # 'function': function not inlined
"C4711" # function 'function' selected for inline expansion
"C4800" # 'int' : forcing value to bool 'true' or 'false'
# (performance warning)
"C4820" # 'bytes' bytes padding added after construct 'member_name'
"C5026" # move constructor was implicitly defined as deleted
"C5027" # move assignment operator was implicitly defined as deleted
)
set(MSVC_LEVEL4_WARNINGS_LIST
@@ -174,6 +181,9 @@ elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64")
set(ARCH "aarch64")
elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "mips")
# Just to avoid the “unknown processor” error.
set(ARCH "generic")
elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "ppc64le")
set(ARCH "ppc64le")
else()
message(FATAL_ERROR "Unknown processor:" ${CMAKE_SYSTEM_PROCESSOR})
endif()
@@ -192,11 +202,47 @@ if (${ARCH} STREQUAL "x86" AND APPLE)
set(ARCH "x86_64")
endif()
if (MSAN)
if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
message(FATAL_ERROR "Cannot enable MSAN unless using Clang")
endif()
if (ASAN)
message(FATAL_ERROR "ASAN and MSAN are mutually exclusive")
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer")
set(OPENSSL_NO_ASM "1")
endif()
if (ASAN)
if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
message(FATAL_ERROR "Cannot enable ASAN unless using Clang")
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fsanitize-address-use-after-scope -fno-omit-frame-pointer")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fsanitize-address-use-after-scope -fno-omit-frame-pointer")
set(OPENSSL_NO_ASM "1")
endif()
if (GCOV)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
endif()
if (OPENSSL_NO_ASM)
add_definitions(-DOPENSSL_NO_ASM)
set(ARCH "generic")
endif()
# Add minimal googletest targets. The provided one has many side-effects, and
# googletest has a very straightforward build.
add_library(gtest third_party/googletest/src/gtest-all.cc)
target_include_directories(gtest PRIVATE third_party/googletest)
include_directories(third_party/googletest/include)
# Declare a dummy target to build all unit tests. Test targets should inject
# themselves as dependencies next to the target definition.
add_custom_target(all_tests)
+4 -3
View File
@@ -23,7 +23,7 @@ Then copy `libFuzzer.a` to the top-level of your BoringSSL source directory.
From the `build/` directory, you can then run the fuzzers. For example:
```
./fuzz/cert -max_len=3072 -jobs=32 -workers=32 ../fuzz/cert_corpus/
./fuzz/cert -max_len=10000 -jobs=32 -workers=32 ../fuzz/cert_corpus/
```
The arguments to `jobs` and `workers` should be the number of cores that you wish to dedicate to fuzzing. By default, libFuzzer uses the largest test in the corpus (or 64 if empty) as the maximum test case length. The `max_len` argument overrides this.
@@ -32,11 +32,12 @@ The recommended values of `max_len` for each test are:
| Test | `max_len` value |
|---------------|-----------------|
| `cert` | 3072 |
| `cert` | 10000 |
| `client` | 20000 |
| `pkcs8` | 2048 |
| `privkey` | 2048 |
| `server` | 4096 |
| `session` | 8192 |
| `spki` | 1024 |
| `read_pem` | 512 |
| `ssl_ctx_api` | 256 |
@@ -79,5 +80,5 @@ If both sets of tests pass, refresh the fuzzer corpora with `refresh_ssl_corpora
```
cd fuzz
./refresh_fuzzer_corpora.sh /path/to/fuzzer/mode/build /path/to/non/fuzzer/mode/build
./refresh_ssl_corpora.sh /path/to/fuzzer/mode/build /path/to/non/fuzzer/mode/build
```
+1
View File
@@ -227,6 +227,7 @@ parameter.
`SSL_CTRL_OPTIONS` | `SSL_CTX_get_options` or `SSL_CTX_set_options`
`SSL_CTRL_SESS_NUMBER` | `SSL_CTX_sess_number`
`SSL_CTRL_SET_CURVES` | `SSL_CTX_set1_curves`
`SSL_CTRL_SET_ECDH_AUTO` | `SSL_CTX_set_ecdh_auto`
`SSL_CTRL_SET_MAX_CERT_LIST` | `SSL_CTX_set_max_cert_list`
`SSL_CTRL_SET_MAX_SEND_FRAGMENT` | `SSL_CTX_set_max_send_fragment`
`SSL_CTRL_SET_MSG_CALLBACK` | `SSL_set_msg_callback`
+10
View File
@@ -45,6 +45,16 @@ not
Rather than `malloc()` and `free()`, use the wrappers `OPENSSL_malloc()`
and `OPENSSL_free()`. Use the standard C `assert()` function freely.
Use the following wrappers, found in `crypto/internal.h` instead of the
corresponding C standard library functions. They behave the same but avoid
confusing undefined behavior.
* `OPENSSL_memchr`
* `OPENSSL_memcmp`
* `OPENSSL_memcpy`
* `OPENSSL_memmove`
* `OPENSSL_memset`
For new constants, prefer enums when the values are sequential and typed
constants for flags. If adding values to an existing set of `#define`s,
continue with `#define`.
+27 -15
View File
@@ -78,7 +78,6 @@ add_subdirectory(conf)
add_subdirectory(chacha)
add_subdirectory(poly1305)
add_subdirectory(curve25519)
add_subdirectory(newhope)
# Level 1, depends only on 0.*
add_subdirectory(digest)
@@ -130,7 +129,6 @@ add_library(
thread_none.c
thread_pthread.c
thread_win.c
time_support.c
$<TARGET_OBJECTS:stack>
$<TARGET_OBJECTS:lhash>
@@ -172,24 +170,12 @@ add_library(
$<TARGET_OBJECTS:x509>
$<TARGET_OBJECTS:x509v3>
$<TARGET_OBJECTS:pkcs8_lib>
$<TARGET_OBJECTS:newhope>
)
if(NOT MSVC AND NOT ANDROID)
target_link_libraries(crypto pthread)
endif()
add_executable(
constant_time_test
constant_time_test.c
$<TARGET_OBJECTS:test_support>
)
target_link_libraries(constant_time_test crypto)
add_dependencies(all_tests constant_time_test)
add_executable(
thread_test
@@ -204,8 +190,34 @@ add_dependencies(all_tests thread_test)
add_executable(
refcount_test
refcount_test.c
refcount_test.cc
)
target_link_libraries(refcount_test crypto)
add_dependencies(all_tests refcount_test)
# TODO(davidben): Convert the remaining tests to GTest.
add_executable(
crypto_test
asn1/asn1_test.cc
bio/bio_test.cc
chacha/chacha_test.cc
constant_time_test.cc
curve25519/x25519_test.cc
dh/dh_test.cc
dsa/dsa_test.cc
ec/ec_test.cc
err/err_test.cc
evp/evp_extra_test.cc
rsa/rsa_test.cc
$<TARGET_OBJECTS:gtest_main>
$<TARGET_OBJECTS:test_support>
)
target_link_libraries(crypto_test crypto gtest)
if (WIN32)
target_link_libraries(crypto_test ws2_32)
endif()
add_dependencies(all_tests crypto_test)
+12 -4
View File
@@ -21,6 +21,7 @@
#include <openssl/aes.h>
#include <openssl/crypto.h>
#include "../internal.h"
#include "../test/file_test.h"
@@ -54,7 +55,7 @@ static bool TestRaw(FileTest *t) {
}
// Test in-place encryption.
memcpy(block, plaintext.data(), AES_BLOCK_SIZE);
OPENSSL_memcpy(block, plaintext.data(), AES_BLOCK_SIZE);
AES_encrypt(block, block, &aes_key);
if (!t->ExpectBytesEqual(block, AES_BLOCK_SIZE, ciphertext.data(),
ciphertext.size())) {
@@ -76,7 +77,7 @@ static bool TestRaw(FileTest *t) {
}
// Test in-place decryption.
memcpy(block, ciphertext.data(), AES_BLOCK_SIZE);
OPENSSL_memcpy(block, ciphertext.data(), AES_BLOCK_SIZE);
AES_decrypt(block, block, &aes_key);
if (!t->ExpectBytesEqual(block, AES_BLOCK_SIZE, plaintext.data(),
plaintext.size())) {
@@ -123,7 +124,7 @@ static bool TestKeyWrap(FileTest *t) {
return false;
}
memset(buf.get(), 0, ciphertext.size());
OPENSSL_memset(buf.get(), 0, ciphertext.size());
if (AES_wrap_key(&aes_key, kDefaultIV, buf.get(), plaintext.data(),
plaintext.size()) != static_cast<int>(ciphertext.size()) ||
!t->ExpectBytesEqual(buf.get(), ciphertext.size(), ciphertext.data(),
@@ -146,7 +147,7 @@ static bool TestKeyWrap(FileTest *t) {
return false;
}
memset(buf.get(), 0, plaintext.size());
OPENSSL_memset(buf.get(), 0, plaintext.size());
if (AES_unwrap_key(&aes_key, kDefaultIV, buf.get(), ciphertext.data(),
ciphertext.size()) != static_cast<int>(plaintext.size()) ||
!t->ExpectBytesEqual(buf.get(), plaintext.size(), plaintext.data(),
@@ -155,6 +156,13 @@ static bool TestKeyWrap(FileTest *t) {
return false;
}
ciphertext[0] ^= 1;
if (AES_unwrap_key(&aes_key, nullptr /* iv */, buf.get(), ciphertext.data(),
ciphertext.size()) != -1) {
t->PrintLine("AES_unwrap_key with bad input unexpectedly succeeded.");
return false;
}
return true;
}
+6 -6
View File
@@ -116,7 +116,7 @@
# words every cache-line is *guaranteed* to be accessed within ~50
# cycles window. Why just SSE? Because it's needed on hyper-threading
# CPU! Which is also why it's prefetched with 64 byte stride. Best
# part is that it has no negative effect on performance:-)
# part is that it has no negative effect on performance:-)
#
# Version 4.3 implements switch between compact and non-compact block
# functions in AES_cbc_encrypt depending on how much data was asked
@@ -578,7 +578,7 @@ sub enctransform()
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
# | mm4 | mm0 |
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
# | s3 | s2 | s1 | s0 |
# | s3 | s2 | s1 | s0 |
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
# |15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
@@ -798,7 +798,7 @@ sub encstep()
if ($i==3) { $tmp=$s[3]; &mov ($s[2],$__s1); }##%ecx
elsif($i==2){ &movz ($tmp,&HB($s[3])); }#%ebx[2]
else { &mov ($tmp,$s[3]);
else { &mov ($tmp,$s[3]);
&shr ($tmp,24) }
&xor ($out,&DWP(1,$te,$tmp,8));
if ($i<2) { &mov (&DWP(4+4*$i,"esp"),$out); }
@@ -1551,7 +1551,7 @@ sub sse_deccompact()
&pxor ("mm1","mm3"); &pxor ("mm5","mm7"); # tp4
&pshufw ("mm3","mm1",0xb1); &pshufw ("mm7","mm5",0xb1);
&pxor ("mm0","mm1"); &pxor ("mm4","mm5"); # ^= tp4
&pxor ("mm0","mm3"); &pxor ("mm4","mm7"); # ^= ROTATE(tp4,16)
&pxor ("mm0","mm3"); &pxor ("mm4","mm7"); # ^= ROTATE(tp4,16)
&pxor ("mm3","mm3"); &pxor ("mm7","mm7");
&pcmpgtb("mm3","mm1"); &pcmpgtb("mm7","mm5");
@@ -2021,7 +2021,7 @@ sub declast()
{
# stack frame layout
# -4(%esp) # return address 0(%esp)
# 0(%esp) # s0 backing store 4(%esp)
# 0(%esp) # s0 backing store 4(%esp)
# 4(%esp) # s1 backing store 8(%esp)
# 8(%esp) # s2 backing store 12(%esp)
# 12(%esp) # s3 backing store 16(%esp)
@@ -2731,7 +2731,7 @@ sub enckey()
&mov (&DWP(80,"edi"),10); # setup number of rounds
&xor ("eax","eax");
&jmp (&label("exit"));
&set_label("12rounds");
&mov ("eax",&DWP(0,"esi")); # copy first 6 dwords
&mov ("ebx",&DWP(4,"esi"));
Regular → Executable
+22 -24
View File
@@ -590,6 +590,7 @@ $code.=<<___;
.type asm_AES_encrypt,\@function,3
.hidden asm_AES_encrypt
asm_AES_encrypt:
mov %rsp,%rax
push %rbx
push %rbp
push %r12
@@ -598,7 +599,6 @@ asm_AES_encrypt:
push %r15
# allocate frame "above" key schedule
mov %rsp,%r10
lea -63(%rdx),%rcx # %rdx is key argument
and \$-64,%rsp
sub %rsp,%rcx
@@ -608,7 +608,7 @@ asm_AES_encrypt:
sub \$32,%rsp
mov %rsi,16(%rsp) # save out
mov %r10,24(%rsp) # save real stack pointer
mov %rax,24(%rsp) # save original stack pointer
.Lenc_prologue:
mov %rdx,$key
@@ -640,13 +640,13 @@ asm_AES_encrypt:
mov $s2,8($out)
mov $s3,12($out)
mov (%rsi),%r15
mov 8(%rsi),%r14
mov 16(%rsi),%r13
mov 24(%rsi),%r12
mov 32(%rsi),%rbp
mov 40(%rsi),%rbx
lea 48(%rsi),%rsp
mov -48(%rsi),%r15
mov -40(%rsi),%r14
mov -32(%rsi),%r13
mov -24(%rsi),%r12
mov -16(%rsi),%rbp
mov -8(%rsi),%rbx
lea (%rsi),%rsp
.Lenc_epilogue:
ret
.size asm_AES_encrypt,.-asm_AES_encrypt
@@ -1186,6 +1186,7 @@ $code.=<<___;
.type asm_AES_decrypt,\@function,3
.hidden asm_AES_decrypt
asm_AES_decrypt:
mov %rsp,%rax
push %rbx
push %rbp
push %r12
@@ -1194,7 +1195,6 @@ asm_AES_decrypt:
push %r15
# allocate frame "above" key schedule
mov %rsp,%r10
lea -63(%rdx),%rcx # %rdx is key argument
and \$-64,%rsp
sub %rsp,%rcx
@@ -1204,7 +1204,7 @@ asm_AES_decrypt:
sub \$32,%rsp
mov %rsi,16(%rsp) # save out
mov %r10,24(%rsp) # save real stack pointer
mov %rax,24(%rsp) # save original stack pointer
.Ldec_prologue:
mov %rdx,$key
@@ -1238,13 +1238,13 @@ asm_AES_decrypt:
mov $s2,8($out)
mov $s3,12($out)
mov (%rsi),%r15
mov 8(%rsi),%r14
mov 16(%rsi),%r13
mov 24(%rsi),%r12
mov 32(%rsi),%rbp
mov 40(%rsi),%rbx
lea 48(%rsi),%rsp
mov -48(%rsi),%r15
mov -40(%rsi),%r14
mov -32(%rsi),%r13
mov -24(%rsi),%r12
mov -16(%rsi),%rbp
mov -8(%rsi),%rbx
lea (%rsi),%rsp
.Ldec_epilogue:
ret
.size asm_AES_decrypt,.-asm_AES_decrypt
@@ -1286,7 +1286,7 @@ $code.=<<___;
asm_AES_set_encrypt_key:
push %rbx
push %rbp
push %r12 # redundant, but allows to share
push %r12 # redundant, but allows to share
push %r13 # exception handler...
push %r14
push %r15
@@ -1412,7 +1412,7 @@ $code.=<<___;
xor %rax,%rax
jmp .Lexit
.L14rounds:
.L14rounds:
mov 0(%rsi),%rax # copy first 8 dwords
mov 8(%rsi),%rbx
mov 16(%rsi),%rcx
@@ -1660,10 +1660,9 @@ asm_AES_cbc_encrypt:
mov %r9d,%r9d # clear upper half of enc
lea .LAES_Te(%rip),$sbox
lea .LAES_Td(%rip),%r10
cmp \$0,%r9
jne .Lcbc_picked_te
lea .LAES_Td(%rip),$sbox
.Lcbc_picked_te:
cmoveq %r10,$sbox
mov OPENSSL_ia32cap_P(%rip),%r10d
cmp \$$speed_limit,%rdx
@@ -2565,7 +2564,6 @@ block_se_handler:
jae .Lin_block_prologue
mov 24(%rax),%rax # pull saved real stack pointer
lea 48(%rax),%rax # adjust...
mov -8(%rax),%rbx
mov -16(%rax),%rbp
+3 -1
View File
@@ -51,7 +51,9 @@
# Westmere 3.77/1.37 1.37 1.52 1.27
# * Bridge 5.07/0.98 0.99 1.09 0.91
# Haswell 4.44/0.80 0.97 1.03 0.72
# Skylake 2.68/0.65 0.65 0.66 0.64
# Silvermont 5.77/3.56 3.67 4.03 3.46
# Goldmont 3.84/1.39 1.39 1.63 1.31
# Bulldozer 5.80/0.98 1.05 1.24 0.93
$PREFIX="aesni"; # if $PREFIX is set to "AES", the script
@@ -1040,7 +1042,7 @@ if ($PREFIX eq "aesni") {
&set_label("ctr32_one_shortcut",16);
&movups ($inout0,&QWP(0,$rounds_)); # load ivec
&mov ($rounds,&DWP(240,$key));
&set_label("ctr32_one");
if ($inline)
{ &aesni_inline_generate1("enc"); }
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -957,21 +957,21 @@ if ($flavour =~ /64/) { ######## 64-bit code
$arg =~ m/q([0-9]+),\s*\{q([0-9]+)\},\s*q([0-9]+)/o &&
sprintf "vtbl.8 d%d,{q%d},d%d\n\t".
"vtbl.8 d%d,{q%d},d%d", 2*$1,$2,2*$3, 2*$1+1,$2,2*$3+1;
"vtbl.8 d%d,{q%d},d%d", 2*$1,$2,2*$3, 2*$1+1,$2,2*$3+1;
}
sub unvdup32 {
my $arg=shift;
$arg =~ m/q([0-9]+),\s*q([0-9]+)\[([0-3])\]/o &&
sprintf "vdup.32 q%d,d%d[%d]",$1,2*$2+($3>>1),$3&1;
sprintf "vdup.32 q%d,d%d[%d]",$1,2*$2+($3>>1),$3&1;
}
sub unvmov32 {
my $arg=shift;
$arg =~ m/q([0-9]+)\[([0-3])\],(.*)/o &&
sprintf "vmov.32 d%d[%d],%s",2*$1+($2>>1),$2&1,$3;
sprintf "vmov.32 d%d[%d],%s",2*$1+($2>>1),$2&1,$3;
}
foreach(split("\n",$code)) {
+11 -3
View File
@@ -1,4 +1,11 @@
#!/usr/bin/env perl
#! /usr/bin/env perl
# Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
#
# Licensed under the OpenSSL license (the "License"). You may not use
# this file except in compliance with the License. You can obtain a copy
# in the file LICENSE in the source distribution or at
# https://www.openssl.org/source/license.html
# ====================================================================
# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
@@ -84,7 +91,7 @@ my @s=@_[12..15];
sub InBasisChange {
# input in lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
# output in lsb > [b6, b5, b0, b3, b7, b1, b4, b2] < msb
# output in lsb > [b6, b5, b0, b3, b7, b1, b4, b2] < msb
my @b=@_[0..7];
$code.=<<___;
veor @b[2], @b[2], @b[1]
@@ -731,6 +738,7 @@ $code.=<<___;
.thumb
#else
.code 32
# undef __thumb2__
#endif
.type _bsaes_decrypt8,%function
@@ -1357,7 +1365,7 @@ bsaes_cbc_encrypt:
vmov @XMM[4],@XMM[15] @ just in case ensure that IV
vmov @XMM[5],@XMM[0] @ and input are preserved
bl AES_decrypt
vld1.8 {@XMM[0]}, [$fp,:64] @ load result
vld1.8 {@XMM[0]}, [$fp] @ load result
veor @XMM[0], @XMM[0], @XMM[4] @ ^= IV
vmov @XMM[15], @XMM[5] @ @XMM[5] holds input
vst1.8 {@XMM[0]}, [$rounds] @ write output
+91 -74
View File
@@ -41,6 +41,7 @@
# Nehalem(**) 7.63 6.88 +11%
# Atom 17.1 16.4 +4%
# Silvermont - 12.9
# Goldmont - 8.85
#
# (*) Comparison is not completely fair, because "this" is ECB,
# i.e. no extra processing such as counter values calculation
@@ -80,6 +81,7 @@
# Nehalem 7.80
# Atom 17.9
# Silvermont 14.0
# Goldmont 10.2
#
# November 2011.
#
@@ -122,7 +124,7 @@ my @s=@_[12..15];
sub InBasisChange {
# input in lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
# output in lsb > [b6, b5, b0, b3, b7, b1, b4, b2] < msb
# output in lsb > [b6, b5, b0, b3, b7, b1, b4, b2] < msb
my @b=@_[0..7];
$code.=<<___;
pxor @b[6], @b[5]
@@ -372,7 +374,7 @@ $code.=<<___;
pxor @s[0], @t[3]
pxor @s[1], @t[2]
pxor @s[2], @t[1]
pxor @s[3], @t[0]
pxor @s[3], @t[0]
#Inv_GF16 \t0, \t1, \t2, \t3, \s0, \s1, \s2, \s3
@@ -1325,7 +1327,7 @@ $code.=<<___;
cmp %rax, %rbp
jb .Lecb_enc_bzero
lea (%rbp),%rsp # restore %rsp
lea 0x78(%rbp),%rax
___
$code.=<<___ if ($win64);
movaps 0x40(%rbp), %xmm6
@@ -1338,17 +1340,17 @@ $code.=<<___ if ($win64);
movaps 0xb0(%rbp), %xmm13
movaps 0xc0(%rbp), %xmm14
movaps 0xd0(%rbp), %xmm15
lea 0xa0(%rbp), %rsp
lea 0xa0(%rax), %rax
.Lecb_enc_tail:
___
$code.=<<___;
mov 0x48(%rsp), %r15
mov 0x50(%rsp), %r14
mov 0x58(%rsp), %r13
mov 0x60(%rsp), %r12
mov 0x68(%rsp), %rbx
mov 0x70(%rsp), %rax
lea 0x78(%rsp), %rsp
mov %rax, %rbp
mov -48(%rax), %r15
mov -40(%rax), %r14
mov -32(%rax), %r13
mov -24(%rax), %r12
mov -16(%rax), %rbx
mov -8(%rax), %rbp
lea (%rax), %rsp # restore %rsp
.Lecb_enc_epilogue:
ret
.size bsaes_ecb_encrypt_blocks,.-bsaes_ecb_encrypt_blocks
@@ -1527,7 +1529,7 @@ $code.=<<___;
cmp %rax, %rbp
jb .Lecb_dec_bzero
lea (%rbp),%rsp # restore %rsp
lea 0x78(%rbp),%rax
___
$code.=<<___ if ($win64);
movaps 0x40(%rbp), %xmm6
@@ -1540,17 +1542,17 @@ $code.=<<___ if ($win64);
movaps 0xb0(%rbp), %xmm13
movaps 0xc0(%rbp), %xmm14
movaps 0xd0(%rbp), %xmm15
lea 0xa0(%rbp), %rsp
lea 0xa0(%rax), %rax
.Lecb_dec_tail:
___
$code.=<<___;
mov 0x48(%rsp), %r15
mov 0x50(%rsp), %r14
mov 0x58(%rsp), %r13
mov 0x60(%rsp), %r12
mov 0x68(%rsp), %rbx
mov 0x70(%rsp), %rax
lea 0x78(%rsp), %rsp
mov %rax, %rbp
mov -48(%rax), %r15
mov -40(%rax), %r14
mov -32(%rax), %r13
mov -24(%rax), %r12
mov -16(%rax), %rbx
mov -8(%rax), %rbp
lea (%rax), %rsp # restore %rsp
.Lecb_dec_epilogue:
ret
.size bsaes_ecb_decrypt_blocks,.-bsaes_ecb_decrypt_blocks
@@ -1817,7 +1819,7 @@ $code.=<<___;
cmp %rax, %rbp
ja .Lcbc_dec_bzero
lea (%rbp),%rsp # restore %rsp
lea 0x78(%rbp),%rax
___
$code.=<<___ if ($win64);
movaps 0x40(%rbp), %xmm6
@@ -1830,17 +1832,17 @@ $code.=<<___ if ($win64);
movaps 0xb0(%rbp), %xmm13
movaps 0xc0(%rbp), %xmm14
movaps 0xd0(%rbp), %xmm15
lea 0xa0(%rbp), %rsp
lea 0xa0(%rax), %rax
.Lcbc_dec_tail:
___
$code.=<<___;
mov 0x48(%rsp), %r15
mov 0x50(%rsp), %r14
mov 0x58(%rsp), %r13
mov 0x60(%rsp), %r12
mov 0x68(%rsp), %rbx
mov 0x70(%rsp), %rax
lea 0x78(%rsp), %rsp
mov %rax, %rbp
mov -48(%rax), %r15
mov -40(%rax), %r14
mov -32(%rax), %r13
mov -24(%rax), %r12
mov -16(%rax), %rbx
mov -8(%rax), %rbp
lea (%rax), %rsp # restore %rsp
.Lcbc_dec_epilogue:
ret
.size bsaes_cbc_encrypt,.-bsaes_cbc_encrypt
@@ -2049,7 +2051,7 @@ $code.=<<___;
cmp %rax, %rbp
ja .Lctr_enc_bzero
lea (%rbp),%rsp # restore %rsp
lea 0x78(%rbp),%rax
___
$code.=<<___ if ($win64);
movaps 0x40(%rbp), %xmm6
@@ -2062,17 +2064,17 @@ $code.=<<___ if ($win64);
movaps 0xb0(%rbp), %xmm13
movaps 0xc0(%rbp), %xmm14
movaps 0xd0(%rbp), %xmm15
lea 0xa0(%rbp), %rsp
lea 0xa0(%rax), %rax
.Lctr_enc_tail:
___
$code.=<<___;
mov 0x48(%rsp), %r15
mov 0x50(%rsp), %r14
mov 0x58(%rsp), %r13
mov 0x60(%rsp), %r12
mov 0x68(%rsp), %rbx
mov 0x70(%rsp), %rax
lea 0x78(%rsp), %rsp
mov %rax, %rbp
mov -48(%rax), %r15
mov -40(%rax), %r14
mov -32(%rax), %r13
mov -24(%rax), %r12
mov -16(%rax), %rbx
mov -8(%rax), %rbp
lea (%rax), %rsp # restore %rsp
.Lctr_enc_epilogue:
ret
.size bsaes_ctr32_encrypt_blocks,.-bsaes_ctr32_encrypt_blocks
@@ -2439,7 +2441,7 @@ $code.=<<___;
cmp %rax, %rbp
ja .Lxts_enc_bzero
lea (%rbp),%rsp # restore %rsp
lea 0x78(%rbp),%rax
___
$code.=<<___ if ($win64);
movaps 0x40(%rbp), %xmm6
@@ -2452,17 +2454,17 @@ $code.=<<___ if ($win64);
movaps 0xb0(%rbp), %xmm13
movaps 0xc0(%rbp), %xmm14
movaps 0xd0(%rbp), %xmm15
lea 0xa0(%rbp), %rsp
lea 0xa0(%rax), %rax
.Lxts_enc_tail:
___
$code.=<<___;
mov 0x48(%rsp), %r15
mov 0x50(%rsp), %r14
mov 0x58(%rsp), %r13
mov 0x60(%rsp), %r12
mov 0x68(%rsp), %rbx
mov 0x70(%rsp), %rax
lea 0x78(%rsp), %rsp
mov %rax, %rbp
mov -48(%rax), %r15
mov -40(%rax), %r14
mov -32(%rax), %r13
mov -24(%rax), %r12
mov -16(%rax), %rbx
mov -8(%rax), %rbp
lea (%rax), %rsp # restore %rsp
.Lxts_enc_epilogue:
ret
.size bsaes_xts_encrypt,.-bsaes_xts_encrypt
@@ -2846,7 +2848,7 @@ $code.=<<___;
cmp %rax, %rbp
ja .Lxts_dec_bzero
lea (%rbp),%rsp # restore %rsp
lea 0x78(%rbp),%rax
___
$code.=<<___ if ($win64);
movaps 0x40(%rbp), %xmm6
@@ -2859,17 +2861,17 @@ $code.=<<___ if ($win64);
movaps 0xb0(%rbp), %xmm13
movaps 0xc0(%rbp), %xmm14
movaps 0xd0(%rbp), %xmm15
lea 0xa0(%rbp), %rsp
lea 0xa0(%rax), %rax
.Lxts_dec_tail:
___
$code.=<<___;
mov 0x48(%rsp), %r15
mov 0x50(%rsp), %r14
mov 0x58(%rsp), %r13
mov 0x60(%rsp), %r12
mov 0x68(%rsp), %rbx
mov 0x70(%rsp), %rax
lea 0x78(%rsp), %rsp
mov %rax, %rbp
mov -48(%rax), %r15
mov -40(%rax), %r14
mov -32(%rax), %r13
mov -24(%rax), %r12
mov -16(%rax), %rbx
mov -8(%rax), %rbp
lea (%rax), %rsp # restore %rsp
.Lxts_dec_epilogue:
ret
.size bsaes_xts_decrypt,.-bsaes_xts_decrypt
@@ -2965,31 +2967,34 @@ se_handler:
mov 0(%r11),%r10d # HandlerData[0]
lea (%rsi,%r10),%r10 # prologue label
cmp %r10,%rbx # context->Rip<prologue label
jb .Lin_prologue
mov 152($context),%rax # pull context->Rsp
cmp %r10,%rbx # context->Rip<=prologue label
jbe .Lin_prologue
mov 4(%r11),%r10d # HandlerData[1]
lea (%rsi,%r10),%r10 # epilogue label
cmp %r10,%rbx # context->Rip>=epilogue label
jae .Lin_prologue
mov 8(%r11),%r10d # HandlerData[2]
lea (%rsi,%r10),%r10 # epilogue label
cmp %r10,%rbx # context->Rip>=tail label
jae .Lin_tail
mov 160($context),%rax # pull context->Rbp
lea 0x40(%rax),%rsi # %xmm save area
lea 512($context),%rdi # &context.Xmm6
mov \$20,%ecx # 10*sizeof(%xmm0)/sizeof(%rax)
.long 0xa548f3fc # cld; rep movsq
lea 0xa0(%rax),%rax # adjust stack pointer
lea 0xa0+0x78(%rax),%rax # adjust stack pointer
mov 0x70(%rax),%rbp
mov 0x68(%rax),%rbx
mov 0x60(%rax),%r12
mov 0x58(%rax),%r13
mov 0x50(%rax),%r14
mov 0x48(%rax),%r15
lea 0x78(%rax),%rax # adjust stack pointer
.Lin_tail:
mov -48(%rax),%rbp
mov -40(%rax),%rbx
mov -32(%rax),%r12
mov -24(%rax),%r13
mov -16(%rax),%r14
mov -8(%rax),%r15
mov %rbx,144($context) # restore context->Rbx
mov %rbp,160($context) # restore context->Rbp
mov %r12,216($context) # restore context->R12
@@ -3070,28 +3075,40 @@ $code.=<<___ if ($ecb);
.byte 9,0,0,0
.rva se_handler
.rva .Lecb_enc_body,.Lecb_enc_epilogue # HandlerData[]
.rva .Lecb_enc_tail
.long 0
.Lecb_dec_info:
.byte 9,0,0,0
.rva se_handler
.rva .Lecb_dec_body,.Lecb_dec_epilogue # HandlerData[]
.rva .Lecb_dec_tail
.long 0
___
$code.=<<___;
.Lcbc_dec_info:
.byte 9,0,0,0
.rva se_handler
.rva .Lcbc_dec_body,.Lcbc_dec_epilogue # HandlerData[]
.rva .Lcbc_dec_tail
.long 0
.Lctr_enc_info:
.byte 9,0,0,0
.rva se_handler
.rva .Lctr_enc_body,.Lctr_enc_epilogue # HandlerData[]
.rva .Lctr_enc_tail
.long 0
.Lxts_enc_info:
.byte 9,0,0,0
.rva se_handler
.rva .Lxts_enc_body,.Lxts_enc_epilogue # HandlerData[]
.rva .Lxts_enc_tail
.long 0
.Lxts_dec_info:
.byte 9,0,0,0
.rva se_handler
.rva .Lxts_dec_body,.Lxts_dec_epilogue # HandlerData[]
.rva .Lxts_dec_tail
.long 0
___
}
+4 -4
View File
@@ -438,7 +438,7 @@ $k_dsbo=0x2c0; # decryption sbox final output
##
&set_label("schedule_192",16);
&movdqu ("xmm0",&QWP(8,$inp)); # load key part 2 (very unaligned)
&call ("_vpaes_schedule_transform"); # input transform
&call ("_vpaes_schedule_transform"); # input transform
&movdqa ("xmm6","xmm0"); # save short part
&pxor ("xmm4","xmm4"); # clear 4
&movhlps("xmm6","xmm4"); # clobber low side with zeros
@@ -469,7 +469,7 @@ $k_dsbo=0x2c0; # decryption sbox final output
##
&set_label("schedule_256",16);
&movdqu ("xmm0",&QWP(16,$inp)); # load key part 2 (unaligned)
&call ("_vpaes_schedule_transform"); # input transform
&call ("_vpaes_schedule_transform"); # input transform
&mov ($round,7);
&set_label("loop_schedule_256");
@@ -480,7 +480,7 @@ $k_dsbo=0x2c0; # decryption sbox final output
&call ("_vpaes_schedule_round");
&dec ($round);
&jz (&label("schedule_mangle_last"));
&call ("_vpaes_schedule_mangle");
&call ("_vpaes_schedule_mangle");
# low round. swap xmm7 and xmm6
&pshufd ("xmm0","xmm0",0xFF);
@@ -603,7 +603,7 @@ $k_dsbo=0x2c0; # decryption sbox final output
# subbyte
&movdqa ("xmm4",&QWP($k_s0F,$const));
&movdqa ("xmm5",&QWP($k_inv,$const)); # 4 : 1/j
&movdqa ("xmm1","xmm4");
&movdqa ("xmm1","xmm4");
&pandn ("xmm1","xmm0");
&psrld ("xmm1",4); # 1 = i
&pand ("xmm0","xmm4"); # 0 = k
+11 -10
View File
@@ -31,6 +31,7 @@
# Nehalem 29.6/40.3/14.6 10.0/11.8
# Atom 57.3/74.2/32.1 60.9/77.2(***)
# Silvermont 52.7/64.0/19.5 48.8/60.8(***)
# Goldmont 38.9/49.0/17.8 10.6/12.6
#
# (*) "Hyper-threading" in the context refers rather to cache shared
# among multiple cores, than to specifically Intel HTT. As vast
@@ -164,7 +165,7 @@ _vpaes_encrypt_core:
pshufb %xmm1, %xmm0
ret
.size _vpaes_encrypt_core,.-_vpaes_encrypt_core
##
## Decryption core
##
@@ -325,7 +326,7 @@ _vpaes_schedule_core:
##
.Lschedule_128:
mov \$10, %esi
.Loop_schedule_128:
call _vpaes_schedule_round
dec %rsi
@@ -359,7 +360,7 @@ _vpaes_schedule_core:
.Loop_schedule_192:
call _vpaes_schedule_round
palignr \$8,%xmm6,%xmm0
palignr \$8,%xmm6,%xmm0
call _vpaes_schedule_mangle # save key n
call _vpaes_schedule_192_smear
call _vpaes_schedule_mangle # save key n+1
@@ -385,7 +386,7 @@ _vpaes_schedule_core:
movdqu 16(%rdi),%xmm0 # load key part 2 (unaligned)
call _vpaes_schedule_transform # input transform
mov \$7, %esi
.Loop_schedule_256:
call _vpaes_schedule_mangle # output low result
movdqa %xmm0, %xmm6 # save cur_lo in xmm6
@@ -394,7 +395,7 @@ _vpaes_schedule_core:
call _vpaes_schedule_round
dec %rsi
jz .Lschedule_mangle_last
call _vpaes_schedule_mangle
call _vpaes_schedule_mangle
# low round. swap xmm7 and xmm6
pshufd \$0xFF, %xmm0, %xmm0
@@ -402,10 +403,10 @@ _vpaes_schedule_core:
movdqa %xmm6, %xmm7
call _vpaes_schedule_low_round
movdqa %xmm5, %xmm7
jmp .Loop_schedule_256
##
## .aes_schedule_mangle_last
##
@@ -504,9 +505,9 @@ _vpaes_schedule_round:
# rotate
pshufd \$0xFF, %xmm0, %xmm0
palignr \$1, %xmm0, %xmm0
# fall through...
# low round: same as high round, but no rotation and no rcon.
_vpaes_schedule_low_round:
# smear xmm7
@@ -545,7 +546,7 @@ _vpaes_schedule_low_round:
pxor %xmm4, %xmm0 # 0 = sbox output
# add in smeared stuff
pxor %xmm7, %xmm0
pxor %xmm7, %xmm0
movdqa %xmm0, %xmm7
ret
.size _vpaes_schedule_round,.-_vpaes_schedule_round
+11 -9
View File
@@ -53,6 +53,8 @@
#include <openssl/mem.h>
#include "../internal.h"
/* kDefaultIV is the default IV value given in RFC 3394, 2.2.3.1. */
static const uint8_t kDefaultIV[] = {
@@ -73,15 +75,15 @@ int AES_wrap_key(const AES_KEY *key, const uint8_t *iv, uint8_t *out,
iv = kDefaultIV;
}
memmove(out + 8, in, in_len);
OPENSSL_memmove(out + 8, in, in_len);
uint8_t A[AES_BLOCK_SIZE];
memcpy(A, iv, 8);
OPENSSL_memcpy(A, iv, 8);
size_t n = in_len / 8;
for (unsigned j = 0; j < kBound; j++) {
for (size_t i = 1; i <= n; i++) {
memcpy(A + 8, out + 8 * i, 8);
OPENSSL_memcpy(A + 8, out + 8 * i, 8);
AES_encrypt(A, A, key);
uint32_t t = (uint32_t)(n * j + i);
@@ -89,11 +91,11 @@ int AES_wrap_key(const AES_KEY *key, const uint8_t *iv, uint8_t *out,
A[6] ^= (t >> 8) & 0xff;
A[5] ^= (t >> 16) & 0xff;
A[4] ^= (t >> 24) & 0xff;
memcpy(out + 8 * i, A + 8, 8);
OPENSSL_memcpy(out + 8 * i, A + 8, 8);
}
}
memcpy(out, A, 8);
OPENSSL_memcpy(out, A, 8);
return (int)in_len + 8;
}
@@ -110,8 +112,8 @@ int AES_unwrap_key(const AES_KEY *key, const uint8_t *iv, uint8_t *out,
}
uint8_t A[AES_BLOCK_SIZE];
memcpy(A, in, 8);
memmove(out, in + 8, in_len - 8);
OPENSSL_memcpy(A, in, 8);
OPENSSL_memmove(out, in + 8, in_len - 8);
size_t n = (in_len / 8) - 1;
@@ -122,9 +124,9 @@ int AES_unwrap_key(const AES_KEY *key, const uint8_t *iv, uint8_t *out,
A[6] ^= (t >> 8) & 0xff;
A[5] ^= (t >> 16) & 0xff;
A[4] ^= (t >> 24) & 0xff;
memcpy(A + 8, out + 8 * (i - 1), 8);
OPENSSL_memcpy(A + 8, out + 8 * (i - 1), 8);
AES_decrypt(A, A, key);
memcpy(out + 8 * (i - 1), A + 8, 8);
OPENSSL_memcpy(out + 8 * (i - 1), A + 8, 8);
}
}
+1 -13
View File
@@ -35,17 +35,5 @@ add_library(
tasn_new.c
tasn_typ.c
tasn_utl.c
x_bignum.c
x_long.c
time_support.c
)
add_executable(
asn1_test
asn1_test.cc
$<TARGET_OBJECTS:test_support>
)
target_link_libraries(asn1_test crypto)
add_dependencies(all_tests asn1_test)
+6 -3
View File
@@ -61,6 +61,9 @@
#include <openssl/err.h>
#include <openssl/mem.h>
#include "../internal.h"
int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
{
return M_ASN1_BIT_STRING_set(x, d, len);
@@ -115,7 +118,7 @@ int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
*(p++) = (unsigned char)bits;
d = a->data;
memcpy(p, d, len);
OPENSSL_memcpy(p, d, len);
p += len;
if (len > 0)
p[-1] &= (0xff << bits);
@@ -162,7 +165,7 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
memcpy(s, p, (int)len);
OPENSSL_memcpy(s, p, (int)len);
s[len - 1] &= (0xff << padding);
p += len;
} else
@@ -215,7 +218,7 @@ int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
return 0;
}
if (w + 1 - a->length > 0)
memset(c + a->length, 0, w + 1 - a->length);
OPENSSL_memset(c + a->length, 0, w + 1 - a->length);
a->data = c;
a->length = w + 1;
}
+4 -1
View File
@@ -61,6 +61,9 @@
#include <openssl/err.h>
#include <openssl/mem.h>
#include "../internal.h"
/*
* Code for ENUMERATED type: identical to INTEGER apart from a different tag.
* for comments on encoding see a_int.c
@@ -79,7 +82,7 @@ int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
OPENSSL_free(a->data);
if ((a->data =
(unsigned char *)OPENSSL_malloc(sizeof(long) + 1)) != NULL)
memset((char *)a->data, 0, sizeof(long) + 1);
OPENSSL_memset((char *)a->data, 0, sizeof(long) + 1);
}
if (a->data == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
-1
View File
@@ -61,7 +61,6 @@
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/time_support.h>
#include "asn1_locl.h"
+7 -4
View File
@@ -61,6 +61,9 @@
#include <openssl/err.h>
#include <openssl/mem.h>
#include "../internal.h"
ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x)
{
return M_ASN1_INTEGER_dup(x);
@@ -157,7 +160,7 @@ int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
if (a->length == 0)
*(p++) = 0;
else if (!neg)
memcpy(p, a->data, (unsigned int)a->length);
OPENSSL_memcpy(p, a->data, (unsigned int)a->length);
else {
/* Begin at the end of the encoding */
n = a->data + a->length - 1;
@@ -254,7 +257,7 @@ ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
p++;
len--;
}
memcpy(s, p, (int)len);
OPENSSL_memcpy(s, p, (int)len);
}
if (ret->data != NULL)
@@ -322,7 +325,7 @@ ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
p++;
len--;
}
memcpy(s, p, (int)len);
OPENSSL_memcpy(s, p, (int)len);
p += len;
}
@@ -354,7 +357,7 @@ int ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
OPENSSL_free(a->data);
if ((a->data =
(unsigned char *)OPENSSL_malloc(sizeof(long) + 1)) != NULL)
memset((char *)a->data, 0, sizeof(long) + 1);
OPENSSL_memset((char *)a->data, 0, sizeof(long) + 1);
}
if (a->data == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
+5 -2
View File
@@ -63,6 +63,9 @@
#include <openssl/mem.h>
#include <openssl/obj.h>
#include "../internal.h"
int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
{
unsigned char *p;
@@ -77,7 +80,7 @@ int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
p = *pp;
ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
memcpy(p, a->data, a->length);
OPENSSL_memcpy(p, a->data, a->length);
p += a->length;
*pp = p;
@@ -321,7 +324,7 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
}
ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA;
}
memcpy(data, p, length);
OPENSSL_memcpy(data, p, length);
/* reattach data to object, after which it remains const */
ret->data = data;
ret->length = length;
+17 -10
View File
@@ -63,7 +63,6 @@
#include <openssl/buf.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/time_support.h>
#include "asn1_locl.h"
@@ -115,7 +114,7 @@ int ASN1_TIME_check(ASN1_TIME *t)
ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t,
ASN1_GENERALIZEDTIME **out)
{
ASN1_GENERALIZEDTIME *ret;
ASN1_GENERALIZEDTIME *ret = NULL;
char *str;
int newlen;
@@ -124,22 +123,21 @@ ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t,
if (!out || !*out) {
if (!(ret = ASN1_GENERALIZEDTIME_new()))
return NULL;
if (out)
*out = ret;
} else
goto err;
} else {
ret = *out;
}
/* If already GeneralizedTime just copy across */
if (t->type == V_ASN1_GENERALIZEDTIME) {
if (!ASN1_STRING_set(ret, t->data, t->length))
return NULL;
return ret;
goto err;
goto done;
}
/* grow the string */
if (!ASN1_STRING_set(ret, NULL, t->length + 2))
return NULL;
goto err;
/* ASN1_STRING_set() allocated 'len + 1' bytes. */
newlen = t->length + 2 + 1;
str = (char *)ret->data;
@@ -151,9 +149,18 @@ ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t,
BUF_strlcat(str, (char *)t->data, newlen);
return ret;
done:
if (out != NULL && *out == NULL)
*out = ret;
return ret;
err:
if (out == NULL || *out != ret)
ASN1_GENERALIZEDTIME_free(ret);
return NULL;
}
int ASN1_TIME_set_string(ASN1_TIME *s, const char *str)
{
ASN1_TIME t;
+1 -2
View File
@@ -61,7 +61,6 @@
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/time_support.h>
#include "asn1_locl.h"
@@ -270,7 +269,7 @@ time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s)
struct tm tm;
int offset;
memset(&tm, '\0', sizeof tm);
OPENSSL_memset(&tm, '\0', sizeof tm);
# define g2(p) (((p)[0]-'0')*10+(p)[1]-'0')
tm.tm_year = g2(s->data);
+5 -2
View File
@@ -63,6 +63,9 @@
#include <openssl/err.h>
#include <openssl/mem.h>
#include "../internal.h"
/* Cross-module errors from crypto/x509/i2d_pr.c. */
OPENSSL_DECLARE_ERROR_REASON(ASN1, UNSUPPORTED_PUBLIC_KEY_TYPE)
@@ -401,7 +404,7 @@ int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
}
str->length = len;
if (data != NULL) {
memcpy(str->data, data, len);
OPENSSL_memcpy(str->data, data, len);
/* an allowance for strings :-) */
str->data[len] = '\0';
}
@@ -452,7 +455,7 @@ int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
i = (a->length - b->length);
if (i == 0) {
i = memcmp(a->data, b->data, a->length);
i = OPENSSL_memcmp(a->data, b->data, a->length);
if (i == 0)
return (a->type - b->type);
else
+35
View File
@@ -57,7 +57,42 @@
*
*/
#ifndef OPENSSL_HEADER_ASN1_ASN1_LOCL_H
#define OPENSSL_HEADER_ASN1_ASN1_LOCL_H
#include <time.h>
#include <openssl/asn1.h>
#if defined(__cplusplus)
extern "C" {
#endif
/* Wrapper functions for time functions. */
/* OPENSSL_gmtime wraps |gmtime_r|. See the manual page for that function. */
struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result);
/* OPENSSL_gmtime_adj updates |tm| by adding |offset_day| days and |offset_sec|
* seconds. */
int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, long offset_sec);
/* OPENSSL_gmtime_diff calculates the difference between |from| and |to| and
* outputs the difference as a number of days and seconds in |*out_days| and
* |*out_secs|. */
int OPENSSL_gmtime_diff(int *out_days, int *out_secs, const struct tm *from,
const struct tm *to);
/* Internal ASN1 structures and functions: not for application use */
int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d);
int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d);
#if defined(__cplusplus)
} /* extern C */
#endif
#endif /* OPENSSL_HEADER_ASN1_ASN1_LOCL_H */
+12 -29
View File
@@ -14,10 +14,13 @@
#include <stdio.h>
#include <gtest/gtest.h>
#include <openssl/asn1.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include "../test/test_util.h"
// kTag128 is an ASN.1 structure with a universal tag with number 128.
static const uint8_t kTag128[] = {
@@ -38,42 +41,22 @@ static const uint8_t kTagOverflow[] = {
0x1f, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x01, 0x00,
};
static bool TestLargeTags() {
TEST(ASN1Test, LargeTags) {
const uint8_t *p = kTag258;
bssl::UniquePtr<ASN1_TYPE> obj(d2i_ASN1_TYPE(NULL, &p, sizeof(kTag258)));
if (obj) {
fprintf(stderr, "Parsed value with illegal tag (type = %d).\n", obj->type);
return false;
}
EXPECT_FALSE(obj) << "Parsed value with illegal tag" << obj->type;
ERR_clear_error();
p = kTagOverflow;
obj.reset(d2i_ASN1_TYPE(NULL, &p, sizeof(kTagOverflow)));
if (obj) {
fprintf(stderr, "Parsed value with tag overflow (type = %d).\n", obj->type);
return false;
}
EXPECT_FALSE(obj) << "Parsed value with tag overflow" << obj->type;
ERR_clear_error();
p = kTag128;
obj.reset(d2i_ASN1_TYPE(NULL, &p, sizeof(kTag128)));
if (!obj || obj->type != 128 || obj->value.asn1_string->length != 1 ||
obj->value.asn1_string->data[0] != 0) {
fprintf(stderr, "Failed to parse value with tag 128.\n");
ERR_print_errors_fp(stderr);
return false;
}
return true;
}
int main() {
CRYPTO_library_init();
if (!TestLargeTags()) {
return 1;
}
printf("PASS\n");
return 0;
ASSERT_TRUE(obj);
EXPECT_EQ(128, obj->type);
const uint8_t kZero = 0;
EXPECT_EQ(Bytes(&kZero, 1), Bytes(obj->value.asn1_string->data,
obj->value.asn1_string->length));
}
+3 -1
View File
@@ -180,6 +180,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
int ret = 0;
ASN1_VALUE **pchptr, *ptmpval;
int combine = aclass & ASN1_TFLG_COMBINE;
aclass &= ~ASN1_TFLG_COMBINE;
if (!pval)
return 0;
if (aux && aux->asn1_cb)
@@ -667,6 +668,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
}
len -= p - q;
if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, skfield)) {
ASN1_item_ex_free(&skfield, ASN1_ITEM_ptr(tt->item));
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -1108,7 +1110,7 @@ static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen)
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return 0;
}
memcpy(buf->data + len, *p, plen);
OPENSSL_memcpy(buf->data + len, *p, plen);
}
*p += plen;
return 1;
+6 -3
View File
@@ -62,6 +62,9 @@
#include <openssl/asn1t.h>
#include <openssl/mem.h>
#include "../internal.h"
static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
const ASN1_ITEM *it, int tag, int aclass);
static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
@@ -415,7 +418,7 @@ static int der_cmp(const void *a, const void *b)
const DER_ENC *d1 = a, *d2 = b;
int cmplen, i;
cmplen = (d1->length < d2->length) ? d1->length : d2->length;
i = memcmp(d1->data, d2->data, cmplen);
i = OPENSSL_memcmp(d1->data, d2->data, cmplen);
if (i)
return i;
return d1->length - d2->length;
@@ -470,7 +473,7 @@ static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
/* Output sorted DER encoding */
p = *out;
for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
memcpy(p, tder->data, tder->length);
OPENSSL_memcpy(p, tder->data, tder->length);
p += tder->length;
}
*out = p;
@@ -660,6 +663,6 @@ int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
}
if (cout && len)
memcpy(cout, cont, len);
OPENSSL_memcpy(cout, cont, len);
return len;
}
+12 -7
View File
@@ -63,6 +63,9 @@
#include <openssl/mem.h>
#include <openssl/obj.h>
#include "../internal.h"
static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
int combine);
static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
@@ -153,11 +156,11 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
*pval = OPENSSL_malloc(it->size);
if (!*pval)
goto memerr;
memset(*pval, 0, it->size);
OPENSSL_memset(*pval, 0, it->size);
}
asn1_set_choice_selector(pval, -1, it);
if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
goto auxerr;
goto auxerr2;
break;
case ASN1_ITYPE_NDEF_SEQUENCE:
@@ -178,17 +181,17 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
*pval = OPENSSL_malloc(it->size);
if (!*pval)
goto memerr;
memset(*pval, 0, it->size);
OPENSSL_memset(*pval, 0, it->size);
asn1_refcount_set_one(pval, it);
asn1_enc_init(pval, it);
}
for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
pseqval = asn1_get_field_ptr(pval, tt);
if (!ASN1_template_new(pseqval, tt))
goto memerr;
goto memerr2;
}
if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
goto auxerr;
goto auxerr2;
break;
}
#ifdef CRYPTO_MDEBUG
@@ -197,18 +200,20 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
#endif
return 1;
memerr2:
ASN1_item_ex_free(pval, it);
memerr:
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
ASN1_item_ex_free(pval, it);
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_pop_info();
#endif
return 0;
auxerr2:
ASN1_item_ex_free(pval, it);
auxerr:
OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
ASN1_item_ex_free(pval, it);
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_pop_info();
+2 -2
View File
@@ -178,7 +178,7 @@ int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen,
if (!enc->enc) {
return 0;
}
memcpy(enc->enc, in, inlen);
OPENSSL_memcpy(enc->enc, in, inlen);
}
enc->len = inlen;
@@ -195,7 +195,7 @@ int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval,
return 0;
}
if (out) {
memcpy(*out, enc->enc, enc->len);
OPENSSL_memcpy(*out, enc->enc, enc->len);
*out += enc->len;
}
if (len) {
@@ -59,7 +59,7 @@
#define _POSIX_C_SOURCE 201410L /* for gmtime_r */
#endif
#include <openssl/time_support.h>
#include "asn1_locl.h"
#include <time.h>
-197
View File
@@ -1,197 +0,0 @@
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
#include <openssl/asn1.h>
#include <string.h>
#include <openssl/asn1t.h>
#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/mem.h>
/*
* Custom primitive type for long handling. This converts between an
* ASN1_INTEGER and a long directly.
*/
static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
const ASN1_ITEM *it);
static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
int utype, char *free_cont, const ASN1_ITEM *it);
static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
int indent, const ASN1_PCTX *pctx);
static const ASN1_PRIMITIVE_FUNCS long_pf = {
NULL, 0,
long_new,
long_free,
long_free, /* Clear should set to initial value */
long_c2i,
long_i2c,
long_print
};
ASN1_ITEM_start(LONG)
ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, ASN1_LONG_UNDEF, "LONG"
ASN1_ITEM_end(LONG)
ASN1_ITEM_start(ZLONG)
ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, 0, "ZLONG"
ASN1_ITEM_end(ZLONG)
static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
*(long *)pval = it->size;
return 1;
}
static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
*(long *)pval = it->size;
}
static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
const ASN1_ITEM *it)
{
long ltmp;
unsigned long utmp;
int clen, pad, i;
/* this exists to bypass broken gcc optimization */
char *cp = (char *)pval;
/* use memcpy, because we may not be long aligned */
memcpy(&ltmp, cp, sizeof(long));
if (ltmp == it->size)
return -1;
/*
* Convert the long to positive: we subtract one if negative so we can
* cleanly handle the padding if only the MSB of the leading octet is
* set.
*/
if (ltmp < 0)
utmp = -ltmp - 1;
else
utmp = ltmp;
clen = BN_num_bits_word(utmp);
/* If MSB of leading octet set we need to pad */
if (!(clen & 0x7))
pad = 1;
else
pad = 0;
/* Convert number of bits to number of octets */
clen = (clen + 7) >> 3;
if (cont) {
if (pad)
*cont++ = (ltmp < 0) ? 0xff : 0;
for (i = clen - 1; i >= 0; i--) {
cont[i] = (unsigned char)(utmp & 0xff);
if (ltmp < 0)
cont[i] ^= 0xff;
utmp >>= 8;
}
}
return clen + pad;
}
static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
int utype, char *free_cont, const ASN1_ITEM *it)
{
int neg, i;
long ltmp;
unsigned long utmp = 0;
char *cp = (char *)pval;
if (len > (int)sizeof(long)) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
return 0;
}
/* Is it negative? */
if (len && (cont[0] & 0x80))
neg = 1;
else
neg = 0;
utmp = 0;
for (i = 0; i < len; i++) {
utmp <<= 8;
if (neg)
utmp |= cont[i] ^ 0xff;
else
utmp |= cont[i];
}
ltmp = (long)utmp;
if (neg) {
ltmp++;
ltmp = -ltmp;
}
if (ltmp == it->size) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
return 0;
}
memcpy(cp, &ltmp, sizeof(long));
return 1;
}
static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
int indent, const ASN1_PCTX *pctx)
{
return BIO_printf(out, "%ld\n", *(long *)pval);
}
+7 -5
View File
@@ -62,6 +62,8 @@
#include <openssl/type_check.h>
#include "../internal.h"
/* Encoding. */
@@ -95,7 +97,7 @@ int EVP_EncodedLength(size_t *out_len, size_t len) {
}
void EVP_EncodeInit(EVP_ENCODE_CTX *ctx) {
memset(ctx, 0, sizeof(EVP_ENCODE_CTX));
OPENSSL_memset(ctx, 0, sizeof(EVP_ENCODE_CTX));
}
void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
@@ -110,14 +112,14 @@ void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
assert(ctx->data_used < sizeof(ctx->data));
if (sizeof(ctx->data) - ctx->data_used > in_len) {
memcpy(&ctx->data[ctx->data_used], in, in_len);
OPENSSL_memcpy(&ctx->data[ctx->data_used], in, in_len);
ctx->data_used += (unsigned)in_len;
return;
}
if (ctx->data_used != 0) {
const size_t todo = sizeof(ctx->data) - ctx->data_used;
memcpy(&ctx->data[ctx->data_used], in, todo);
OPENSSL_memcpy(&ctx->data[ctx->data_used], in, todo);
in += todo;
in_len -= todo;
@@ -149,7 +151,7 @@ void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
}
if (in_len != 0) {
memcpy(ctx->data, in, in_len);
OPENSSL_memcpy(ctx->data, in, in_len);
}
ctx->data_used = (unsigned)in_len;
@@ -224,7 +226,7 @@ int EVP_DecodedLength(size_t *out_len, size_t len) {
}
void EVP_DecodeInit(EVP_ENCODE_CTX *ctx) {
memset(ctx, 0, sizeof(EVP_ENCODE_CTX));
OPENSSL_memset(ctx, 0, sizeof(EVP_ENCODE_CTX));
}
/* kBase64ASCIIToBinData maps characters (c < 128) to their base64 value, or
+8 -6
View File
@@ -136,7 +136,7 @@ static bool TestEncodeBlock() {
std::string encoded(RemoveNewlines(t->encoded));
if (len != encoded.size() ||
memcmp(out, encoded.data(), len) != 0) {
OPENSSL_memcmp(out, encoded.data(), len) != 0) {
fprintf(stderr, "encode(\"%s\") = \"%.*s\", want \"%s\"\n",
t->decoded, (int)len, (const char*)out, encoded.c_str());
return false;
@@ -178,7 +178,7 @@ static bool TestDecodeBase64() {
}
if (len != strlen(t->decoded) ||
memcmp(out, t->decoded, len) != 0) {
OPENSSL_memcmp(out, t->decoded, len) != 0) {
fprintf(stderr, "decode(\"%s\") = \"%.*s\", want \"%s\"\n",
encoded.c_str(), (int)len, (const char*)out, t->decoded);
return false;
@@ -217,7 +217,7 @@ static bool TestDecodeBlock() {
ret -= 3 - (expected_len % 3);
}
if (static_cast<size_t>(ret) != strlen(t->decoded) ||
memcmp(out, t->decoded, ret) != 0) {
OPENSSL_memcmp(out, t->decoded, ret) != 0) {
fprintf(stderr, "decode(\"%s\") = \"%.*s\", want \"%s\"\n",
t->encoded, ret, (const char*)out, t->decoded);
return false;
@@ -258,7 +258,8 @@ static bool TestEncodeDecode() {
EVP_EncodeFinal(&ctx, out + total, &out_len);
total += out_len;
if (total != strlen(t->encoded) || memcmp(out, t->encoded, total) != 0) {
if (total != strlen(t->encoded) ||
OPENSSL_memcmp(out, t->encoded, total) != 0) {
fprintf(stderr, "#%u: EVP_EncodeUpdate produced different output: '%s' (%u)\n",
test_num, out, static_cast<unsigned>(total));
return false;
@@ -287,7 +288,8 @@ static bool TestEncodeDecode() {
fprintf(stderr, "#%u: EVP_DecodeUpdate failed\n", test_num);
return false;
}
if (total != decoded_len || memcmp(out, t->decoded, decoded_len)) {
if (total != decoded_len ||
OPENSSL_memcmp(out, t->decoded, decoded_len)) {
fprintf(stderr, "#%u: EVP_DecodeUpdate produced incorrect output\n",
test_num);
return false;
@@ -368,7 +370,7 @@ static bool TestDecodeUpdateStreaming() {
out_len += bytes_written;
if (out_len != strlen(t->decoded) ||
memcmp(out.data(), t->decoded, out_len) != 0) {
OPENSSL_memcmp(out.data(), t->decoded, out_len) != 0) {
fprintf(stderr, "#%u: incorrect output\n", test_num);
return 0;
}
-15
View File
@@ -7,7 +7,6 @@ add_library(
bio.c
bio_mem.c
buffer.c
connect.c
fd.c
file.c
@@ -17,17 +16,3 @@ add_library(
socket.c
socket_helper.c
)
add_executable(
bio_test
bio_test.cc
$<TARGET_OBJECTS:test_support>
)
target_link_libraries(bio_test crypto)
if (WIN32)
target_link_libraries(bio_test ws2_32)
endif()
add_dependencies(all_tests bio_test)
+9 -3
View File
@@ -75,7 +75,7 @@ BIO *BIO_new(const BIO_METHOD *method) {
return NULL;
}
memset(ret, 0, sizeof(BIO));
OPENSSL_memset(ret, 0, sizeof(BIO));
ret->method = method;
ret->shutdown = 1;
ret->references = 1;
@@ -488,7 +488,7 @@ static int bio_read_all(BIO *bio, uint8_t **out, size_t *out_len,
if (*out == NULL) {
return 0;
}
memcpy(*out, prefix, prefix_len);
OPENSSL_memcpy(*out, prefix, prefix_len);
size_t done = prefix_len;
for (;;) {
@@ -595,7 +595,7 @@ int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len, size_t max_len) {
if (*out == NULL) {
return 0;
}
memcpy(*out, header, header_len);
OPENSSL_memcpy(*out, header, header_len);
if (BIO_read(bio, (*out) + header_len, len - header_len) !=
(int) (len - header_len)) {
OPENSSL_free(*out);
@@ -604,3 +604,9 @@ int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len, size_t max_len) {
return 1;
}
void BIO_set_retry_special(BIO *bio) {
bio->flags |= BIO_FLAGS_READ | BIO_FLAGS_IO_SPECIAL;
}
int BIO_set_write_buffer_size(BIO *bio, int buffer_size) { return 0; }
+12 -10
View File
@@ -63,6 +63,8 @@
#include <openssl/err.h>
#include <openssl/mem.h>
#include "../internal.h"
BIO *BIO_new_mem_buf(const void *buf, int len) {
BIO *ret;
@@ -144,12 +146,12 @@ static int mem_read(BIO *bio, char *out, int outl) {
}
if (ret > 0) {
memcpy(out, b->data, ret);
OPENSSL_memcpy(out, b->data, ret);
b->length -= ret;
if (bio->flags & BIO_FLAGS_MEM_RDONLY) {
b->data += ret;
} else {
memmove(b->data, &b->data[ret], b->length);
OPENSSL_memmove(b->data, &b->data[ret], b->length);
}
} else if (b->length == 0) {
ret = bio->num;
@@ -180,17 +182,13 @@ static int mem_write(BIO *bio, const char *in, int inl) {
if (BUF_MEM_grow_clean(b, blen + inl) != ((size_t) blen) + inl) {
goto err;
}
memcpy(&b->data[blen], in, inl);
OPENSSL_memcpy(&b->data[blen], in, inl);
ret = inl;
err:
return ret;
}
static int mem_puts(BIO *bp, const char *str) {
return mem_write(bp, str, strlen(str));
}
static int mem_gets(BIO *bio, char *buf, int size) {
int i, j;
char *p;
@@ -240,7 +238,7 @@ static long mem_ctrl(BIO *bio, int cmd, long num, void *ptr) {
b->data -= b->max - b->length;
b->length = b->max;
} else {
memset(b->data, 0, b->max);
OPENSSL_memset(b->data, 0, b->max);
b->length = 0;
}
}
@@ -293,8 +291,12 @@ static long mem_ctrl(BIO *bio, int cmd, long num, void *ptr) {
}
static const BIO_METHOD mem_method = {
BIO_TYPE_MEM, "memory buffer", mem_write, mem_read, mem_puts,
mem_gets, mem_ctrl, mem_new, mem_free, NULL, };
BIO_TYPE_MEM, "memory buffer",
mem_write, mem_read,
NULL /* puts */, mem_gets,
mem_ctrl, mem_new,
mem_free, NULL /* callback_ctrl */,
};
const BIO_METHOD *BIO_s_mem(void) { return &mem_method; }
+208 -335
View File
@@ -16,7 +16,18 @@
#define _POSIX_C_SOURCE 201410L
#endif
#include <openssl/base.h>
#include <algorithm>
#include <string>
#include <gtest/gtest.h>
#include <openssl/bio.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include "../internal.h"
#include "../test/test_util.h"
#if !defined(OPENSSL_WINDOWS)
#include <arpa/inet.h>
@@ -33,27 +44,15 @@ OPENSSL_MSVC_PRAGMA(warning(push, 3))
OPENSSL_MSVC_PRAGMA(warning(pop))
#endif
#include <openssl/bio.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <algorithm>
#include "../internal.h"
#if !defined(OPENSSL_WINDOWS)
static int closesocket(int sock) {
return close(sock);
}
static void PrintSocketError(const char *func) {
perror(func);
}
static int closesocket(int sock) { return close(sock); }
static std::string LastSocketError() { return strerror(errno); }
#else
static void PrintSocketError(const char *func) {
fprintf(stderr, "%s: %d\n", func, WSAGetLastError());
static std::string LastSocketError() {
char buf[DECIMAL_SIZE(int) + 1];
BIO_snprintf(buf, sizeof(buf), "%d", WSAGetLastError());
return buf;
}
#endif
@@ -68,372 +67,246 @@ class ScopedSocket {
const int sock_;
};
static bool TestSocketConnect() {
TEST(BIOTest, SocketConnect) {
static const char kTestMessage[] = "test";
// Set up a listening socket on localhost.
int listening_sock = socket(AF_INET, SOCK_STREAM, 0);
if (listening_sock == -1) {
PrintSocketError("socket");
return false;
}
ASSERT_NE(-1, listening_sock) << LastSocketError();
ScopedSocket listening_sock_closer(listening_sock);
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
OPENSSL_memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
if (!inet_pton(AF_INET, "127.0.0.1", &sin.sin_addr)) {
PrintSocketError("inet_pton");
return false;
}
if (bind(listening_sock, (struct sockaddr *)&sin, sizeof(sin)) != 0) {
PrintSocketError("bind");
return false;
}
if (listen(listening_sock, 1)) {
PrintSocketError("listen");
return false;
}
ASSERT_EQ(1, inet_pton(AF_INET, "127.0.0.1", &sin.sin_addr))
<< LastSocketError();
ASSERT_EQ(0, bind(listening_sock, (struct sockaddr *)&sin, sizeof(sin)))
<< LastSocketError();
ASSERT_EQ(0, listen(listening_sock, 1)) << LastSocketError();
socklen_t sockaddr_len = sizeof(sin);
if (getsockname(listening_sock, (struct sockaddr *)&sin, &sockaddr_len) ||
sockaddr_len != sizeof(sin)) {
PrintSocketError("getsockname");
return false;
}
ASSERT_EQ(0,
getsockname(listening_sock, (struct sockaddr *)&sin, &sockaddr_len))
<< LastSocketError();
// The Android NDK, contrary to POSIX, makes |socklen_t| signed.
ASSERT_EQ(sizeof(sin), static_cast<size_t>(sockaddr_len));
// Connect to it with a connect BIO.
char hostname[80];
BIO_snprintf(hostname, sizeof(hostname), "%s:%d", "127.0.0.1",
ntohs(sin.sin_port));
bssl::UniquePtr<BIO> bio(BIO_new_connect(hostname));
if (!bio) {
fprintf(stderr, "BIO_new_connect failed.\n");
return false;
}
ASSERT_TRUE(bio);
if (BIO_write(bio.get(), kTestMessage, sizeof(kTestMessage)) !=
sizeof(kTestMessage)) {
fprintf(stderr, "BIO_write failed.\n");
ERR_print_errors_fp(stderr);
return false;
}
// Write a test message to the BIO.
ASSERT_EQ(static_cast<int>(sizeof(kTestMessage)),
BIO_write(bio.get(), kTestMessage, sizeof(kTestMessage)));
// Accept the socket.
int sock = accept(listening_sock, (struct sockaddr *) &sin, &sockaddr_len);
if (sock == -1) {
PrintSocketError("accept");
return false;
}
ASSERT_NE(-1, sock) << LastSocketError();
ScopedSocket sock_closer(sock);
char buf[5];
if (recv(sock, buf, sizeof(buf), 0) != sizeof(kTestMessage)) {
PrintSocketError("read");
return false;
}
if (memcmp(buf, kTestMessage, sizeof(kTestMessage))) {
return false;
}
return true;
// Check the same message is read back out.
char buf[sizeof(kTestMessage)];
ASSERT_EQ(static_cast<int>(sizeof(kTestMessage)),
recv(sock, buf, sizeof(buf), 0))
<< LastSocketError();
EXPECT_EQ(Bytes(kTestMessage, sizeof(kTestMessage)), Bytes(buf, sizeof(buf)));
}
// BioReadZeroCopyWrapper is a wrapper around the zero-copy APIs to make
// testing easier.
static size_t BioReadZeroCopyWrapper(BIO *bio, uint8_t *data, size_t len) {
uint8_t *read_buf;
size_t read_buf_offset;
size_t available_bytes;
size_t len_read = 0;
do {
if (!BIO_zero_copy_get_read_buf(bio, &read_buf, &read_buf_offset,
&available_bytes)) {
return 0;
}
available_bytes = std::min(available_bytes, len - len_read);
memmove(data + len_read, read_buf + read_buf_offset, available_bytes);
BIO_zero_copy_get_read_buf_done(bio, available_bytes);
len_read += available_bytes;
} while (len - len_read > 0 && available_bytes > 0);
return len_read;
}
// BioWriteZeroCopyWrapper is a wrapper around the zero-copy APIs to make
// testing easier.
static size_t BioWriteZeroCopyWrapper(BIO *bio, const uint8_t *data,
size_t len) {
uint8_t *write_buf;
size_t write_buf_offset;
size_t available_bytes;
size_t len_written = 0;
do {
if (!BIO_zero_copy_get_write_buf(bio, &write_buf, &write_buf_offset,
&available_bytes)) {
return 0;
}
available_bytes = std::min(available_bytes, len - len_written);
memmove(write_buf + write_buf_offset, data + len_written, available_bytes);
BIO_zero_copy_get_write_buf_done(bio, available_bytes);
len_written += available_bytes;
} while (len - len_written > 0 && available_bytes > 0);
return len_written;
}
static bool TestZeroCopyBioPairs() {
// Test read and write, especially triggering the ring buffer wrap-around.
uint8_t bio1_application_send_buffer[1024];
uint8_t bio2_application_recv_buffer[1024];
const size_t kLengths[] = {254, 255, 256, 257, 510, 511, 512, 513};
// These trigger ring buffer wrap around.
const size_t kPartialLengths[] = {0, 1, 2, 3, 128, 255, 256, 257, 511, 512};
static const size_t kBufferSize = 512;
srand(1);
for (size_t i = 0; i < sizeof(bio1_application_send_buffer); i++) {
bio1_application_send_buffer[i] = rand() & 255;
}
// Transfer bytes from bio1_application_send_buffer to
// bio2_application_recv_buffer in various ways.
for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kLengths); i++) {
for (size_t j = 0; j < OPENSSL_ARRAY_SIZE(kPartialLengths); j++) {
size_t total_write = 0;
size_t total_read = 0;
BIO *bio1, *bio2;
if (!BIO_new_bio_pair(&bio1, kBufferSize, &bio2, kBufferSize)) {
return false;
}
bssl::UniquePtr<BIO> bio1_scoper(bio1);
bssl::UniquePtr<BIO> bio2_scoper(bio2);
total_write += BioWriteZeroCopyWrapper(
bio1, bio1_application_send_buffer, kLengths[i]);
// This tests interleaved read/write calls. Do a read between zero copy
// write calls.
uint8_t *write_buf;
size_t write_buf_offset;
size_t available_bytes;
if (!BIO_zero_copy_get_write_buf(bio1, &write_buf, &write_buf_offset,
&available_bytes)) {
return false;
}
// Free kPartialLengths[j] bytes in the beginning of bio1 write buffer.
// This enables ring buffer wrap around for the next write.
total_read += BIO_read(bio2, bio2_application_recv_buffer + total_read,
kPartialLengths[j]);
size_t interleaved_write_len = std::min(kPartialLengths[j],
available_bytes);
// Write the data for the interleaved write call. If the buffer becomes
// empty after a read, the write offset is normally set to 0. Check that
// this does not happen for interleaved read/write and that
// |write_buf_offset| is still valid.
memcpy(write_buf + write_buf_offset,
bio1_application_send_buffer + total_write, interleaved_write_len);
if (BIO_zero_copy_get_write_buf_done(bio1, interleaved_write_len)) {
total_write += interleaved_write_len;
}
// Do another write in case |write_buf_offset| was wrapped.
total_write += BioWriteZeroCopyWrapper(
bio1, bio1_application_send_buffer + total_write,
kPartialLengths[j] - interleaved_write_len);
// Drain the rest.
size_t bytes_left = BIO_pending(bio2);
total_read += BioReadZeroCopyWrapper(
bio2, bio2_application_recv_buffer + total_read, bytes_left);
if (total_read != total_write) {
fprintf(stderr, "Lengths not equal in round (%u, %u)\n", (unsigned)i,
(unsigned)j);
return false;
}
if (total_read > kLengths[i] + kPartialLengths[j]) {
fprintf(stderr, "Bad lengths in round (%u, %u)\n", (unsigned)i,
(unsigned)j);
return false;
}
if (memcmp(bio1_application_send_buffer, bio2_application_recv_buffer,
total_read) != 0) {
fprintf(stderr, "Buffers not equal in round (%u, %u)\n", (unsigned)i,
(unsigned)j);
return false;
}
}
}
return true;
}
static bool TestPrintf() {
TEST(BIOTest, Printf) {
// Test a short output, a very long one, and various sizes around
// 256 (the size of the buffer) to ensure edge cases are correct.
static const size_t kLengths[] = { 5, 250, 251, 252, 253, 254, 1023 };
static const size_t kLengths[] = {5, 250, 251, 252, 253, 254, 1023};
bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
if (!bio) {
fprintf(stderr, "BIO_new failed\n");
return false;
}
ASSERT_TRUE(bio);
for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kLengths); i++) {
char string[1024];
if (kLengths[i] >= sizeof(string)) {
fprintf(stderr, "Bad test string length\n");
return false;
}
memset(string, 'a', sizeof(string));
string[kLengths[i]] = '\0';
for (size_t length : kLengths) {
SCOPED_TRACE(length);
std::string in(length, 'a');
int ret = BIO_printf(bio.get(), "test %s", in.c_str());
ASSERT_GE(ret, 0);
EXPECT_EQ(5 + length, static_cast<size_t>(ret));
int ret = BIO_printf(bio.get(), "test %s", string);
if (ret < 0 || static_cast<size_t>(ret) != 5 + kLengths[i]) {
fprintf(stderr, "BIO_printf failed: %d\n", ret);
return false;
}
const uint8_t *contents;
size_t len;
if (!BIO_mem_contents(bio.get(), &contents, &len)) {
fprintf(stderr, "BIO_mem_contents failed\n");
return false;
}
if (len != 5 + kLengths[i] ||
strncmp((const char *)contents, "test ", 5) != 0 ||
strncmp((const char *)contents + 5, string, kLengths[i]) != 0) {
fprintf(stderr, "Contents did not match: %.*s\n", (int)len, contents);
return false;
}
ASSERT_TRUE(BIO_mem_contents(bio.get(), &contents, &len));
EXPECT_EQ("test " + in,
std::string(reinterpret_cast<const char *>(contents), len));
if (!BIO_reset(bio.get())) {
fprintf(stderr, "BIO_reset failed\n");
return false;
}
ASSERT_TRUE(BIO_reset(bio.get()));
}
return true;
}
static bool ReadASN1(bool should_succeed, const uint8_t *data, size_t data_len,
size_t expected_len, size_t max_len) {
bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(data, data_len));
static const size_t kLargeASN1PayloadLen = 8000;
struct ASN1TestParam {
bool should_succeed;
std::vector<uint8_t> input;
// suffix_len is the number of zeros to append to |input|.
size_t suffix_len;
// expected_len, if |should_succeed| is true, is the expected length of the
// ASN.1 element.
size_t expected_len;
size_t max_len;
} kASN1TestParams[] = {
{true, {0x30, 2, 1, 2, 0, 0}, 0, 4, 100},
{false /* truncated */, {0x30, 3, 1, 2}, 0, 0, 100},
{false /* should be short len */, {0x30, 0x81, 1, 1}, 0, 0, 100},
{false /* zero padded */, {0x30, 0x82, 0, 1, 1}, 0, 0, 100},
// Test a large payload.
{true,
{0x30, 0x82, kLargeASN1PayloadLen >> 8, kLargeASN1PayloadLen & 0xff},
kLargeASN1PayloadLen,
4 + kLargeASN1PayloadLen,
kLargeASN1PayloadLen * 2},
{false /* max_len too short */,
{0x30, 0x82, kLargeASN1PayloadLen >> 8, kLargeASN1PayloadLen & 0xff},
kLargeASN1PayloadLen,
4 + kLargeASN1PayloadLen,
3 + kLargeASN1PayloadLen},
// Test an indefinite-length input.
{true,
{0x30, 0x80},
kLargeASN1PayloadLen + 2,
2 + kLargeASN1PayloadLen + 2,
kLargeASN1PayloadLen * 2},
{false /* max_len too short */,
{0x30, 0x80},
kLargeASN1PayloadLen + 2,
2 + kLargeASN1PayloadLen + 2,
2 + kLargeASN1PayloadLen + 1},
};
class BIOASN1Test : public testing::TestWithParam<ASN1TestParam> {};
TEST_P(BIOASN1Test, ReadASN1) {
const ASN1TestParam& param = GetParam();
std::vector<uint8_t> input = param.input;
input.resize(input.size() + param.suffix_len, 0);
bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(input.data(), input.size()));
ASSERT_TRUE(bio);
uint8_t *out;
size_t out_len;
int ok = BIO_read_asn1(bio.get(), &out, &out_len, max_len);
int ok = BIO_read_asn1(bio.get(), &out, &out_len, param.max_len);
if (!ok) {
out = nullptr;
}
bssl::UniquePtr<uint8_t> out_storage(out);
if (should_succeed != (ok == 1)) {
return false;
ASSERT_EQ(param.should_succeed, (ok == 1));
if (param.should_succeed) {
EXPECT_EQ(Bytes(input.data(), param.expected_len), Bytes(out, out_len));
}
if (should_succeed &&
(out_len != expected_len || memcmp(data, out, expected_len) != 0)) {
return false;
}
return true;
}
static bool TestASN1() {
static const uint8_t kData1[] = {0x30, 2, 1, 2, 0, 0};
static const uint8_t kData2[] = {0x30, 3, 1, 2}; /* truncated */
static const uint8_t kData3[] = {0x30, 0x81, 1, 1}; /* should be short len */
static const uint8_t kData4[] = {0x30, 0x82, 0, 1, 1}; /* zero padded. */
INSTANTIATE_TEST_CASE_P(, BIOASN1Test, testing::ValuesIn(kASN1TestParams));
if (!ReadASN1(true, kData1, sizeof(kData1), 4, 100) ||
!ReadASN1(false, kData2, sizeof(kData2), 0, 100) ||
!ReadASN1(false, kData3, sizeof(kData3), 0, 100) ||
!ReadASN1(false, kData4, sizeof(kData4), 0, 100)) {
return false;
// Run through the tests twice, swapping |bio1| and |bio2|, for symmetry.
class BIOPairTest : public testing::TestWithParam<bool> {};
TEST_P(BIOPairTest, TestPair) {
BIO *bio1, *bio2;
ASSERT_TRUE(BIO_new_bio_pair(&bio1, 10, &bio2, 10));
bssl::UniquePtr<BIO> free_bio1(bio1), free_bio2(bio2);
if (GetParam()) {
std::swap(bio1, bio2);
}
static const size_t kLargePayloadLen = 8000;
static const uint8_t kLargePrefix[] = {0x30, 0x82, kLargePayloadLen >> 8,
kLargePayloadLen & 0xff};
bssl::UniquePtr<uint8_t> large(reinterpret_cast<uint8_t *>(
OPENSSL_malloc(sizeof(kLargePrefix) + kLargePayloadLen)));
if (!large) {
return false;
}
memset(large.get() + sizeof(kLargePrefix), 0, kLargePayloadLen);
memcpy(large.get(), kLargePrefix, sizeof(kLargePrefix));
// Check initial states.
EXPECT_EQ(10u, BIO_ctrl_get_write_guarantee(bio1));
EXPECT_EQ(0u, BIO_ctrl_get_read_request(bio1));
if (!ReadASN1(true, large.get(), sizeof(kLargePrefix) + kLargePayloadLen,
sizeof(kLargePrefix) + kLargePayloadLen,
kLargePayloadLen * 2)) {
fprintf(stderr, "Large payload test failed.\n");
return false;
}
// Data written in one end may be read out the other.
uint8_t buf[20];
EXPECT_EQ(5, BIO_write(bio1, "12345", 5));
EXPECT_EQ(5u, BIO_ctrl_get_write_guarantee(bio1));
ASSERT_EQ(5, BIO_read(bio2, buf, sizeof(buf)));
EXPECT_EQ(Bytes("12345"), Bytes(buf, 5));
EXPECT_EQ(10u, BIO_ctrl_get_write_guarantee(bio1));
if (!ReadASN1(false, large.get(), sizeof(kLargePrefix) + kLargePayloadLen,
sizeof(kLargePrefix) + kLargePayloadLen,
kLargePayloadLen - 1)) {
fprintf(stderr, "max_len test failed.\n");
return false;
}
// Attempting to write more than 10 bytes will write partially.
EXPECT_EQ(10, BIO_write(bio1, "1234567890___", 13));
EXPECT_EQ(0u, BIO_ctrl_get_write_guarantee(bio1));
EXPECT_EQ(-1, BIO_write(bio1, "z", 1));
EXPECT_TRUE(BIO_should_write(bio1));
ASSERT_EQ(10, BIO_read(bio2, buf, sizeof(buf)));
EXPECT_EQ(Bytes("1234567890"), Bytes(buf, 10));
EXPECT_EQ(10u, BIO_ctrl_get_write_guarantee(bio1));
static const uint8_t kIndefPrefix[] = {0x30, 0x80};
memcpy(large.get(), kIndefPrefix, sizeof(kIndefPrefix));
if (!ReadASN1(true, large.get(), sizeof(kLargePrefix) + kLargePayloadLen,
sizeof(kLargePrefix) + kLargePayloadLen,
kLargePayloadLen*2)) {
fprintf(stderr, "indefinite length test failed.\n");
return false;
}
// Unsuccessful reads update the read request.
EXPECT_EQ(-1, BIO_read(bio2, buf, 5));
EXPECT_TRUE(BIO_should_read(bio2));
EXPECT_EQ(5u, BIO_ctrl_get_read_request(bio1));
if (!ReadASN1(false, large.get(), sizeof(kLargePrefix) + kLargePayloadLen,
sizeof(kLargePrefix) + kLargePayloadLen,
kLargePayloadLen-1)) {
fprintf(stderr, "indefinite length, max_len test failed.\n");
return false;
}
// The read request is clamped to the size of the buffer.
EXPECT_EQ(-1, BIO_read(bio2, buf, 20));
EXPECT_TRUE(BIO_should_read(bio2));
EXPECT_EQ(10u, BIO_ctrl_get_read_request(bio1));
return true;
// Data may be written and read in chunks.
EXPECT_EQ(5, BIO_write(bio1, "12345", 5));
EXPECT_EQ(5u, BIO_ctrl_get_write_guarantee(bio1));
EXPECT_EQ(5, BIO_write(bio1, "67890___", 8));
EXPECT_EQ(0u, BIO_ctrl_get_write_guarantee(bio1));
ASSERT_EQ(3, BIO_read(bio2, buf, 3));
EXPECT_EQ(Bytes("123"), Bytes(buf, 3));
EXPECT_EQ(3u, BIO_ctrl_get_write_guarantee(bio1));
ASSERT_EQ(7, BIO_read(bio2, buf, sizeof(buf)));
EXPECT_EQ(Bytes("4567890"), Bytes(buf, 7));
EXPECT_EQ(10u, BIO_ctrl_get_write_guarantee(bio1));
// Successful reads reset the read request.
EXPECT_EQ(0u, BIO_ctrl_get_read_request(bio1));
// Test writes and reads starting in the middle of the ring buffer and
// wrapping to front.
EXPECT_EQ(8, BIO_write(bio1, "abcdefgh", 8));
EXPECT_EQ(2u, BIO_ctrl_get_write_guarantee(bio1));
ASSERT_EQ(3, BIO_read(bio2, buf, 3));
EXPECT_EQ(Bytes("abc"), Bytes(buf, 3));
EXPECT_EQ(5u, BIO_ctrl_get_write_guarantee(bio1));
EXPECT_EQ(5, BIO_write(bio1, "ijklm___", 8));
EXPECT_EQ(0u, BIO_ctrl_get_write_guarantee(bio1));
ASSERT_EQ(10, BIO_read(bio2, buf, sizeof(buf)));
EXPECT_EQ(Bytes("defghijklm"), Bytes(buf, 10));
EXPECT_EQ(10u, BIO_ctrl_get_write_guarantee(bio1));
// Data may flow from both ends in parallel.
EXPECT_EQ(5, BIO_write(bio1, "12345", 5));
EXPECT_EQ(5, BIO_write(bio2, "67890", 5));
ASSERT_EQ(5, BIO_read(bio2, buf, sizeof(buf)));
EXPECT_EQ(Bytes("12345"), Bytes(buf, 5));
ASSERT_EQ(5, BIO_read(bio1, buf, sizeof(buf)));
EXPECT_EQ(Bytes("67890"), Bytes(buf, 5));
// Closing the write end causes an EOF on the read half, after draining.
EXPECT_EQ(5, BIO_write(bio1, "12345", 5));
EXPECT_TRUE(BIO_shutdown_wr(bio1));
ASSERT_EQ(5, BIO_read(bio2, buf, sizeof(buf)));
EXPECT_EQ(Bytes("12345"), Bytes(buf, 5));
EXPECT_EQ(0, BIO_read(bio2, buf, sizeof(buf)));
// A closed write end may not be written to.
EXPECT_EQ(0u, BIO_ctrl_get_write_guarantee(bio1));
EXPECT_EQ(-1, BIO_write(bio1, "_____", 5));
uint32_t err = ERR_get_error();
EXPECT_EQ(ERR_LIB_BIO, ERR_GET_LIB(err));
EXPECT_EQ(BIO_R_BROKEN_PIPE, ERR_GET_REASON(err));
// The other end is still functional.
EXPECT_EQ(5, BIO_write(bio2, "12345", 5));
ASSERT_EQ(5, BIO_read(bio1, buf, sizeof(buf)));
EXPECT_EQ(Bytes("12345"), Bytes(buf, 5));
}
int main(void) {
CRYPTO_library_init();
#if defined(OPENSSL_WINDOWS)
// Initialize Winsock.
WORD wsa_version = MAKEWORD(2, 2);
WSADATA wsa_data;
int wsa_err = WSAStartup(wsa_version, &wsa_data);
if (wsa_err != 0) {
fprintf(stderr, "WSAStartup failed: %d\n", wsa_err);
return 1;
}
if (wsa_data.wVersion != wsa_version) {
fprintf(stderr, "Didn't get expected version: %x\n", wsa_data.wVersion);
return 1;
}
#endif
if (!TestSocketConnect() ||
!TestPrintf() ||
!TestZeroCopyBioPairs() ||
!TestASN1()) {
return 1;
}
printf("PASS\n");
return 0;
}
INSTANTIATE_TEST_CASE_P(, BIOPairTest, testing::Values(false, true));
-496
View File
@@ -1,496 +0,0 @@
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
#include <openssl/bio.h>
#include <string.h>
#include <openssl/buf.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#define DEFAULT_BUFFER_SIZE 4096
typedef struct bio_f_buffer_ctx_struct {
/* Buffers are setup like this:
*
* <---------------------- size ----------------------->
* +---------------------------------------------------+
* | consumed | remaining | free space |
* +---------------------------------------------------+
* <-- off --><------- len ------->
*/
int ibuf_size; /* how big is the input buffer */
int obuf_size; /* how big is the output buffer */
char *ibuf; /* the char array */
int ibuf_len; /* how many bytes are in it */
int ibuf_off; /* write/read offset */
char *obuf; /* the char array */
int obuf_len; /* how many bytes are in it */
int obuf_off; /* write/read offset */
} BIO_F_BUFFER_CTX;
static int buffer_new(BIO *bio) {
BIO_F_BUFFER_CTX *ctx;
ctx = OPENSSL_malloc(sizeof(BIO_F_BUFFER_CTX));
if (ctx == NULL) {
return 0;
}
memset(ctx, 0, sizeof(BIO_F_BUFFER_CTX));
ctx->ibuf = OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
if (ctx->ibuf == NULL) {
goto err1;
}
ctx->obuf = OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
if (ctx->obuf == NULL) {
goto err2;
}
ctx->ibuf_size = DEFAULT_BUFFER_SIZE;
ctx->obuf_size = DEFAULT_BUFFER_SIZE;
bio->init = 1;
bio->ptr = (char *)ctx;
return 1;
err2:
OPENSSL_free(ctx->ibuf);
err1:
OPENSSL_free(ctx);
return 0;
}
static int buffer_free(BIO *bio) {
BIO_F_BUFFER_CTX *ctx;
if (bio == NULL || bio->ptr == NULL) {
return 0;
}
ctx = (BIO_F_BUFFER_CTX *)bio->ptr;
OPENSSL_free(ctx->ibuf);
OPENSSL_free(ctx->obuf);
OPENSSL_free(bio->ptr);
bio->ptr = NULL;
bio->init = 0;
bio->flags = 0;
return 1;
}
static int buffer_read(BIO *bio, char *out, int outl) {
int i, num = 0;
BIO_F_BUFFER_CTX *ctx;
ctx = (BIO_F_BUFFER_CTX *)bio->ptr;
if (ctx == NULL || bio->next_bio == NULL) {
return 0;
}
num = 0;
BIO_clear_retry_flags(bio);
for (;;) {
i = ctx->ibuf_len;
/* If there is stuff left over, grab it */
if (i != 0) {
if (i > outl) {
i = outl;
}
memcpy(out, &ctx->ibuf[ctx->ibuf_off], i);
ctx->ibuf_off += i;
ctx->ibuf_len -= i;
num += i;
if (outl == i) {
return num;
}
outl -= i;
out += i;
}
/* We may have done a partial read. Try to do more. We have nothing in the
* buffer. If we get an error and have read some data, just return it and
* let them retry to get the error again. Copy direct to parent address
* space */
if (outl > ctx->ibuf_size) {
for (;;) {
i = BIO_read(bio->next_bio, out, outl);
if (i <= 0) {
BIO_copy_next_retry(bio);
if (i < 0) {
return (num > 0) ? num : i;
}
return num;
}
num += i;
if (outl == i) {
return num;
}
out += i;
outl -= i;
}
}
/* else */
/* we are going to be doing some buffering */
i = BIO_read(bio->next_bio, ctx->ibuf, ctx->ibuf_size);
if (i <= 0) {
BIO_copy_next_retry(bio);
if (i < 0) {
return (num > 0) ? num : i;
}
return num;
}
ctx->ibuf_off = 0;
ctx->ibuf_len = i;
}
}
static int buffer_write(BIO *b, const char *in, int inl) {
int i, num = 0;
BIO_F_BUFFER_CTX *ctx;
ctx = (BIO_F_BUFFER_CTX *)b->ptr;
if (ctx == NULL || b->next_bio == NULL) {
return 0;
}
BIO_clear_retry_flags(b);
for (;;) {
i = ctx->obuf_size - (ctx->obuf_off + ctx->obuf_len);
/* add to buffer and return */
if (i >= inl) {
memcpy(&ctx->obuf[ctx->obuf_off + ctx->obuf_len], in, inl);
ctx->obuf_len += inl;
return num + inl;
}
/* else */
/* stuff already in buffer, so add to it first, then flush */
if (ctx->obuf_len != 0) {
if (i > 0) {
memcpy(&ctx->obuf[ctx->obuf_off + ctx->obuf_len], in, i);
in += i;
inl -= i;
num += i;
ctx->obuf_len += i;
}
/* we now have a full buffer needing flushing */
for (;;) {
i = BIO_write(b->next_bio, &ctx->obuf[ctx->obuf_off], ctx->obuf_len);
if (i <= 0) {
BIO_copy_next_retry(b);
if (i < 0) {
return (num > 0) ? num : i;
}
return num;
}
ctx->obuf_off += i;
ctx->obuf_len -= i;
if (ctx->obuf_len == 0) {
break;
}
}
}
/* we only get here if the buffer has been flushed and we
* still have stuff to write */
ctx->obuf_off = 0;
/* we now have inl bytes to write */
while (inl >= ctx->obuf_size) {
i = BIO_write(b->next_bio, in, inl);
if (i <= 0) {
BIO_copy_next_retry(b);
if (i < 0) {
return (num > 0) ? num : i;
}
return num;
}
num += i;
in += i;
inl -= i;
if (inl == 0) {
return num;
}
}
/* copy the rest into the buffer since we have only a small
* amount left */
}
}
static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr) {
BIO_F_BUFFER_CTX *ctx;
long ret = 1;
char *p1, *p2;
int r, *ip;
int ibs, obs;
ctx = (BIO_F_BUFFER_CTX *)b->ptr;
switch (cmd) {
case BIO_CTRL_RESET:
ctx->ibuf_off = 0;
ctx->ibuf_len = 0;
ctx->obuf_off = 0;
ctx->obuf_len = 0;
if (b->next_bio == NULL) {
return 0;
}
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
break;
case BIO_CTRL_INFO:
ret = ctx->obuf_len;
break;
case BIO_CTRL_WPENDING:
ret = (long)ctx->obuf_len;
if (ret == 0) {
if (b->next_bio == NULL) {
return 0;
}
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
}
break;
case BIO_CTRL_PENDING:
ret = (long)ctx->ibuf_len;
if (ret == 0) {
if (b->next_bio == NULL) {
return 0;
}
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
}
break;
case BIO_C_SET_BUFF_SIZE:
ip = (int *)ptr;
if (*ip == 0) {
ibs = (int)num;
obs = ctx->obuf_size;
} else /* if (*ip == 1) */ {
ibs = ctx->ibuf_size;
obs = (int)num;
}
p1 = ctx->ibuf;
p2 = ctx->obuf;
if (ibs > DEFAULT_BUFFER_SIZE && ibs != ctx->ibuf_size) {
p1 = OPENSSL_malloc(ibs);
if (p1 == NULL) {
goto malloc_error;
}
}
if (obs > DEFAULT_BUFFER_SIZE && obs != ctx->obuf_size) {
p2 = OPENSSL_malloc(obs);
if (p2 == NULL) {
if (p1 != ctx->ibuf) {
OPENSSL_free(p1);
}
goto malloc_error;
}
}
if (ctx->ibuf != p1) {
OPENSSL_free(ctx->ibuf);
ctx->ibuf = p1;
ctx->ibuf_size = ibs;
}
ctx->ibuf_off = 0;
ctx->ibuf_len = 0;
if (ctx->obuf != p2) {
OPENSSL_free(ctx->obuf);
ctx->obuf = p2;
ctx->obuf_size = obs;
}
ctx->obuf_off = 0;
ctx->obuf_len = 0;
break;
case BIO_CTRL_FLUSH:
if (b->next_bio == NULL) {
return 0;
}
while (ctx->obuf_len > 0) {
BIO_clear_retry_flags(b);
r = BIO_write(b->next_bio, &(ctx->obuf[ctx->obuf_off]),
ctx->obuf_len);
BIO_copy_next_retry(b);
if (r <= 0) {
return r;
}
ctx->obuf_off += r;
ctx->obuf_len -= r;
}
ctx->obuf_len = 0;
ctx->obuf_off = 0;
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
break;
default:
if (b->next_bio == NULL) {
return 0;
}
BIO_clear_retry_flags(b);
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
BIO_copy_next_retry(b);
break;
}
return ret;
malloc_error:
OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
return 0;
}
static long buffer_callback_ctrl(BIO *b, int cmd, bio_info_cb fp) {
long ret = 1;
if (b->next_bio == NULL) {
return 0;
}
switch (cmd) {
default:
ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
break;
}
return ret;
}
static int buffer_gets(BIO *b, char *buf, int size) {
BIO_F_BUFFER_CTX *ctx;
int num = 0, i, flag;
char *p;
ctx = (BIO_F_BUFFER_CTX *)b->ptr;
if (buf == NULL || size <= 0) {
return 0;
}
size--; /* reserve space for a '\0' */
BIO_clear_retry_flags(b);
for (;;) {
if (ctx->ibuf_len > 0) {
p = &ctx->ibuf[ctx->ibuf_off];
flag = 0;
for (i = 0; (i < ctx->ibuf_len) && (i < size); i++) {
*(buf++) = p[i];
if (p[i] == '\n') {
flag = 1;
i++;
break;
}
}
num += i;
size -= i;
ctx->ibuf_len -= i;
ctx->ibuf_off += i;
if (flag || size == 0) {
*buf = '\0';
return num;
}
} else /* read another chunk */
{
i = BIO_read(b->next_bio, ctx->ibuf, ctx->ibuf_size);
if (i <= 0) {
BIO_copy_next_retry(b);
*buf = '\0';
if (i < 0) {
return (num > 0) ? num : i;
}
return num;
}
ctx->ibuf_len = i;
ctx->ibuf_off = 0;
}
}
}
static int buffer_puts(BIO *b, const char *str) {
return buffer_write(b, str, strlen(str));
}
static const BIO_METHOD methods_buffer = {
BIO_TYPE_BUFFER, "buffer", buffer_write, buffer_read,
buffer_puts, buffer_gets, buffer_ctrl, buffer_new,
buffer_free, buffer_callback_ctrl,
};
const BIO_METHOD *BIO_f_buffer(void) { return &methods_buffer; }
int BIO_set_read_buffer_size(BIO *bio, int buffer_size) {
return BIO_int_ctrl(bio, BIO_C_SET_BUFF_SIZE, buffer_size, 0);
}
int BIO_set_write_buffer_size(BIO *bio, int buffer_size) {
return BIO_int_ctrl(bio, BIO_C_SET_BUFF_SIZE, buffer_size, 1);
}
+7 -18
View File
@@ -77,6 +77,7 @@ OPENSSL_MSVC_PRAGMA(warning(pop))
#include <openssl/mem.h>
#include "internal.h"
#include "../internal.h"
enum {
@@ -298,7 +299,7 @@ static BIO_CONNECT *BIO_CONNECT_new(void) {
if (ret == NULL) {
return NULL;
}
memset(ret, 0, sizeof(BIO_CONNECT));
OPENSSL_memset(ret, 0, sizeof(BIO_CONNECT));
ret->state = BIO_CONN_S_BEFORE;
return ret;
@@ -467,14 +468,6 @@ static long conn_ctrl(BIO *bio, int cmd, long num, void *ptr) {
break;
case BIO_CTRL_FLUSH:
break;
case BIO_CTRL_SET_CALLBACK: {
#if 0 /* FIXME: Should this be used? -- Richard Levitte */
OPENSSL_PUT_ERROR(BIO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
ret = -1;
#else
ret = 0;
#endif
} break;
case BIO_CTRL_GET_CALLBACK: {
int (**fptr)(const BIO *bio, int state, int xret);
fptr = (int (**)(const BIO *bio, int state, int xret))ptr;
@@ -484,7 +477,7 @@ static long conn_ctrl(BIO *bio, int cmd, long num, void *ptr) {
ret = 0;
break;
}
return (ret);
return ret;
}
static long conn_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp) {
@@ -494,9 +487,9 @@ static long conn_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp) {
data = (BIO_CONNECT *)bio->ptr;
switch (cmd) {
case BIO_CTRL_SET_CALLBACK: {
case BIO_CTRL_SET_CALLBACK:
data->info_callback = (int (*)(const struct bio_st *, int, int))fp;
} break;
break;
default:
ret = 0;
break;
@@ -504,10 +497,6 @@ static long conn_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp) {
return ret;
}
static int conn_puts(BIO *bp, const char *str) {
return conn_write(bp, str, strlen(str));
}
BIO *BIO_new_connect(const char *hostname) {
BIO *ret;
@@ -523,8 +512,8 @@ BIO *BIO_new_connect(const char *hostname) {
}
static const BIO_METHOD methods_connectp = {
BIO_TYPE_CONNECT, "socket connect", conn_write, conn_read,
conn_puts, NULL /* connect_gets, */, conn_ctrl, conn_new,
BIO_TYPE_CONNECT, "socket connect", conn_write, conn_read,
NULL /* puts */, NULL /* gets */, conn_ctrl, conn_new,
conn_free, conn_callback_ctrl,
};
+3 -6
View File
@@ -241,10 +241,6 @@ static long fd_ctrl(BIO *b, int cmd, long num, void *ptr) {
return ret;
}
static int fd_puts(BIO *bp, const char *str) {
return fd_write(bp, str, strlen(str));
}
static int fd_gets(BIO *bp, char *buf, int size) {
char *ptr = buf;
char *end = buf + size - 1;
@@ -263,8 +259,9 @@ static int fd_gets(BIO *bp, char *buf, int size) {
}
static const BIO_METHOD methods_fdp = {
BIO_TYPE_FD, "file descriptor", fd_write, fd_read, fd_puts,
fd_gets, fd_ctrl, fd_new, fd_free, NULL, };
BIO_TYPE_FD, "file descriptor", fd_write, fd_read, NULL /* puts */,
fd_gets, fd_ctrl, fd_new, fd_free, NULL /* callback_ctrl */,
};
const BIO_METHOD *BIO_s_fd(void) { return &methods_fdp; }
+6 -6
View File
@@ -273,13 +273,13 @@ err:
return ret;
}
static int file_puts(BIO *bp, const char *str) {
return file_write(bp, str, strlen(str));
}
static const BIO_METHOD methods_filep = {
BIO_TYPE_FILE, "FILE pointer", file_write, file_read, file_puts,
file_gets, file_ctrl, file_new, file_free, NULL, };
BIO_TYPE_FILE, "FILE pointer",
file_write, file_read,
NULL /* puts */, file_gets,
file_ctrl, file_new,
file_free, NULL /* callback_ctrl */,
};
const BIO_METHOD *BIO_s_file(void) { return &methods_filep; }
+4 -2
View File
@@ -59,6 +59,8 @@
#include <limits.h>
#include <string.h>
#include "../internal.h"
/* hexdump_ctx contains the state of a hexdump. */
struct hexdump_ctx {
@@ -154,7 +156,7 @@ static int finish(struct hexdump_ctx *ctx) {
return 1;
}
memset(buf, ' ', 4);
OPENSSL_memset(buf, ' ', 4);
buf[4] = '|';
for (; ctx->used < 16; ctx->used++) {
@@ -179,7 +181,7 @@ static int finish(struct hexdump_ctx *ctx) {
int BIO_hexdump(BIO *bio, const uint8_t *data, size_t len, unsigned indent) {
struct hexdump_ctx ctx;
memset(&ctx, 0, sizeof(ctx));
OPENSSL_memset(&ctx, 0, sizeof(ctx));
ctx.bio = bio;
ctx.indent = indent;
+30 -344
View File
@@ -59,6 +59,8 @@
#include <openssl/err.h>
#include <openssl/mem.h>
#include "../internal.h"
struct bio_bio_st {
BIO *peer; /* NULL if buf == NULL.
@@ -72,12 +74,6 @@ struct bio_bio_st {
size_t offset; /* valid iff buf != NULL; 0 if len == 0 */
size_t size;
uint8_t *buf; /* "size" elements (if != NULL) */
char buf_externally_allocated; /* true iff buf was externally allocated. */
char zero_copy_read_lock; /* true iff a zero copy read operation
* is in progress. */
char zero_copy_write_lock; /* true iff a zero copy write operation
* is in progress. */
size_t request; /* valid iff peer != NULL; 0 if len != 0,
* otherwise set by peer to number of bytes
@@ -92,7 +88,7 @@ static int bio_new(BIO *bio) {
if (b == NULL) {
return 0;
}
memset(b, 0, sizeof(struct bio_bio_st));
OPENSSL_memset(b, 0, sizeof(struct bio_bio_st));
b->size = 17 * 1024; /* enough for one TLS record (just a default) */
bio->ptr = b;
@@ -145,263 +141,12 @@ static int bio_free(BIO *bio) {
bio_destroy_pair(bio);
}
if (!b->buf_externally_allocated) {
OPENSSL_free(b->buf);
}
OPENSSL_free(b->buf);
OPENSSL_free(b);
return 1;
}
static size_t bio_zero_copy_get_read_buf(struct bio_bio_st* peer_b,
uint8_t** out_read_buf,
size_t* out_buf_offset) {
size_t max_available;
if (peer_b->len > peer_b->size - peer_b->offset) {
/* Only the first half of the ring buffer can be read. */
max_available = peer_b->size - peer_b->offset;
} else {
max_available = peer_b->len;
}
*out_read_buf = peer_b->buf;
*out_buf_offset = peer_b->offset;
return max_available;
}
int BIO_zero_copy_get_read_buf(BIO* bio, uint8_t** out_read_buf,
size_t* out_buf_offset,
size_t* out_available_bytes) {
struct bio_bio_st* b;
struct bio_bio_st* peer_b;
size_t max_available;
*out_available_bytes = 0;
BIO_clear_retry_flags(bio);
if (!bio->init) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
return 0;
}
b = bio->ptr;
if (!b || !b->peer) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
peer_b = b->peer->ptr;
if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
if (peer_b->zero_copy_read_lock) {
OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
return 0;
}
peer_b->request = 0; /* Is not used by zero-copy API. */
max_available =
bio_zero_copy_get_read_buf(peer_b, out_read_buf, out_buf_offset);
assert(peer_b->buf != NULL);
if (max_available > 0) {
peer_b->zero_copy_read_lock = 1;
}
*out_available_bytes = max_available;
return 1;
}
int BIO_zero_copy_get_read_buf_done(BIO* bio, size_t bytes_read) {
struct bio_bio_st* b;
struct bio_bio_st* peer_b;
size_t max_available;
size_t dummy_read_offset;
uint8_t* dummy_read_buf;
assert(BIO_get_retry_flags(bio) == 0);
if (!bio->init) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
return 0;
}
b = bio->ptr;
if (!b || !b->peer) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
peer_b = b->peer->ptr;
if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
if (!peer_b->zero_copy_read_lock) {
OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
return 0;
}
max_available =
bio_zero_copy_get_read_buf(peer_b, &dummy_read_buf, &dummy_read_offset);
if (bytes_read > max_available) {
OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
return 0;
}
assert(peer_b->len >= bytes_read);
peer_b->len -= bytes_read;
assert(peer_b->offset + bytes_read <= peer_b->size);
/* Move read offset. If zero_copy_write_lock == 1 we must advance the
* offset even if buffer becomes empty, to make sure
* write_offset = (offset + len) mod size does not change. */
if (peer_b->offset + bytes_read == peer_b->size ||
(!peer_b->zero_copy_write_lock && peer_b->len == 0)) {
peer_b->offset = 0;
} else {
peer_b->offset += bytes_read;
}
bio->num_read += bytes_read;
peer_b->zero_copy_read_lock = 0;
return 1;
}
static size_t bio_zero_copy_get_write_buf(struct bio_bio_st* b,
uint8_t** out_write_buf,
size_t* out_buf_offset) {
size_t write_offset;
size_t max_available;
assert(b->len <= b->size);
write_offset = b->offset + b->len;
if (write_offset >= b->size) {
/* Only the first half of the ring buffer can be written to. */
write_offset -= b->size;
/* write up to the start of the ring buffer. */
max_available = b->offset - write_offset;
} else {
/* write up to the end the buffer. */
max_available = b->size - write_offset;
}
*out_write_buf = b->buf;
*out_buf_offset = write_offset;
return max_available;
}
int BIO_zero_copy_get_write_buf(BIO* bio, uint8_t** out_write_buf,
size_t* out_buf_offset,
size_t* out_available_bytes) {
struct bio_bio_st* b;
struct bio_bio_st* peer_b;
size_t max_available;
*out_available_bytes = 0;
BIO_clear_retry_flags(bio);
if (!bio->init) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
return 0;
}
b = bio->ptr;
if (!b || !b->buf || !b->peer) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
peer_b = b->peer->ptr;
if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
assert(b->buf != NULL);
if (b->zero_copy_write_lock) {
OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
return 0;
}
b->request = 0;
if (b->closed) {
/* Bio is already closed. */
OPENSSL_PUT_ERROR(BIO, BIO_R_BROKEN_PIPE);
return 0;
}
max_available = bio_zero_copy_get_write_buf(b, out_write_buf, out_buf_offset);
if (max_available > 0) {
b->zero_copy_write_lock = 1;
}
*out_available_bytes = max_available;
return 1;
}
int BIO_zero_copy_get_write_buf_done(BIO* bio, size_t bytes_written) {
struct bio_bio_st* b;
struct bio_bio_st* peer_b;
size_t rest;
size_t dummy_write_offset;
uint8_t* dummy_write_buf;
if (!bio->init) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
return 0;
}
b = bio->ptr;
if (!b || !b->buf || !b->peer) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
peer_b = b->peer->ptr;
if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) {
OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
b->request = 0;
if (b->closed) {
/* BIO is already closed. */
OPENSSL_PUT_ERROR(BIO, BIO_R_BROKEN_PIPE);
return 0;
}
if (!b->zero_copy_write_lock) {
OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
return 0;
}
rest = bio_zero_copy_get_write_buf(b, &dummy_write_buf, &dummy_write_offset);
if (bytes_written > rest) {
OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
return 0;
}
bio->num_write += bytes_written;
/* Move write offset. */
b->len += bytes_written;
b->zero_copy_write_lock = 0;
return 1;
}
static int bio_read(BIO *bio, char *buf, int size_) {
size_t size = size_;
size_t rest;
@@ -422,7 +167,7 @@ static int bio_read(BIO *bio, char *buf, int size_) {
peer_b->request = 0; /* will be set in "retry_read" situation */
if (buf == NULL || size == 0 || peer_b->zero_copy_read_lock) {
if (buf == NULL || size == 0) {
return 0;
}
@@ -464,13 +209,10 @@ static int bio_read(BIO *bio, char *buf, int size_) {
}
assert(peer_b->offset + chunk <= peer_b->size);
memcpy(buf, peer_b->buf + peer_b->offset, chunk);
OPENSSL_memcpy(buf, peer_b->buf + peer_b->offset, chunk);
peer_b->len -= chunk;
/* If zero_copy_write_lock == 1 we must advance the offset even if buffer
* becomes empty, to make sure write_offset = (offset + len) % size
* does not change. */
if (peer_b->len || peer_b->zero_copy_write_lock) {
if (peer_b->len) {
peer_b->offset += chunk;
assert(peer_b->offset <= peer_b->size);
if (peer_b->offset == peer_b->size) {
@@ -504,10 +246,6 @@ static int bio_write(BIO *bio, const char *buf, int num_) {
assert(b->peer != NULL);
assert(b->buf != NULL);
if (b->zero_copy_write_lock) {
return 0;
}
b->request = 0;
if (b->closed) {
/* we already closed */
@@ -551,7 +289,7 @@ static int bio_write(BIO *bio, const char *buf, int num_) {
chunk = b->size - write_offset;
}
memcpy(b->buf + write_offset, buf, chunk);
OPENSSL_memcpy(b->buf + write_offset, buf, chunk);
b->len += chunk;
@@ -564,9 +302,8 @@ static int bio_write(BIO *bio, const char *buf, int num_) {
return num;
}
static int bio_make_pair(BIO* bio1, BIO* bio2,
size_t writebuf1_len, uint8_t* ext_writebuf1,
size_t writebuf2_len, uint8_t* ext_writebuf2) {
static int bio_make_pair(BIO *bio1, BIO *bio2, size_t writebuf1_len,
size_t writebuf2_len) {
struct bio_bio_st *b1, *b2;
assert(bio1 != NULL);
@@ -580,23 +317,14 @@ static int bio_make_pair(BIO* bio1, BIO* bio2,
return 0;
}
assert(b1->buf_externally_allocated == 0);
assert(b2->buf_externally_allocated == 0);
if (b1->buf == NULL) {
if (writebuf1_len) {
b1->size = writebuf1_len;
}
if (!ext_writebuf1) {
b1->buf_externally_allocated = 0;
b1->buf = OPENSSL_malloc(b1->size);
if (b1->buf == NULL) {
OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
return 0;
}
} else {
b1->buf = ext_writebuf1;
b1->buf_externally_allocated = 1;
b1->buf = OPENSSL_malloc(b1->size);
if (b1->buf == NULL) {
OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
return 0;
}
b1->len = 0;
b1->offset = 0;
@@ -606,16 +334,10 @@ static int bio_make_pair(BIO* bio1, BIO* bio2,
if (writebuf2_len) {
b2->size = writebuf2_len;
}
if (!ext_writebuf2) {
b2->buf_externally_allocated = 0;
b2->buf = OPENSSL_malloc(b2->size);
if (b2->buf == NULL) {
OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
return 0;
}
} else {
b2->buf = ext_writebuf2;
b2->buf_externally_allocated = 1;
b2->buf = OPENSSL_malloc(b2->size);
if (b2->buf == NULL) {
OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
return 0;
}
b2->len = 0;
b2->offset = 0;
@@ -624,13 +346,9 @@ static int bio_make_pair(BIO* bio1, BIO* bio2,
b1->peer = bio2;
b1->closed = 0;
b1->request = 0;
b1->zero_copy_read_lock = 0;
b1->zero_copy_write_lock = 0;
b2->peer = bio1;
b2->closed = 0;
b2->request = 0;
b2->zero_copy_read_lock = 0;
b2->zero_copy_write_lock = 0;
bio1->init = 1;
bio2->init = 1;
@@ -732,62 +450,30 @@ static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) {
return ret;
}
static int bio_puts(BIO *bio, const char *str) {
return bio_write(bio, str, strlen(str));
}
static const BIO_METHOD methods_biop = {
BIO_TYPE_BIO, "BIO pair", bio_write, bio_read,
bio_puts, NULL /* no bio_gets */, bio_ctrl, bio_new,
bio_free, NULL /* no bio_callback_ctrl */
BIO_TYPE_BIO, "BIO pair", bio_write, bio_read, NULL /* puts */,
NULL /* gets */, bio_ctrl, bio_new, bio_free, NULL /* callback_ctrl */
};
static const BIO_METHOD *bio_s_bio(void) { return &methods_biop; }
int BIO_new_bio_pair(BIO** bio1_p, size_t writebuf1,
BIO** bio2_p, size_t writebuf2) {
return BIO_new_bio_pair_external_buf(bio1_p, writebuf1, NULL, bio2_p,
writebuf2, NULL);
}
int BIO_new_bio_pair_external_buf(BIO** bio1_p, size_t writebuf1_len,
uint8_t* ext_writebuf1,
BIO** bio2_p, size_t writebuf2_len,
uint8_t* ext_writebuf2) {
BIO *bio1 = NULL, *bio2 = NULL;
int ret = 0;
/* External buffers must have sizes greater than 0. */
if ((ext_writebuf1 && !writebuf1_len) || (ext_writebuf2 && !writebuf2_len)) {
goto err;
}
bio1 = BIO_new(bio_s_bio());
if (bio1 == NULL) {
goto err;
}
bio2 = BIO_new(bio_s_bio());
if (bio2 == NULL) {
goto err;
}
if (!bio_make_pair(bio1, bio2, writebuf1_len, ext_writebuf1, writebuf2_len,
ext_writebuf2)) {
goto err;
}
ret = 1;
err:
if (ret == 0) {
int BIO_new_bio_pair(BIO** bio1_p, size_t writebuf1_len,
BIO** bio2_p, size_t writebuf2_len) {
BIO *bio1 = BIO_new(bio_s_bio());
BIO *bio2 = BIO_new(bio_s_bio());
if (bio1 == NULL || bio2 == NULL ||
!bio_make_pair(bio1, bio2, writebuf1_len, writebuf2_len)) {
BIO_free(bio1);
bio1 = NULL;
BIO_free(bio2);
bio2 = NULL;
*bio1_p = NULL;
*bio2_p = NULL;
return 0;
}
*bio1_p = bio1;
*bio2_p = bio2;
return ret;
return 1;
}
size_t BIO_ctrl_get_read_request(BIO *bio) {
+5 -6
View File
@@ -142,10 +142,6 @@ static int sock_write(BIO *b, const char *in, int inl) {
return ret;
}
static int sock_puts(BIO *bp, const char *str) {
return sock_write(bp, str, strlen(str));
}
static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) {
long ret = 1;
int *ip;
@@ -185,8 +181,11 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) {
}
static const BIO_METHOD methods_sockp = {
BIO_TYPE_SOCKET, "socket", sock_write, sock_read, sock_puts,
NULL /* gets, */, sock_ctrl, sock_new, sock_free, NULL,
BIO_TYPE_SOCKET, "socket",
sock_write, sock_read,
NULL /* puts */, NULL /* gets, */,
sock_ctrl, sock_new,
sock_free, NULL /* callback_ctrl */,
};
const BIO_METHOD *BIO_s_socket(void) { return &methods_sockp; }
+4 -3
View File
@@ -33,6 +33,7 @@ OPENSSL_MSVC_PRAGMA(warning(pop))
#endif
#include "internal.h"
#include "../internal.h"
int bio_ip_and_port_to_socket_and_addr(int *out_sock,
@@ -45,7 +46,7 @@ int bio_ip_and_port_to_socket_and_addr(int *out_sock,
*out_sock = -1;
memset(&hint, 0, sizeof(hint));
OPENSSL_memset(&hint, 0, sizeof(hint));
hint.ai_family = AF_UNSPEC;
hint.ai_socktype = SOCK_STREAM;
@@ -62,8 +63,8 @@ int bio_ip_and_port_to_socket_and_addr(int *out_sock,
if ((size_t) cur->ai_addrlen > sizeof(struct sockaddr_storage)) {
continue;
}
memset(out_addr, 0, sizeof(struct sockaddr_storage));
memcpy(out_addr, cur->ai_addr, cur->ai_addrlen);
OPENSSL_memset(out_addr, 0, sizeof(struct sockaddr_storage));
OPENSSL_memcpy(out_addr, cur->ai_addr, cur->ai_addrlen);
*out_addr_length = cur->ai_addrlen;
*out_sock = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol);
-2
View File
@@ -6,7 +6,6 @@ if (${ARCH} STREQUAL "x86_64")
x86_64-mont.${ASM_EXT}
x86_64-mont5.${ASM_EXT}
rsaz-x86_64.${ASM_EXT}
rsaz-avx2.${ASM_EXT}
rsaz_exp.c
@@ -69,7 +68,6 @@ add_library(
perlasm(x86_64-mont.${ASM_EXT} asm/x86_64-mont.pl)
perlasm(x86_64-mont5.${ASM_EXT} asm/x86_64-mont5.pl)
perlasm(rsaz-x86_64.${ASM_EXT} asm/rsaz-x86_64.pl)
perlasm(rsaz-avx2.${ASM_EXT} asm/rsaz-avx2.pl)
perlasm(bn-586.${ASM_EXT} asm/bn-586.pl)
perlasm(co-586.${ASM_EXT} asm/co-586.pl)
+1 -1
View File
@@ -314,7 +314,7 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
}
if (dif > 0 && rp != ap) {
memcpy(rp, ap, sizeof(*rp) * dif);
OPENSSL_memcpy(rp, ap, sizeof(*rp) * dif);
}
r->top = max;
+1 -1
View File
@@ -16,7 +16,7 @@
# [depending on key length, less for longer keys] on ARM920T, and
# +115-80% on Intel IXP425. This is compared to pre-bn_mul_mont code
# base and compiler generated code with in-lined umull and even umlal
# instructions. The latter means that this code didn't really have an
# instructions. The latter means that this code didn't really have an
# "advantage" of utilizing some "secret" instruction.
#
# The code is interoperable with Thumb ISA and is rather compact, less
+12 -12
View File
@@ -47,7 +47,7 @@ sub bn_mul_add_words
&movd("mm0",&wparam(3)); # mm0 = w
&pxor("mm1","mm1"); # mm1 = carry_in
&jmp(&label("maw_sse2_entry"));
&set_label("maw_sse2_unrolled",16);
&movd("mm3",&DWP(0,$r,"",0)); # mm3 = r[0]
&paddq("mm1","mm3"); # mm1 = carry_in + r[0]
@@ -668,20 +668,20 @@ sub bn_sub_part_words
&adc($c,0);
&mov(&DWP($i*4,$r,"",0),$tmp1); # *r
}
&comment("");
&add($b,32);
&add($r,32);
&sub($num,8);
&jnz(&label("pw_neg_loop"));
&set_label("pw_neg_finish",0);
&mov($tmp2,&wparam(4)); # get dl
&mov($num,0);
&sub($num,$tmp2);
&and($num,7);
&jz(&label("pw_end"));
for ($i=0; $i<7; $i++)
{
&comment("dl<0 Tail Round $i");
@@ -698,9 +698,9 @@ sub bn_sub_part_words
}
&jmp(&label("pw_end"));
&set_label("pw_pos",0);
&and($num,0xfffffff8); # num / 8
&jz(&label("pw_pos_finish"));
@@ -715,18 +715,18 @@ sub bn_sub_part_words
&mov(&DWP($i*4,$r,"",0),$tmp1); # *r
&jnc(&label("pw_nc".$i));
}
&comment("");
&add($a,32);
&add($r,32);
&sub($num,8);
&jnz(&label("pw_pos_loop"));
&set_label("pw_pos_finish",0);
&mov($num,&wparam(4)); # get dl
&and($num,7);
&jz(&label("pw_end"));
for ($i=0; $i<7; $i++)
{
&comment("dl>0 Tail Round $i");
@@ -747,17 +747,17 @@ sub bn_sub_part_words
&mov(&DWP($i*4,$r,"",0),$tmp1); # *r
&set_label("pw_nc".$i,0);
}
&comment("");
&add($a,32);
&add($r,32);
&sub($num,8);
&jnz(&label("pw_nc_loop"));
&mov($num,&wparam(4)); # get dl
&and($num,7);
&jz(&label("pw_nc_end"));
for ($i=0; $i<7; $i++)
{
&mov($tmp1,&DWP($i*4,$a,"",0)); # *a
+6 -6
View File
@@ -41,7 +41,7 @@ sub mul_add_c
&mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 1; # laod next b
###
&adc($c2,0);
# is pos > 1, it means it is the last loop
# is pos > 1, it means it is the last loop
&mov(&DWP($i*4,"eax","",0),$c0) if $pos > 0; # save r[];
&mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1; # laod next a
}
@@ -70,7 +70,7 @@ sub sqr_add_c
&mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos == 1) && ($na != $nb);
###
&adc($c2,0);
# is pos > 1, it means it is the last loop
# is pos > 1, it means it is the last loop
&mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0; # save r[];
&mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1; # load next b
}
@@ -121,7 +121,7 @@ sub bn_mul_comba
$c2="ebp";
$a="esi";
$b="edi";
$as=0;
$ae=0;
$bs=0;
@@ -136,9 +136,9 @@ sub bn_mul_comba
&push("ebx");
&xor($c0,$c0);
&mov("eax",&DWP(0,$a,"",0)); # load the first word
&mov("eax",&DWP(0,$a,"",0)); # load the first word
&xor($c1,$c1);
&mov("edx",&DWP(0,$b,"",0)); # load the first second
&mov("edx",&DWP(0,$b,"",0)); # load the first second
for ($i=0; $i<$tot; $i++)
{
@@ -146,7 +146,7 @@ sub bn_mul_comba
$bi=$bs;
$end=$be+1;
&comment("################## Calculate word $i");
&comment("################## Calculate word $i");
for ($j=$bs; $j<$end; $j++)
{
+59 -12
View File
@@ -84,8 +84,8 @@ die "can't locate x86_64-xlate.pl";
# output, so this isn't useful anyway.
#
# TODO(davidben): Enable these after testing. $avx goes up to 2 and $addx to 1.
$avx = 0;
$addx = 0;
$avx = 2;
$addx = 1;
open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
*STDOUT = *OUT;
@@ -145,13 +145,21 @@ $code.=<<___;
.type rsaz_1024_sqr_avx2,\@function,5
.align 64
rsaz_1024_sqr_avx2: # 702 cycles, 14% faster than rsaz_1024_mul_avx2
.cfi_startproc
lea (%rsp), %rax
.cfi_def_cfa_register %rax
push %rbx
.cfi_push %rbx
push %rbp
.cfi_push %rbp
push %r12
.cfi_push %r12
push %r13
.cfi_push %r13
push %r14
.cfi_push %r14
push %r15
.cfi_push %r15
vzeroupper
___
$code.=<<___ if ($win64);
@@ -170,6 +178,7 @@ $code.=<<___ if ($win64);
___
$code.=<<___;
mov %rax,%rbp
.cfi_def_cfa_register %rbp
mov %rdx, $np # reassigned argument
sub \$$FrameSize, %rsp
mov $np, $tmp
@@ -359,7 +368,7 @@ $code.=<<___;
vpaddq $TEMP1, $ACC1, $ACC1
vpmuludq 32*7-128($aap), $B2, $ACC2
vpbroadcastq 32*5-128($tpa), $B2
vpaddq 32*11-448($tp1), $ACC2, $ACC2
vpaddq 32*11-448($tp1), $ACC2, $ACC2
vmovdqu $ACC6, 32*6-192($tp0)
vmovdqu $ACC7, 32*7-192($tp0)
@@ -418,7 +427,7 @@ $code.=<<___;
vmovdqu $ACC7, 32*16-448($tp1)
lea 8($tp1), $tp1
dec $i
dec $i
jnz .LOOP_SQR_1024
___
$ZERO = $ACC9;
@@ -763,7 +772,7 @@ $code.=<<___;
vpblendd \$3, $TEMP4, $TEMP5, $TEMP4
vpaddq $TEMP3, $ACC7, $ACC7
vpaddq $TEMP4, $ACC8, $ACC8
vpsrlq \$29, $ACC4, $TEMP1
vpand $AND_MASK, $ACC4, $ACC4
vpsrlq \$29, $ACC5, $TEMP2
@@ -802,8 +811,10 @@ $code.=<<___;
vzeroall
mov %rbp, %rax
.cfi_def_cfa_register %rax
___
$code.=<<___ if ($win64);
.Lsqr_1024_in_tail:
movaps -0xd8(%rax),%xmm6
movaps -0xc8(%rax),%xmm7
movaps -0xb8(%rax),%xmm8
@@ -817,14 +828,22 @@ $code.=<<___ if ($win64);
___
$code.=<<___;
mov -48(%rax),%r15
.cfi_restore %r15
mov -40(%rax),%r14
.cfi_restore %r14
mov -32(%rax),%r13
.cfi_restore %r13
mov -24(%rax),%r12
.cfi_restore %r12
mov -16(%rax),%rbp
.cfi_restore %rbp
mov -8(%rax),%rbx
.cfi_restore %rbx
lea (%rax),%rsp # restore %rsp
.cfi_def_cfa_register %rsp
.Lsqr_1024_epilogue:
ret
.cfi_endproc
.size rsaz_1024_sqr_avx2,.-rsaz_1024_sqr_avx2
___
}
@@ -877,13 +896,21 @@ $code.=<<___;
.type rsaz_1024_mul_avx2,\@function,5
.align 64
rsaz_1024_mul_avx2:
.cfi_startproc
lea (%rsp), %rax
.cfi_def_cfa_register %rax
push %rbx
.cfi_push %rbx
push %rbp
.cfi_push %rbp
push %r12
.cfi_push %r12
push %r13
.cfi_push %r13
push %r14
.cfi_push %r14
push %r15
.cfi_push %r15
___
$code.=<<___ if ($win64);
vzeroupper
@@ -902,6 +929,7 @@ $code.=<<___ if ($win64);
___
$code.=<<___;
mov %rax,%rbp
.cfi_def_cfa_register %rbp
vzeroall
mov %rdx, $bp # reassigned argument
sub \$64,%rsp
@@ -1428,15 +1456,17 @@ $code.=<<___;
vpaddq $TEMP4, $ACC8, $ACC8
vmovdqu $ACC4, 128-128($rp)
vmovdqu $ACC5, 160-128($rp)
vmovdqu $ACC5, 160-128($rp)
vmovdqu $ACC6, 192-128($rp)
vmovdqu $ACC7, 224-128($rp)
vmovdqu $ACC8, 256-128($rp)
vzeroupper
mov %rbp, %rax
.cfi_def_cfa_register %rax
___
$code.=<<___ if ($win64);
.Lmul_1024_in_tail:
movaps -0xd8(%rax),%xmm6
movaps -0xc8(%rax),%xmm7
movaps -0xb8(%rax),%xmm8
@@ -1450,14 +1480,22 @@ $code.=<<___ if ($win64);
___
$code.=<<___;
mov -48(%rax),%r15
.cfi_restore %r15
mov -40(%rax),%r14
.cfi_restore %r14
mov -32(%rax),%r13
.cfi_restore %r13
mov -24(%rax),%r12
.cfi_restore %r12
mov -16(%rax),%rbp
.cfi_restore %rbp
mov -8(%rax),%rbx
.cfi_restore %rbx
lea (%rax),%rsp # restore %rsp
.cfi_def_cfa_register %rsp
.Lmul_1024_epilogue:
ret
.cfi_endproc
.size rsaz_1024_mul_avx2,.-rsaz_1024_mul_avx2
___
}
@@ -1576,8 +1614,10 @@ rsaz_1024_scatter5_avx2:
.type rsaz_1024_gather5_avx2,\@abi-omnipotent
.align 32
rsaz_1024_gather5_avx2:
.cfi_startproc
vzeroupper
mov %rsp,%r11
.cfi_def_cfa_register %r11
___
$code.=<<___ if ($win64);
lea -0x88(%rsp),%rax
@@ -1715,11 +1755,13 @@ $code.=<<___ if ($win64);
movaps -0x38(%r11),%xmm13
movaps -0x28(%r11),%xmm14
movaps -0x18(%r11),%xmm15
.LSEH_end_rsaz_1024_gather5:
___
$code.=<<___;
lea (%r11),%rsp
.cfi_def_cfa_register %rsp
ret
.cfi_endproc
.LSEH_end_rsaz_1024_gather5:
.size rsaz_1024_gather5_avx2,.-rsaz_1024_gather5_avx2
___
}
@@ -1792,14 +1834,17 @@ rsaz_se_handler:
cmp %r10,%rbx # context->Rip<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 160($context),%rax # pull context->Rbp
mov 160($context),%rbp # pull context->Rbp
mov 8(%r11),%r10d # HandlerData[2]
lea (%rsi,%r10),%r10 # "in tail" label
cmp %r10,%rbx # context->Rip>="in tail" label
cmovc %rbp,%rax
mov -48(%rax),%r15
mov -40(%rax),%r14
@@ -1877,11 +1922,13 @@ rsaz_se_handler:
.LSEH_info_rsaz_1024_sqr_avx2:
.byte 9,0,0,0
.rva rsaz_se_handler
.rva .Lsqr_1024_body,.Lsqr_1024_epilogue
.rva .Lsqr_1024_body,.Lsqr_1024_epilogue,.Lsqr_1024_in_tail
.long 0
.LSEH_info_rsaz_1024_mul_avx2:
.byte 9,0,0,0
.rva rsaz_se_handler
.rva .Lmul_1024_body,.Lmul_1024_epilogue
.rva .Lmul_1024_body,.Lmul_1024_epilogue,.Lmul_1024_in_tail
.long 0
.LSEH_info_rsaz_1024_gather5:
.byte 0x01,0x36,0x17,0x0b
.byte 0x36,0xf8,0x09,0x00 # vmovaps 0x90(rsp),xmm15
File diff suppressed because it is too large Load Diff
Regular → Executable
+44 -19
View File
@@ -32,7 +32,7 @@ require "x86asm.pl";
$output = pop;
open STDOUT,">$output";
&asm_init($ARGV[0],$0);
$sse2=0;
@@ -66,33 +66,57 @@ $frame=32; # size of above frame rounded up to 16n
&lea ("esi",&wparam(0)); # put aside pointer to argument block
&lea ("edx",&wparam(1)); # load ap
&mov ("ebp","esp"); # saved stack pointer!
&add ("edi",2); # extra two words on top of tp
&neg ("edi");
&lea ("esp",&DWP(-$frame,"esp","edi",4)); # alloca($frame+4*(num+2))
&lea ("ebp",&DWP(-$frame,"esp","edi",4)); # future alloca($frame+4*(num+2))
&neg ("edi");
# minimize cache contention by arraning 2K window between stack
# pointer and ap argument [np is also position sensitive vector,
# but it's assumed to be near ap, as it's allocated at ~same
# time].
&mov ("eax","esp");
&mov ("eax","ebp");
&sub ("eax","edx");
&and ("eax",2047);
&sub ("esp","eax"); # this aligns sp and ap modulo 2048
&sub ("ebp","eax"); # this aligns sp and ap modulo 2048
&xor ("edx","esp");
&xor ("edx","ebp");
&and ("edx",2048);
&xor ("edx",2048);
&sub ("esp","edx"); # this splits them apart modulo 4096
&sub ("ebp","edx"); # this splits them apart modulo 4096
&and ("esp",-64); # align to cache line
&and ("ebp",-64); # align to cache line
# An OS-agnostic version of __chkstk.
#
# Some OSes (Windows) insist on stack being "wired" to
# physical memory in strictly sequential manner, i.e. if stack
# allocation spans two pages, then reference to farmost one can
# be punishable by SEGV. But page walking can do good even on
# other OSes, because it guarantees that villain thread hits
# the guard page before it can make damage to innocent one...
&mov ("eax","esp");
&sub ("eax","ebp");
&and ("eax",-4096);
&mov ("edx","esp"); # saved stack pointer!
&lea ("esp",&DWP(0,"ebp","eax"));
&mov ("eax",&DWP(0,"esp"));
&cmp ("esp","ebp");
&ja (&label("page_walk"));
&jmp (&label("page_walk_done"));
&set_label("page_walk",16);
&lea ("esp",&DWP(-4096,"esp"));
&mov ("eax",&DWP(0,"esp"));
&cmp ("esp","ebp");
&ja (&label("page_walk"));
&set_label("page_walk_done");
################################# load argument block...
&mov ("eax",&DWP(0*4,"esi"));# BN_ULONG *rp
&mov ("ebx",&DWP(1*4,"esi"));# const BN_ULONG *ap
&mov ("ecx",&DWP(2*4,"esi"));# const BN_ULONG *bp
&mov ("edx",&DWP(3*4,"esi"));# const BN_ULONG *np
&mov ("ebp",&DWP(3*4,"esi"));# const BN_ULONG *np
&mov ("esi",&DWP(4*4,"esi"));# const BN_ULONG *n0
#&mov ("edi",&DWP(5*4,"esi"));# int num
@@ -100,11 +124,11 @@ $frame=32; # size of above frame rounded up to 16n
&mov ($_rp,"eax"); # ... save a copy of argument block
&mov ($_ap,"ebx");
&mov ($_bp,"ecx");
&mov ($_np,"edx");
&mov ($_np,"ebp");
&mov ($_n0,"esi");
&lea ($num,&DWP(-3,"edi")); # num=num-1 to assist modulo-scheduling
#&mov ($_num,$num); # redundant as $num is not reused
&mov ($_sp,"ebp"); # saved stack pointer!
&mov ($_sp,"edx"); # saved stack pointer!
if($sse2) {
$acc0="mm0"; # mmx register bank layout
@@ -270,7 +294,7 @@ if (0) {
&xor ("eax","eax"); # signal "not fast enough [yet]"
&jmp (&label("just_leave"));
# While the below code provides competitive performance for
# all key lengthes on modern Intel cores, it's still more
# all key lengths on modern Intel cores, it's still more
# than 10% slower for 4096-bit key elsewhere:-( "Competitive"
# means compared to the original integer-only assembler.
# 512-bit RSA sign is better by ~40%, but that's about all
@@ -573,15 +597,16 @@ $sbit=$num;
&jge (&label("sub"));
&sbb ("eax",0); # handle upmost overflow bit
&and ($tp,"eax");
&not ("eax");
&mov ($np,$rp);
&and ($np,"eax");
&or ($tp,$np); # tp=carry?tp:rp
&set_label("copy",16); # copy or in-place refresh
&mov ("edx",&DWP(0,$tp,$num,4));
&mov ($np,&DWP(0,$rp,$num,4));
&xor ("edx",$np); # conditional select
&and ("edx","eax");
&xor ("edx",$np);
&mov (&DWP(0,$tp,$num,4),$j) # zap temporary vector
&mov (&DWP(0,$rp,$num,4),"edx"); # rp[i]=tp[i]
&mov ("eax",&DWP(0,$tp,$num,4));
&mov (&DWP(0,$rp,$num,4),"eax"); # rp[i]=tp[i]
&mov (&DWP($frame,"esp",$num,4),$j); # zap temporary vector
&dec ($num);
&jge (&label("copy"));
+229 -85
View File
@@ -84,6 +84,10 @@ $code=<<___;
.type bn_mul_mont,\@function,6
.align 16
bn_mul_mont:
.cfi_startproc
mov ${num}d,${num}d
mov %rsp,%rax
.cfi_def_cfa_register %rax
test \$3,${num}d
jnz .Lmul_enter
cmp \$8,${num}d
@@ -102,20 +106,50 @@ $code.=<<___;
.align 16
.Lmul_enter:
push %rbx
.cfi_push %rbx
push %rbp
.cfi_push %rbp
push %r12
.cfi_push %r12
push %r13
.cfi_push %r13
push %r14
.cfi_push %r14
push %r15
.cfi_push %r15
mov ${num}d,${num}d
lea 2($num),%r10
neg $num
mov %rsp,%r11
neg %r10
lea (%rsp,%r10,8),%rsp # tp=alloca(8*(num+2))
and \$-1024,%rsp # minimize TLB usage
lea -16(%rsp,$num,8),%r10 # future alloca(8*(num+2))
neg $num # restore $num
and \$-1024,%r10 # minimize TLB usage
mov %r11,8(%rsp,$num,8) # tp[num+1]=%rsp
# An OS-agnostic version of __chkstk.
#
# Some OSes (Windows) insist on stack being "wired" to
# physical memory in strictly sequential manner, i.e. if stack
# allocation spans two pages, then reference to farmost one can
# be punishable by SEGV. But page walking can do good even on
# other OSes, because it guarantees that villain thread hits
# the guard page before it can make damage to innocent one...
sub %r10,%r11
and \$-4096,%r11
lea (%r10,%r11),%rsp
mov (%rsp),%r11
cmp %r10,%rsp
ja .Lmul_page_walk
jmp .Lmul_page_walk_done
.align 16
.Lmul_page_walk:
lea -4096(%rsp),%rsp
mov (%rsp),%r11
cmp %r10,%rsp
ja .Lmul_page_walk
.Lmul_page_walk_done:
mov %rax,8(%rsp,$num,8) # tp[num+1]=%rsp
.cfi_cfa_expression %rsp+8,$num,8,mul,plus,deref,+8
.Lmul_body:
mov $bp,%r12 # reassign $bp
___
@@ -265,36 +299,46 @@ $code.=<<___;
mov %rax,($rp,$i,8) # rp[i]=tp[i]-np[i]
mov 8($ap,$i,8),%rax # tp[i+1]
lea 1($i),$i # i++
dec $j # doesn't affect CF!
dec $j # doesnn't affect CF!
jnz .Lsub
sbb \$0,%rax # handle upmost overflow bit
xor $i,$i
and %rax,$ap
not %rax
mov $rp,$np
and %rax,$np
mov $num,$j # j=num
or $np,$ap # ap=borrow?tp:rp
.align 16
.Lcopy: # copy or in-place refresh
mov (%rsp,$i,8),$ap
mov ($rp,$i,8),$np
xor $np,$ap # conditional select:
and %rax,$ap # ((ap ^ np) & %rax) ^ np
xor $np,$ap # ap = borrow?tp:rp
mov ($ap,$i,8),%rax
mov $i,(%rsp,$i,8) # zap temporary vector
mov $ap,($rp,$i,8) # rp[i]=tp[i]
mov %rax,($rp,$i,8) # rp[i]=tp[i]
lea 1($i),$i
sub \$1,$j
jnz .Lcopy
mov 8(%rsp,$num,8),%rsi # restore %rsp
.cfi_def_cfa %rsi,8
mov \$1,%rax
mov (%rsi),%r15
mov 8(%rsi),%r14
mov 16(%rsi),%r13
mov 24(%rsi),%r12
mov 32(%rsi),%rbp
mov 40(%rsi),%rbx
lea 48(%rsi),%rsp
mov -48(%rsi),%r15
.cfi_restore %r15
mov -40(%rsi),%r14
.cfi_restore %r14
mov -32(%rsi),%r13
.cfi_restore %r13
mov -24(%rsi),%r12
.cfi_restore %r12
mov -16(%rsi),%rbp
.cfi_restore %rbp
mov -8(%rsi),%rbx
.cfi_restore %rbx
lea (%rsi),%rsp
.cfi_def_cfa_register %rsp
.Lmul_epilogue:
ret
.cfi_endproc
.size bn_mul_mont,.-bn_mul_mont
___
{{{
@@ -304,6 +348,10 @@ $code.=<<___;
.type bn_mul4x_mont,\@function,6
.align 16
bn_mul4x_mont:
.cfi_startproc
mov ${num}d,${num}d
mov %rsp,%rax
.cfi_def_cfa_register %rax
.Lmul4x_enter:
___
$code.=<<___ if ($addx);
@@ -313,20 +361,41 @@ $code.=<<___ if ($addx);
___
$code.=<<___;
push %rbx
.cfi_push %rbx
push %rbp
.cfi_push %rbp
push %r12
.cfi_push %r12
push %r13
.cfi_push %r13
push %r14
.cfi_push %r14
push %r15
.cfi_push %r15
mov ${num}d,${num}d
lea 4($num),%r10
neg $num
mov %rsp,%r11
neg %r10
lea (%rsp,%r10,8),%rsp # tp=alloca(8*(num+4))
and \$-1024,%rsp # minimize TLB usage
lea -32(%rsp,$num,8),%r10 # future alloca(8*(num+4))
neg $num # restore
and \$-1024,%r10 # minimize TLB usage
mov %r11,8(%rsp,$num,8) # tp[num+1]=%rsp
sub %r10,%r11
and \$-4096,%r11
lea (%r10,%r11),%rsp
mov (%rsp),%r11
cmp %r10,%rsp
ja .Lmul4x_page_walk
jmp .Lmul4x_page_walk_done
.Lmul4x_page_walk:
lea -4096(%rsp),%rsp
mov (%rsp),%r11
cmp %r10,%rsp
ja .Lmul4x_page_walk
.Lmul4x_page_walk_done:
mov %rax,8(%rsp,$num,8) # tp[num+1]=%rsp
.cfi_cfa_expression %rsp+8,$num,8,mul,plus,deref,+8
.Lmul4x_body:
mov $rp,16(%rsp,$num,8) # tp[num+2]=$rp
mov %rdx,%r12 # reassign $bp
@@ -633,9 +702,11 @@ ___
my @ri=("%rax","%rdx",$m0,$m1);
$code.=<<___;
mov 16(%rsp,$num,8),$rp # restore $rp
lea -4($num),$j
mov 0(%rsp),@ri[0] # tp[0]
pxor %xmm0,%xmm0
mov 8(%rsp),@ri[1] # tp[1]
shr \$2,$num # num/=4
shr \$2,$j # j=num/4-1
lea (%rsp),$ap # borrow ap for tp
xor $i,$i # i=0 and clear CF!
@@ -643,7 +714,6 @@ $code.=<<___;
mov 16($ap),@ri[2] # tp[2]
mov 24($ap),@ri[3] # tp[3]
sbb 8($np),@ri[1]
lea -1($num),$j # j=num/4-1
jmp .Lsub4x
.align 16
.Lsub4x:
@@ -671,50 +741,58 @@ $code.=<<___;
mov @ri[2],16($rp,$i,8) # rp[i]=tp[i]-np[i]
sbb \$0,@ri[0] # handle upmost overflow bit
mov @ri[0],%xmm0
punpcklqdq %xmm0,%xmm0 # extend mask to 128 bits
mov @ri[3],24($rp,$i,8) # rp[i]=tp[i]-np[i]
xor $i,$i # i=0
and @ri[0],$ap
not @ri[0]
mov $rp,$np
and @ri[0],$np
lea -4($num),$j
or $np,$ap # ap=borrow?tp:rp
shr \$2,$j # j=num/4-1
mov $num,$j
pxor %xmm5,%xmm5
movdqu ($ap),%xmm1
movdqa %xmm0,(%rsp)
movdqu %xmm1,($rp)
jmp .Lcopy4x
.align 16
.Lcopy4x: # copy or in-place refresh
movdqu (%rsp,$i),%xmm2
movdqu 16(%rsp,$i),%xmm4
movdqu ($rp,$i),%xmm1
movdqu 16($rp,$i),%xmm3
pxor %xmm1,%xmm2 # conditional select
pxor %xmm3,%xmm4
pand %xmm0,%xmm2
pand %xmm0,%xmm4
pxor %xmm1,%xmm2
pxor %xmm3,%xmm4
movdqu %xmm2,($rp,$i)
movdqu %xmm4,16($rp,$i)
movdqa %xmm5,(%rsp,$i) # zap temporary vectors
movdqa %xmm5,16(%rsp,$i)
.Lcopy4x: # copy or in-place refresh
movdqu 16($ap,$i),%xmm2
movdqu 32($ap,$i),%xmm1
movdqa %xmm0,16(%rsp,$i)
movdqu %xmm2,16($rp,$i)
movdqa %xmm0,32(%rsp,$i)
movdqu %xmm1,32($rp,$i)
lea 32($i),$i
dec $j
jnz .Lcopy4x
shl \$2,$num
movdqu 16($ap,$i),%xmm2
movdqa %xmm0,16(%rsp,$i)
movdqu %xmm2,16($rp,$i)
___
}
$code.=<<___;
mov 8(%rsp,$num,8),%rsi # restore %rsp
.cfi_def_cfa %rsi, 8
mov \$1,%rax
mov (%rsi),%r15
mov 8(%rsi),%r14
mov 16(%rsi),%r13
mov 24(%rsi),%r12
mov 32(%rsi),%rbp
mov 40(%rsi),%rbx
lea 48(%rsi),%rsp
mov -48(%rsi),%r15
.cfi_restore %r15
mov -40(%rsi),%r14
.cfi_restore %r14
mov -32(%rsi),%r13
.cfi_restore %r13
mov -24(%rsi),%r12
.cfi_restore %r12
mov -16(%rsi),%rbp
.cfi_restore %rbp
mov -8(%rsi),%rbx
.cfi_restore %rbx
lea (%rsi),%rsp
.cfi_def_cfa_register %rsp
.Lmul4x_epilogue:
ret
.cfi_endproc
.size bn_mul4x_mont,.-bn_mul4x_mont
___
}}}
@@ -742,14 +820,23 @@ $code.=<<___;
.type bn_sqr8x_mont,\@function,6
.align 32
bn_sqr8x_mont:
.Lsqr8x_enter:
.cfi_startproc
mov %rsp,%rax
.cfi_def_cfa_register %rax
.Lsqr8x_enter:
push %rbx
.cfi_push %rbx
push %rbp
.cfi_push %rbp
push %r12
.cfi_push %r12
push %r13
.cfi_push %r13
push %r14
.cfi_push %r14
push %r15
.cfi_push %r15
.Lsqr8x_prologue:
mov ${num}d,%r10d
shl \$3,${num}d # convert $num to bytes
@@ -762,30 +849,49 @@ bn_sqr8x_mont:
# do its job.
#
lea -64(%rsp,$num,2),%r11
mov %rsp,%rbp
mov ($n0),$n0 # *n0
sub $aptr,%r11
and \$4095,%r11
cmp %r11,%r10
jb .Lsqr8x_sp_alt
sub %r11,%rsp # align with $aptr
lea -64(%rsp,$num,2),%rsp # alloca(frame+2*$num)
sub %r11,%rbp # align with $aptr
lea -64(%rbp,$num,2),%rbp # future alloca(frame+2*$num)
jmp .Lsqr8x_sp_done
.align 32
.Lsqr8x_sp_alt:
lea 4096-64(,$num,2),%r10 # 4096-frame-2*$num
lea -64(%rsp,$num,2),%rsp # alloca(frame+2*$num)
lea -64(%rbp,$num,2),%rbp # future alloca(frame+2*$num)
sub %r10,%r11
mov \$0,%r10
cmovc %r10,%r11
sub %r11,%rsp
sub %r11,%rbp
.Lsqr8x_sp_done:
and \$-64,%rsp
and \$-64,%rbp
mov %rsp,%r11
sub %rbp,%r11
and \$-4096,%r11
lea (%rbp,%r11),%rsp
mov (%rsp),%r10
cmp %rbp,%rsp
ja .Lsqr8x_page_walk
jmp .Lsqr8x_page_walk_done
.align 16
.Lsqr8x_page_walk:
lea -4096(%rsp),%rsp
mov (%rsp),%r10
cmp %rbp,%rsp
ja .Lsqr8x_page_walk
.Lsqr8x_page_walk_done:
mov $num,%r10
neg $num
mov $n0, 32(%rsp)
mov %rax, 40(%rsp) # save original %rsp
.cfi_cfa_expression %rsp+40,deref,+8
.Lsqr8x_body:
movq $nptr, %xmm2 # save pointer to modulus
@@ -855,6 +961,7 @@ $code.=<<___;
pxor %xmm0,%xmm0
pshufd \$0,%xmm1,%xmm1
mov 40(%rsp),%rsi # restore %rsp
.cfi_def_cfa %rsi,8
jmp .Lsqr8x_cond_copy
.align 32
@@ -884,14 +991,22 @@ $code.=<<___;
mov \$1,%rax
mov -48(%rsi),%r15
.cfi_restore %r15
mov -40(%rsi),%r14
.cfi_restore %r14
mov -32(%rsi),%r13
.cfi_restore %r13
mov -24(%rsi),%r12
.cfi_restore %r12
mov -16(%rsi),%rbp
.cfi_restore %rbp
mov -8(%rsi),%rbx
.cfi_restore %rbx
lea (%rsi),%rsp
.cfi_def_cfa_register %rsp
.Lsqr8x_epilogue:
ret
.cfi_endproc
.size bn_sqr8x_mont,.-bn_sqr8x_mont
___
}}}
@@ -903,23 +1018,48 @@ $code.=<<___;
.type bn_mulx4x_mont,\@function,6
.align 32
bn_mulx4x_mont:
.Lmulx4x_enter:
.cfi_startproc
mov %rsp,%rax
.cfi_def_cfa_register %rax
.Lmulx4x_enter:
push %rbx
.cfi_push %rbx
push %rbp
.cfi_push %rbp
push %r12
.cfi_push %r12
push %r13
.cfi_push %r13
push %r14
.cfi_push %r14
push %r15
.cfi_push %r15
.Lmulx4x_prologue:
shl \$3,${num}d # convert $num to bytes
.byte 0x67
xor %r10,%r10
sub $num,%r10 # -$num
mov ($n0),$n0 # *n0
lea -72(%rsp,%r10),%rsp # alloca(frame+$num+8)
lea -72(%rsp,%r10),%rbp # future alloca(frame+$num+8)
and \$-128,%rbp
mov %rsp,%r11
sub %rbp,%r11
and \$-4096,%r11
lea (%rbp,%r11),%rsp
mov (%rsp),%r10
cmp %rbp,%rsp
ja .Lmulx4x_page_walk
jmp .Lmulx4x_page_walk_done
.align 16
.Lmulx4x_page_walk:
lea -4096(%rsp),%rsp
mov (%rsp),%r10
cmp %rbp,%rsp
ja .Lmulx4x_page_walk
.Lmulx4x_page_walk_done:
lea ($bp,$num),%r10
and \$-128,%rsp
##############################################################
# Stack layout
# +0 num
@@ -939,6 +1079,7 @@ bn_mulx4x_mont:
mov $n0, 24(%rsp) # save *n0
mov $rp, 32(%rsp) # save $rp
mov %rax,40(%rsp) # save original %rsp
.cfi_cfa_expression %rsp+40,deref,+8
mov $num,48(%rsp) # inner counter
jmp .Lmulx4x_body
@@ -1188,6 +1329,7 @@ $code.=<<___;
pxor %xmm0,%xmm0
pshufd \$0,%xmm1,%xmm1
mov 40(%rsp),%rsi # restore %rsp
.cfi_def_cfa %rsi,8
jmp .Lmulx4x_cond_copy
.align 32
@@ -1217,14 +1359,22 @@ $code.=<<___;
mov \$1,%rax
mov -48(%rsi),%r15
.cfi_restore %r15
mov -40(%rsi),%r14
.cfi_restore %r14
mov -32(%rsi),%r13
.cfi_restore %r13
mov -24(%rsi),%r12
.cfi_restore %r12
mov -16(%rsi),%rbp
.cfi_restore %rbp
mov -8(%rsi),%rbx
.cfi_restore %rbx
lea (%rsi),%rsp
.cfi_def_cfa_register %rsp
.Lmulx4x_epilogue:
ret
.cfi_endproc
.size bn_mulx4x_mont,.-bn_mulx4x_mont
___
}}}
@@ -1277,22 +1427,8 @@ mul_handler:
mov 192($context),%r10 # pull $num
mov 8(%rax,%r10,8),%rax # pull saved stack pointer
lea 48(%rax),%rax
mov -8(%rax),%rbx
mov -16(%rax),%rbp
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
jmp .Lcommon_seh_tail
jmp .Lcommon_pop_regs
.size mul_handler,.-mul_handler
.type sqr_handler,\@abi-omnipotent
@@ -1317,18 +1453,24 @@ sqr_handler:
mov 0(%r11),%r10d # HandlerData[0]
lea (%rsi,%r10),%r10 # end of prologue label
cmp %r10,%rbx # context->Rip<.Lsqr_body
cmp %r10,%rbx # context->Rip<.Lsqr_prologue
jb .Lcommon_seh_tail
mov 4(%r11),%r10d # HandlerData[1]
lea (%rsi,%r10),%r10 # body label
cmp %r10,%rbx # context->Rip<.Lsqr_body
jb .Lcommon_pop_regs
mov 152($context),%rax # pull context->Rsp
mov 4(%r11),%r10d # HandlerData[1]
mov 8(%r11),%r10d # HandlerData[2]
lea (%rsi,%r10),%r10 # epilogue label
cmp %r10,%rbx # context->Rip>=.Lsqr_epilogue
jae .Lcommon_seh_tail
mov 40(%rax),%rax # pull saved stack pointer
.Lcommon_pop_regs:
mov -8(%rax),%rbx
mov -16(%rax),%rbp
mov -24(%rax),%r12
@@ -1415,13 +1557,15 @@ $code.=<<___;
.LSEH_info_bn_sqr8x_mont:
.byte 9,0,0,0
.rva sqr_handler
.rva .Lsqr8x_body,.Lsqr8x_epilogue # HandlerData[]
.rva .Lsqr8x_prologue,.Lsqr8x_body,.Lsqr8x_epilogue # HandlerData[]
.align 8
___
$code.=<<___ if ($addx);
.LSEH_info_bn_mulx4x_mont:
.byte 9,0,0,0
.rva sqr_handler
.rva .Lmulx4x_body,.Lmulx4x_epilogue # HandlerData[]
.rva .Lmulx4x_prologue,.Lmulx4x_body,.Lmulx4x_epilogue # HandlerData[]
.align 8
___
}
+295 -69
View File
@@ -73,6 +73,10 @@ $code=<<___;
.type bn_mul_mont_gather5,\@function,6
.align 64
bn_mul_mont_gather5:
.cfi_startproc
mov ${num}d,${num}d
mov %rsp,%rax
.cfi_def_cfa_register %rax
test \$7,${num}d
jnz .Lmul_enter
___
@@ -84,24 +88,54 @@ $code.=<<___;
.align 16
.Lmul_enter:
mov ${num}d,${num}d
mov %rsp,%rax
movd `($win64?56:8)`(%rsp),%xmm5 # load 7th argument
lea .Linc(%rip),%r10
push %rbx
.cfi_push %rbx
push %rbp
.cfi_push %rbp
push %r12
.cfi_push %r12
push %r13
.cfi_push %r13
push %r14
.cfi_push %r14
push %r15
.cfi_push %r15
lea 2($num),%r11
neg %r11
lea -264(%rsp,%r11,8),%rsp # tp=alloca(8*(num+2)+256+8)
and \$-1024,%rsp # minimize TLB usage
neg $num
mov %rsp,%r11
lea -280(%rsp,$num,8),%r10 # future alloca(8*(num+2)+256+8)
neg $num # restore $num
and \$-1024,%r10 # minimize TLB usage
# An OS-agnostic version of __chkstk.
#
# Some OSes (Windows) insist on stack being "wired" to
# physical memory in strictly sequential manner, i.e. if stack
# allocation spans two pages, then reference to farmost one can
# be punishable by SEGV. But page walking can do good even on
# other OSes, because it guarantees that villain thread hits
# the guard page before it can make damage to innocent one...
sub %r10,%r11
and \$-4096,%r11
lea (%r10,%r11),%rsp
mov (%rsp),%r11
cmp %r10,%rsp
ja .Lmul_page_walk
jmp .Lmul_page_walk_done
.Lmul_page_walk:
lea -4096(%rsp),%rsp
mov (%rsp),%r11
cmp %r10,%rsp
ja .Lmul_page_walk
.Lmul_page_walk_done:
lea .Linc(%rip),%r10
mov %rax,8(%rsp,$num,8) # tp[num+1]=%rsp
.cfi_cfa_expression %rsp+8,$num,8,mul,plus,deref,+8
.Lmul_body:
lea 128($bp),%r12 # reassign $bp (+size optimization)
___
$bp="%r12";
@@ -370,32 +404,42 @@ $code.=<<___;
sbb \$0,%rax # handle upmost overflow bit
xor $i,$i
and %rax,$ap
not %rax
mov $rp,$np
and %rax,$np
mov $num,$j # j=num
or $np,$ap # ap=borrow?tp:rp
.align 16
.Lcopy: # copy or in-place refresh
mov (%rsp,$i,8),$ap
mov ($rp,$i,8),$np
xor $np,$ap # conditional select:
and %rax,$ap # ((ap ^ np) & %rax) ^ np
xor $np,$ap # ap = borrow?tp:rp
mov ($ap,$i,8),%rax
mov $i,(%rsp,$i,8) # zap temporary vector
mov $ap,($rp,$i,8) # rp[i]=tp[i]
mov %rax,($rp,$i,8) # rp[i]=tp[i]
lea 1($i),$i
sub \$1,$j
jnz .Lcopy
mov 8(%rsp,$num,8),%rsi # restore %rsp
.cfi_def_cfa %rsi,8
mov \$1,%rax
mov -48(%rsi),%r15
.cfi_restore %r15
mov -40(%rsi),%r14
.cfi_restore %r14
mov -32(%rsi),%r13
.cfi_restore %r13
mov -24(%rsi),%r12
.cfi_restore %r12
mov -16(%rsi),%rbp
.cfi_restore %rbp
mov -8(%rsi),%rbx
.cfi_restore %rbx
lea (%rsi),%rsp
.cfi_def_cfa_register %rsp
.Lmul_epilogue:
ret
.cfi_endproc
.size bn_mul_mont_gather5,.-bn_mul_mont_gather5
___
{{{
@@ -405,6 +449,10 @@ $code.=<<___;
.type bn_mul4x_mont_gather5,\@function,6
.align 32
bn_mul4x_mont_gather5:
.cfi_startproc
.byte 0x67
mov %rsp,%rax
.cfi_def_cfa_register %rax
.Lmul4x_enter:
___
$code.=<<___ if ($addx);
@@ -413,14 +461,19 @@ $code.=<<___ if ($addx);
je .Lmulx4x_enter
___
$code.=<<___;
.byte 0x67
mov %rsp,%rax
push %rbx
.cfi_push %rbx
push %rbp
.cfi_push %rbp
push %r12
.cfi_push %r12
push %r13
.cfi_push %r13
push %r14
.cfi_push %r14
push %r15
.cfi_push %r15
.Lmul4x_prologue:
.byte 0x67
shl \$3,${num}d # convert $num to bytes
@@ -437,43 +490,70 @@ $code.=<<___;
# calculated from 7th argument, the index.]
#
lea -320(%rsp,$num,2),%r11
mov %rsp,%rbp
sub $rp,%r11
and \$4095,%r11
cmp %r11,%r10
jb .Lmul4xsp_alt
sub %r11,%rsp # align with $rp
lea -320(%rsp,$num,2),%rsp # alloca(frame+2*num*8+256)
sub %r11,%rbp # align with $rp
lea -320(%rbp,$num,2),%rbp # future alloca(frame+2*num*8+256)
jmp .Lmul4xsp_done
.align 32
.Lmul4xsp_alt:
lea 4096-320(,$num,2),%r10
lea -320(%rsp,$num,2),%rsp # alloca(frame+2*num*8+256)
lea -320(%rbp,$num,2),%rbp # future alloca(frame+2*num*8+256)
sub %r10,%r11
mov \$0,%r10
cmovc %r10,%r11
sub %r11,%rsp
sub %r11,%rbp
.Lmul4xsp_done:
and \$-64,%rsp
and \$-64,%rbp
mov %rsp,%r11
sub %rbp,%r11
and \$-4096,%r11
lea (%rbp,%r11),%rsp
mov (%rsp),%r10
cmp %rbp,%rsp
ja .Lmul4x_page_walk
jmp .Lmul4x_page_walk_done
.Lmul4x_page_walk:
lea -4096(%rsp),%rsp
mov (%rsp),%r10
cmp %rbp,%rsp
ja .Lmul4x_page_walk
.Lmul4x_page_walk_done:
neg $num
mov %rax,40(%rsp)
.cfi_cfa_expression %rsp+40,deref,+8
.Lmul4x_body:
call mul4x_internal
mov 40(%rsp),%rsi # restore %rsp
.cfi_def_cfa %rsi,8
mov \$1,%rax
mov -48(%rsi),%r15
.cfi_restore %r15
mov -40(%rsi),%r14
.cfi_restore %r14
mov -32(%rsi),%r13
.cfi_restore %r13
mov -24(%rsi),%r12
.cfi_restore %r12
mov -16(%rsi),%rbp
.cfi_restore %rbp
mov -8(%rsi),%rbx
.cfi_restore %rbx
lea (%rsi),%rsp
.cfi_def_cfa_register %rsp
.Lmul4x_epilogue:
ret
.cfi_endproc
.size bn_mul4x_mont_gather5,.-bn_mul4x_mont_gather5
.type mul4x_internal,\@abi-omnipotent
@@ -985,7 +1065,7 @@ my $bptr="%rdx"; # const void *table,
my $nptr="%rcx"; # const BN_ULONG *nptr,
my $n0 ="%r8"; # const BN_ULONG *n0);
my $num ="%r9"; # int num, has to be divisible by 8
# int pwr
# int pwr
my ($i,$j,$tptr)=("%rbp","%rcx",$rptr);
my @A0=("%r10","%r11");
@@ -997,6 +1077,9 @@ $code.=<<___;
.type bn_power5,\@function,6
.align 32
bn_power5:
.cfi_startproc
mov %rsp,%rax
.cfi_def_cfa_register %rax
___
$code.=<<___ if ($addx);
mov OPENSSL_ia32cap_P+8(%rip),%r11d
@@ -1005,13 +1088,19 @@ $code.=<<___ if ($addx);
je .Lpowerx5_enter
___
$code.=<<___;
mov %rsp,%rax
push %rbx
.cfi_push %rbx
push %rbp
.cfi_push %rbp
push %r12
.cfi_push %r12
push %r13
.cfi_push %r13
push %r14
.cfi_push %r14
push %r15
.cfi_push %r15
.Lpower5_prologue:
shl \$3,${num}d # convert $num to bytes
lea ($num,$num,2),%r10d # 3*$num
@@ -1026,25 +1115,42 @@ $code.=<<___;
# calculated from 7th argument, the index.]
#
lea -320(%rsp,$num,2),%r11
mov %rsp,%rbp
sub $rptr,%r11
and \$4095,%r11
cmp %r11,%r10
jb .Lpwr_sp_alt
sub %r11,%rsp # align with $aptr
lea -320(%rsp,$num,2),%rsp # alloca(frame+2*num*8+256)
sub %r11,%rbp # align with $aptr
lea -320(%rbp,$num,2),%rbp # future alloca(frame+2*num*8+256)
jmp .Lpwr_sp_done
.align 32
.Lpwr_sp_alt:
lea 4096-320(,$num,2),%r10
lea -320(%rsp,$num,2),%rsp # alloca(frame+2*num*8+256)
lea -320(%rbp,$num,2),%rbp # future alloca(frame+2*num*8+256)
sub %r10,%r11
mov \$0,%r10
cmovc %r10,%r11
sub %r11,%rsp
sub %r11,%rbp
.Lpwr_sp_done:
and \$-64,%rsp
mov $num,%r10
and \$-64,%rbp
mov %rsp,%r11
sub %rbp,%r11
and \$-4096,%r11
lea (%rbp,%r11),%rsp
mov (%rsp),%r10
cmp %rbp,%rsp
ja .Lpwr_page_walk
jmp .Lpwr_page_walk_done
.Lpwr_page_walk:
lea -4096(%rsp),%rsp
mov (%rsp),%r10
cmp %rbp,%rsp
ja .Lpwr_page_walk
.Lpwr_page_walk_done:
mov $num,%r10
neg $num
##############################################################
@@ -1058,6 +1164,7 @@ $code.=<<___;
#
mov $n0, 32(%rsp)
mov %rax, 40(%rsp) # save original %rsp
.cfi_cfa_expression %rsp+40,deref,+8
.Lpower5_body:
movq $rptr,%xmm1 # save $rptr, used in sqr8x
movq $nptr,%xmm2 # save $nptr
@@ -1084,16 +1191,25 @@ $code.=<<___;
call mul4x_internal
mov 40(%rsp),%rsi # restore %rsp
.cfi_def_cfa %rsi,8
mov \$1,%rax
mov -48(%rsi),%r15
.cfi_restore %r15
mov -40(%rsi),%r14
.cfi_restore %r14
mov -32(%rsi),%r13
.cfi_restore %r13
mov -24(%rsi),%r12
.cfi_restore %r12
mov -16(%rsi),%rbp
.cfi_restore %rbp
mov -8(%rsi),%rbx
.cfi_restore %rbx
lea (%rsi),%rsp
.cfi_def_cfa_register %rsp
.Lpower5_epilogue:
ret
.cfi_endproc
.size bn_power5,.-bn_power5
.globl bn_sqr8x_internal
@@ -1852,6 +1968,7 @@ __bn_sqr8x_reduction:
.align 32
.L8x_tail_done:
xor %rax,%rax
add (%rdx),%r8 # can this overflow?
adc \$0,%r9
adc \$0,%r10
@@ -1859,10 +1976,8 @@ __bn_sqr8x_reduction:
adc \$0,%r12
adc \$0,%r13
adc \$0,%r14
adc \$0,%r15 # can't overflow, because we
# started with "overhung" part
# of multiplication
xor %rax,%rax
adc \$0,%r15
adc \$0,%rax
neg $carry
.L8x_no_tail:
@@ -1954,7 +2069,7 @@ __bn_post4x_internal:
jnz .Lsqr4x_sub
mov $num,%r10 # prepare for back-to-back call
neg $num # restore $num
neg $num # restore $num
ret
.size __bn_post4x_internal,.-__bn_post4x_internal
___
@@ -1974,14 +2089,23 @@ bn_from_montgomery:
.type bn_from_mont8x,\@function,6
.align 32
bn_from_mont8x:
.cfi_startproc
.byte 0x67
mov %rsp,%rax
.cfi_def_cfa_register %rax
push %rbx
.cfi_push %rbx
push %rbp
.cfi_push %rbp
push %r12
.cfi_push %r12
push %r13
.cfi_push %r13
push %r14
.cfi_push %r14
push %r15
.cfi_push %r15
.Lfrom_prologue:
shl \$3,${num}d # convert $num to bytes
lea ($num,$num,2),%r10 # 3*$num in bytes
@@ -1996,25 +2120,42 @@ bn_from_mont8x:
# last operation, we use the opportunity to cleanse it.
#
lea -320(%rsp,$num,2),%r11
mov %rsp,%rbp
sub $rptr,%r11
and \$4095,%r11
cmp %r11,%r10
jb .Lfrom_sp_alt
sub %r11,%rsp # align with $aptr
lea -320(%rsp,$num,2),%rsp # alloca(frame+2*$num*8+256)
sub %r11,%rbp # align with $aptr
lea -320(%rbp,$num,2),%rbp # future alloca(frame+2*$num*8+256)
jmp .Lfrom_sp_done
.align 32
.Lfrom_sp_alt:
lea 4096-320(,$num,2),%r10
lea -320(%rsp,$num,2),%rsp # alloca(frame+2*$num*8+256)
lea -320(%rbp,$num,2),%rbp # future alloca(frame+2*$num*8+256)
sub %r10,%r11
mov \$0,%r10
cmovc %r10,%r11
sub %r11,%rsp
sub %r11,%rbp
.Lfrom_sp_done:
and \$-64,%rsp
mov $num,%r10
and \$-64,%rbp
mov %rsp,%r11
sub %rbp,%r11
and \$-4096,%r11
lea (%rbp,%r11),%rsp
mov (%rsp),%r10
cmp %rbp,%rsp
ja .Lfrom_page_walk
jmp .Lfrom_page_walk_done
.Lfrom_page_walk:
lea -4096(%rsp),%rsp
mov (%rsp),%r10
cmp %rbp,%rsp
ja .Lfrom_page_walk
.Lfrom_page_walk_done:
mov $num,%r10
neg $num
##############################################################
@@ -2028,6 +2169,7 @@ bn_from_mont8x:
#
mov $n0, 32(%rsp)
mov %rax, 40(%rsp) # save original %rsp
.cfi_cfa_expression %rsp+40,deref,+8
.Lfrom_body:
mov $num,%r11
lea 48(%rsp),%rax
@@ -2071,7 +2213,6 @@ $code.=<<___ if ($addx);
pxor %xmm0,%xmm0
lea 48(%rsp),%rax
mov 40(%rsp),%rsi # restore %rsp
jmp .Lfrom_mont_zero
.align 32
@@ -2083,11 +2224,12 @@ $code.=<<___;
pxor %xmm0,%xmm0
lea 48(%rsp),%rax
mov 40(%rsp),%rsi # restore %rsp
jmp .Lfrom_mont_zero
.align 32
.Lfrom_mont_zero:
mov 40(%rsp),%rsi # restore %rsp
.cfi_def_cfa %rsi,8
movdqa %xmm0,16*0(%rax)
movdqa %xmm0,16*1(%rax)
movdqa %xmm0,16*2(%rax)
@@ -2098,14 +2240,22 @@ $code.=<<___;
mov \$1,%rax
mov -48(%rsi),%r15
.cfi_restore %r15
mov -40(%rsi),%r14
.cfi_restore %r14
mov -32(%rsi),%r13
.cfi_restore %r13
mov -24(%rsi),%r12
.cfi_restore %r12
mov -16(%rsi),%rbp
.cfi_restore %rbp
mov -8(%rsi),%rbx
.cfi_restore %rbx
lea (%rsi),%rsp
.cfi_def_cfa_register %rsp
.Lfrom_epilogue:
ret
.cfi_endproc
.size bn_from_mont8x,.-bn_from_mont8x
___
}
@@ -2118,14 +2268,23 @@ $code.=<<___;
.type bn_mulx4x_mont_gather5,\@function,6
.align 32
bn_mulx4x_mont_gather5:
.Lmulx4x_enter:
.cfi_startproc
mov %rsp,%rax
.cfi_def_cfa_register %rax
.Lmulx4x_enter:
push %rbx
.cfi_push %rbx
push %rbp
.cfi_push %rbp
push %r12
.cfi_push %r12
push %r13
.cfi_push %r13
push %r14
.cfi_push %r14
push %r15
.cfi_push %r15
.Lmulx4x_prologue:
shl \$3,${num}d # convert $num to bytes
lea ($num,$num,2),%r10 # 3*$num in bytes
@@ -2142,23 +2301,40 @@ bn_mulx4x_mont_gather5:
# calculated from 7th argument, the index.]
#
lea -320(%rsp,$num,2),%r11
mov %rsp,%rbp
sub $rp,%r11
and \$4095,%r11
cmp %r11,%r10
jb .Lmulx4xsp_alt
sub %r11,%rsp # align with $aptr
lea -320(%rsp,$num,2),%rsp # alloca(frame+2*$num*8+256)
sub %r11,%rbp # align with $aptr
lea -320(%rbp,$num,2),%rbp # future alloca(frame+2*$num*8+256)
jmp .Lmulx4xsp_done
.Lmulx4xsp_alt:
lea 4096-320(,$num,2),%r10
lea -320(%rsp,$num,2),%rsp # alloca(frame+2*$num*8+256)
lea -320(%rbp,$num,2),%rbp # future alloca(frame+2*$num*8+256)
sub %r10,%r11
mov \$0,%r10
cmovc %r10,%r11
sub %r11,%rsp
.Lmulx4xsp_done:
and \$-64,%rsp # ensure alignment
sub %r11,%rbp
.Lmulx4xsp_done:
and \$-64,%rbp # ensure alignment
mov %rsp,%r11
sub %rbp,%r11
and \$-4096,%r11
lea (%rbp,%r11),%rsp
mov (%rsp),%r10
cmp %rbp,%rsp
ja .Lmulx4x_page_walk
jmp .Lmulx4x_page_walk_done
.Lmulx4x_page_walk:
lea -4096(%rsp),%rsp
mov (%rsp),%r10
cmp %rbp,%rsp
ja .Lmulx4x_page_walk
.Lmulx4x_page_walk_done:
##############################################################
# Stack layout
# +0 -num
@@ -2173,21 +2349,31 @@ bn_mulx4x_mont_gather5:
#
mov $n0, 32(%rsp) # save *n0
mov %rax,40(%rsp) # save original %rsp
.cfi_cfa_expression %rsp+40,deref,+8
.Lmulx4x_body:
call mulx4x_internal
mov 40(%rsp),%rsi # restore %rsp
.cfi_def_cfa %rsi,8
mov \$1,%rax
mov -48(%rsi),%r15
.cfi_restore %r15
mov -40(%rsi),%r14
.cfi_restore %r14
mov -32(%rsi),%r13
.cfi_restore %r13
mov -24(%rsi),%r12
.cfi_restore %r12
mov -16(%rsi),%rbp
.cfi_restore %rbp
mov -8(%rsi),%rbx
.cfi_restore %rbx
lea (%rsi),%rsp
.cfi_def_cfa_register %rsp
.Lmulx4x_epilogue:
ret
.cfi_endproc
.size bn_mulx4x_mont_gather5,.-bn_mulx4x_mont_gather5
.type mulx4x_internal,\@abi-omnipotent
@@ -2565,14 +2751,23 @@ $code.=<<___;
.type bn_powerx5,\@function,6
.align 32
bn_powerx5:
.Lpowerx5_enter:
.cfi_startproc
mov %rsp,%rax
.cfi_def_cfa_register %rax
.Lpowerx5_enter:
push %rbx
.cfi_push %rbx
push %rbp
.cfi_push %rbp
push %r12
.cfi_push %r12
push %r13
.cfi_push %r13
push %r14
.cfi_push %r14
push %r15
.cfi_push %r15
.Lpowerx5_prologue:
shl \$3,${num}d # convert $num to bytes
lea ($num,$num,2),%r10 # 3*$num in bytes
@@ -2587,25 +2782,42 @@ bn_powerx5:
# calculated from 7th argument, the index.]
#
lea -320(%rsp,$num,2),%r11
mov %rsp,%rbp
sub $rptr,%r11
and \$4095,%r11
cmp %r11,%r10
jb .Lpwrx_sp_alt
sub %r11,%rsp # align with $aptr
lea -320(%rsp,$num,2),%rsp # alloca(frame+2*$num*8+256)
sub %r11,%rbp # align with $aptr
lea -320(%rbp,$num,2),%rbp # future alloca(frame+2*$num*8+256)
jmp .Lpwrx_sp_done
.align 32
.Lpwrx_sp_alt:
lea 4096-320(,$num,2),%r10
lea -320(%rsp,$num,2),%rsp # alloca(frame+2*$num*8+256)
lea -320(%rbp,$num,2),%rbp # alloca(frame+2*$num*8+256)
sub %r10,%r11
mov \$0,%r10
cmovc %r10,%r11
sub %r11,%rsp
sub %r11,%rbp
.Lpwrx_sp_done:
and \$-64,%rsp
mov $num,%r10
and \$-64,%rbp
mov %rsp,%r11
sub %rbp,%r11
and \$-4096,%r11
lea (%rbp,%r11),%rsp
mov (%rsp),%r10
cmp %rbp,%rsp
ja .Lpwrx_page_walk
jmp .Lpwrx_page_walk_done
.Lpwrx_page_walk:
lea -4096(%rsp),%rsp
mov (%rsp),%r10
cmp %rbp,%rsp
ja .Lpwrx_page_walk
.Lpwrx_page_walk_done:
mov $num,%r10
neg $num
##############################################################
@@ -2626,6 +2838,7 @@ bn_powerx5:
movq $bptr,%xmm4
mov $n0, 32(%rsp)
mov %rax, 40(%rsp) # save original %rsp
.cfi_cfa_expression %rsp+40,deref,+8
.Lpowerx5_body:
call __bn_sqrx8x_internal
@@ -2648,17 +2861,26 @@ bn_powerx5:
call mulx4x_internal
mov 40(%rsp),%rsi # restore %rsp
.cfi_def_cfa %rsi,8
mov \$1,%rax
mov -48(%rsi),%r15
.cfi_restore %r15
mov -40(%rsi),%r14
.cfi_restore %r14
mov -32(%rsi),%r13
.cfi_restore %r13
mov -24(%rsi),%r12
.cfi_restore %r12
mov -16(%rsi),%rbp
.cfi_restore %rbp
mov -8(%rsi),%rbx
.cfi_restore %rbx
lea (%rsi),%rsp
.cfi_def_cfa_register %rsp
.Lpowerx5_epilogue:
ret
.cfi_endproc
.size bn_powerx5,.-bn_powerx5
.globl bn_sqrx8x_internal
@@ -3248,6 +3470,7 @@ __bn_sqrx8x_reduction:
.align 32
.Lsqrx8x_tail_done:
xor %rax,%rax
add 24+8(%rsp),%r8 # can this overflow?
adc \$0,%r9
adc \$0,%r10
@@ -3255,10 +3478,8 @@ __bn_sqrx8x_reduction:
adc \$0,%r12
adc \$0,%r13
adc \$0,%r14
adc \$0,%r15 # can't overflow, because we
# started with "overhung" part
# of multiplication
mov $carry,%rax # xor %rax,%rax
adc \$0,%r15
adc \$0,%rax
sub 16+8(%rsp),$carry # mov 16(%rsp),%cf
.Lsqrx8x_no_tail: # %cf is 0 if jumped here
@@ -3273,7 +3494,7 @@ __bn_sqrx8x_reduction:
adc 8*5($tptr),%r13
adc 8*6($tptr),%r14
adc 8*7($tptr),%r15
adc %rax,%rax # top-most carry
adc \$0,%rax # top-most carry
mov 32+8(%rsp),%rbx # n0
mov 8*8($tptr,%rcx),%rdx # modulo-scheduled "%r8"
@@ -3515,9 +3736,14 @@ mul_handler:
cmp %r10,%rbx # context->Rip<end of prologue label
jb .Lcommon_seh_tail
mov 4(%r11),%r10d # HandlerData[1]
lea (%rsi,%r10),%r10 # beginning of body label
cmp %r10,%rbx # context->Rip<body label
jb .Lcommon_pop_regs
mov 152($context),%rax # pull context->Rsp
mov 4(%r11),%r10d # HandlerData[1]
mov 8(%r11),%r10d # HandlerData[2]
lea (%rsi,%r10),%r10 # epilogue label
cmp %r10,%rbx # context->Rip>=epilogue label
jae .Lcommon_seh_tail
@@ -3529,11 +3755,11 @@ mul_handler:
mov 192($context),%r10 # pull $num
mov 8(%rax,%r10,8),%rax # pull saved stack pointer
jmp .Lbody_proceed
jmp .Lcommon_pop_regs
.Lbody_40:
mov 40(%rax),%rax # pull saved stack pointer
.Lbody_proceed:
.Lcommon_pop_regs:
mov -8(%rax),%rbx
mov -16(%rax),%rbp
mov -24(%rax),%r12
@@ -3624,34 +3850,34 @@ $code.=<<___;
.LSEH_info_bn_mul_mont_gather5:
.byte 9,0,0,0
.rva mul_handler
.rva .Lmul_body,.Lmul_epilogue # HandlerData[]
.rva .Lmul_body,.Lmul_body,.Lmul_epilogue # HandlerData[]
.align 8
.LSEH_info_bn_mul4x_mont_gather5:
.byte 9,0,0,0
.rva mul_handler
.rva .Lmul4x_body,.Lmul4x_epilogue # HandlerData[]
.rva .Lmul4x_prologue,.Lmul4x_body,.Lmul4x_epilogue # HandlerData[]
.align 8
.LSEH_info_bn_power5:
.byte 9,0,0,0
.rva mul_handler
.rva .Lpower5_body,.Lpower5_epilogue # HandlerData[]
.rva .Lpower5_prologue,.Lpower5_body,.Lpower5_epilogue # HandlerData[]
.align 8
.LSEH_info_bn_from_mont8x:
.byte 9,0,0,0
.rva mul_handler
.rva .Lfrom_body,.Lfrom_epilogue # HandlerData[]
.rva .Lfrom_prologue,.Lfrom_body,.Lfrom_epilogue # HandlerData[]
___
$code.=<<___ if ($addx);
.align 8
.LSEH_info_bn_mulx4x_mont_gather5:
.byte 9,0,0,0
.rva mul_handler
.rva .Lmulx4x_body,.Lmulx4x_epilogue # HandlerData[]
.rva .Lmulx4x_prologue,.Lmulx4x_body,.Lmulx4x_epilogue # HandlerData[]
.align 8
.LSEH_info_bn_powerx5:
.byte 9,0,0,0
.rva mul_handler
.rva .Lpowerx5_body,.Lpowerx5_epilogue # HandlerData[]
.rva .Lpowerx5_prologue,.Lpowerx5_body,.Lpowerx5_epilogue # HandlerData[]
___
$code.=<<___;
.align 8
+6 -20
View File
@@ -73,14 +73,14 @@ BIGNUM *BN_new(void) {
return NULL;
}
memset(bn, 0, sizeof(BIGNUM));
OPENSSL_memset(bn, 0, sizeof(BIGNUM));
bn->flags = BN_FLG_MALLOCED;
return bn;
}
void BN_init(BIGNUM *bn) {
memset(bn, 0, sizeof(BIGNUM));
OPENSSL_memset(bn, 0, sizeof(BIGNUM));
}
void BN_free(BIGNUM *bn) {
@@ -149,7 +149,7 @@ BIGNUM *BN_copy(BIGNUM *dest, const BIGNUM *src) {
return NULL;
}
memcpy(dest->d, src->d, sizeof(src->d[0]) * src->top);
OPENSSL_memcpy(dest->d, src->d, sizeof(src->d[0]) * src->top);
dest->top = src->top;
dest->neg = src->neg;
@@ -158,7 +158,7 @@ BIGNUM *BN_copy(BIGNUM *dest, const BIGNUM *src) {
void BN_clear(BIGNUM *bn) {
if (bn->d != NULL) {
memset(bn->d, 0, bn->dmax * sizeof(bn->d[0]));
OPENSSL_memset(bn->d, 0, bn->dmax * sizeof(bn->d[0]));
}
bn->top = 0;
@@ -172,12 +172,6 @@ const BIGNUM *BN_value_one(void) {
return &kOne;
}
void BN_with_flags(BIGNUM *out, const BIGNUM *in, int flags) {
memcpy(out, in, sizeof(BIGNUM));
out->flags &= ~BN_FLG_MALLOCED;
out->flags |= BN_FLG_STATIC_DATA | flags;
}
/* BN_num_bits_word returns the minimum number of bits needed to represent the
* value in |l|. */
unsigned BN_num_bits_word(BN_ULONG l) {
@@ -292,7 +286,7 @@ int bn_set_words(BIGNUM *bn, const BN_ULONG *words, size_t num) {
if (bn_wexpand(bn, num) == NULL) {
return 0;
}
memmove(bn->d, words, num * sizeof(BN_ULONG));
OPENSSL_memmove(bn->d, words, num * sizeof(BN_ULONG));
/* |bn_wexpand| verified that |num| isn't too large. */
bn->top = (int)num;
bn_correct_top(bn);
@@ -335,7 +329,7 @@ BIGNUM *bn_wexpand(BIGNUM *bn, size_t words) {
return NULL;
}
memcpy(a, bn->d, sizeof(BN_ULONG) * bn->top);
OPENSSL_memcpy(a, bn->d, sizeof(BN_ULONG) * bn->top);
OPENSSL_free(bn->d);
bn->d = a;
@@ -369,11 +363,3 @@ void bn_correct_top(BIGNUM *bn) {
bn->neg = 0;
}
}
int BN_get_flags(const BIGNUM *bn, int flags) {
return bn->flags & flags;
}
void BN_set_flags(BIGNUM *bn, int flags) {
bn->flags |= flags;
}
+350 -61
View File
@@ -515,6 +515,54 @@ static bool TestModMul(FileTest *t, BN_CTX *ctx) {
return true;
}
static bool TestModSquare(FileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
bssl::UniquePtr<BIGNUM> m = GetBIGNUM(t, "M");
bssl::UniquePtr<BIGNUM> mod_square = GetBIGNUM(t, "ModSquare");
if (!a || !m || !mod_square) {
return false;
}
bssl::UniquePtr<BIGNUM> a_copy(BN_new());
bssl::UniquePtr<BIGNUM> ret(BN_new());
if (!ret || !a_copy ||
!BN_mod_mul(ret.get(), a.get(), a.get(), m.get(), ctx) ||
!ExpectBIGNUMsEqual(t, "A * A (mod M)", mod_square.get(), ret.get()) ||
// Repeat the operation with |a_copy|.
!BN_copy(a_copy.get(), a.get()) ||
!BN_mod_mul(ret.get(), a.get(), a_copy.get(), m.get(), ctx) ||
!ExpectBIGNUMsEqual(t, "A * A_copy (mod M)", mod_square.get(),
ret.get())) {
return false;
}
if (BN_is_odd(m.get())) {
// Reduce |a| and test the Montgomery version.
bssl::UniquePtr<BN_MONT_CTX> mont(BN_MONT_CTX_new());
bssl::UniquePtr<BIGNUM> a_tmp(BN_new());
if (!mont || !a_tmp ||
!BN_MONT_CTX_set(mont.get(), m.get(), ctx) ||
!BN_nnmod(a_tmp.get(), a.get(), m.get(), ctx) ||
!BN_to_montgomery(a_tmp.get(), a_tmp.get(), mont.get(), ctx) ||
!BN_mod_mul_montgomery(ret.get(), a_tmp.get(), a_tmp.get(), mont.get(),
ctx) ||
!BN_from_montgomery(ret.get(), ret.get(), mont.get(), ctx) ||
!ExpectBIGNUMsEqual(t, "A * A (mod M) (Montgomery)",
mod_square.get(), ret.get()) ||
// Repeat the operation with |a_copy|.
!BN_copy(a_copy.get(), a_tmp.get()) ||
!BN_mod_mul_montgomery(ret.get(), a_tmp.get(), a_copy.get(), mont.get(),
ctx) ||
!BN_from_montgomery(ret.get(), ret.get(), mont.get(), ctx) ||
!ExpectBIGNUMsEqual(t, "A * A_copy (mod M) (Montgomery)",
mod_square.get(), ret.get())) {
return false;
}
}
return true;
}
static bool TestModExp(FileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
bssl::UniquePtr<BIGNUM> e = GetBIGNUM(t, "E");
@@ -568,21 +616,25 @@ static bool TestModSqrt(FileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
bssl::UniquePtr<BIGNUM> p = GetBIGNUM(t, "P");
bssl::UniquePtr<BIGNUM> mod_sqrt = GetBIGNUM(t, "ModSqrt");
if (!a || !p || !mod_sqrt) {
bssl::UniquePtr<BIGNUM> mod_sqrt2(BN_new());
if (!a || !p || !mod_sqrt || !mod_sqrt2 ||
// There are two possible answers.
!BN_sub(mod_sqrt2.get(), p.get(), mod_sqrt.get())) {
return false;
}
// -0 is 0, not P.
if (BN_is_zero(mod_sqrt.get())) {
BN_zero(mod_sqrt2.get());
}
bssl::UniquePtr<BIGNUM> ret(BN_new());
bssl::UniquePtr<BIGNUM> ret2(BN_new());
if (!ret ||
!ret2 ||
!BN_mod_sqrt(ret.get(), a.get(), p.get(), ctx) ||
// There are two possible answers.
!BN_sub(ret2.get(), p.get(), ret.get())) {
!BN_mod_sqrt(ret.get(), a.get(), p.get(), ctx)) {
return false;
}
if (BN_cmp(ret2.get(), mod_sqrt.get()) != 0 &&
if (BN_cmp(ret.get(), mod_sqrt2.get()) != 0 &&
!ExpectBIGNUMsEqual(t, "sqrt(A) (mod P)", mod_sqrt.get(), ret.get())) {
return false;
}
@@ -590,6 +642,29 @@ static bool TestModSqrt(FileTest *t, BN_CTX *ctx) {
return true;
}
static bool TestNotModSquare(FileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> not_mod_square = GetBIGNUM(t, "NotModSquare");
bssl::UniquePtr<BIGNUM> p = GetBIGNUM(t, "P");
bssl::UniquePtr<BIGNUM> ret(BN_new());
if (!not_mod_square || !p || !ret) {
return false;
}
if (BN_mod_sqrt(ret.get(), not_mod_square.get(), p.get(), ctx)) {
t->PrintLine("BN_mod_sqrt unexpectedly succeeded.");
return false;
}
uint32_t err = ERR_peek_error();
if (ERR_GET_LIB(err) == ERR_LIB_BN &&
ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) {
ERR_clear_error();
return true;
}
return false;
}
static bool TestModInv(FileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
bssl::UniquePtr<BIGNUM> m = GetBIGNUM(t, "M");
@@ -605,15 +680,6 @@ static bool TestModInv(FileTest *t, BN_CTX *ctx) {
return false;
}
BN_set_flags(a.get(), BN_FLG_CONSTTIME);
if (!ret ||
!BN_mod_inverse(ret.get(), a.get(), m.get(), ctx) ||
!ExpectBIGNUMsEqual(t, "inv(A) (mod M) (constant-time)", mod_inv.get(),
ret.get())) {
return false;
}
return true;
}
@@ -631,9 +697,11 @@ static const Test kTests[] = {
{"Product", TestProduct},
{"Quotient", TestQuotient},
{"ModMul", TestModMul},
{"ModSquare", TestModSquare},
{"ModExp", TestModExp},
{"Exp", TestExp},
{"ModSqrt", TestModSqrt},
{"NotModSquare", TestNotModSquare},
{"ModInv", TestModInv},
};
@@ -652,7 +720,7 @@ static bool RunTest(FileTest *t, void *arg) {
static bool TestBN2BinPadded(BN_CTX *ctx) {
uint8_t zeros[256], out[256], reference[128];
memset(zeros, 0, sizeof(zeros));
OPENSSL_memset(zeros, 0, sizeof(zeros));
// Test edge case at 0.
bssl::UniquePtr<BIGNUM> n(BN_new());
@@ -661,13 +729,13 @@ static bool TestBN2BinPadded(BN_CTX *ctx) {
"BN_bn2bin_padded failed to encode 0 in an empty buffer.\n");
return false;
}
memset(out, -1, sizeof(out));
OPENSSL_memset(out, -1, sizeof(out));
if (!BN_bn2bin_padded(out, sizeof(out), n.get())) {
fprintf(stderr,
"BN_bn2bin_padded failed to encode 0 in a non-empty buffer.\n");
return false;
}
if (memcmp(zeros, out, sizeof(out))) {
if (OPENSSL_memcmp(zeros, out, sizeof(out))) {
fprintf(stderr, "BN_bn2bin_padded did not zero buffer.\n");
return false;
}
@@ -696,20 +764,21 @@ static bool TestBN2BinPadded(BN_CTX *ctx) {
}
// Exactly right size should encode.
if (!BN_bn2bin_padded(out, bytes, n.get()) ||
memcmp(out, reference, bytes) != 0) {
OPENSSL_memcmp(out, reference, bytes) != 0) {
fprintf(stderr, "BN_bn2bin_padded gave a bad result.\n");
return false;
}
// Pad up one byte extra.
if (!BN_bn2bin_padded(out, bytes + 1, n.get()) ||
memcmp(out + 1, reference, bytes) || memcmp(out, zeros, 1)) {
OPENSSL_memcmp(out + 1, reference, bytes) ||
OPENSSL_memcmp(out, zeros, 1)) {
fprintf(stderr, "BN_bn2bin_padded gave a bad result.\n");
return false;
}
// Pad up to 256.
if (!BN_bn2bin_padded(out, sizeof(out), n.get()) ||
memcmp(out + sizeof(out) - bytes, reference, bytes) ||
memcmp(out, zeros, sizeof(out) - bytes)) {
OPENSSL_memcmp(out + sizeof(out) - bytes, reference, bytes) ||
OPENSSL_memcmp(out, zeros, sizeof(out) - bytes)) {
fprintf(stderr, "BN_bn2bin_padded gave a bad result.\n");
return false;
}
@@ -718,6 +787,82 @@ static bool TestBN2BinPadded(BN_CTX *ctx) {
return true;
}
static bool TestLittleEndian() {
bssl::UniquePtr<BIGNUM> x(BN_new());
bssl::UniquePtr<BIGNUM> y(BN_new());
if (!x || !y) {
fprintf(stderr, "BN_new failed to malloc.\n");
return false;
}
// Test edge case at 0. Fill |out| with garbage to ensure |BN_bn2le_padded|
// wrote the result.
uint8_t out[256], zeros[256];
OPENSSL_memset(out, -1, sizeof(out));
OPENSSL_memset(zeros, 0, sizeof(zeros));
if (!BN_bn2le_padded(out, sizeof(out), x.get()) ||
OPENSSL_memcmp(zeros, out, sizeof(out))) {
fprintf(stderr, "BN_bn2le_padded failed to encode 0.\n");
return false;
}
if (!BN_le2bn(out, sizeof(out), y.get()) ||
BN_cmp(x.get(), y.get()) != 0) {
fprintf(stderr, "BN_le2bn failed to decode 0 correctly.\n");
return false;
}
// Test random numbers at various byte lengths.
for (size_t bytes = 128 - 7; bytes <= 128; bytes++) {
if (!BN_rand(x.get(), bytes * 8, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) {
ERR_print_errors_fp(stderr);
return false;
}
// Fill |out| with garbage to ensure |BN_bn2le_padded| wrote the result.
OPENSSL_memset(out, -1, sizeof(out));
if (!BN_bn2le_padded(out, sizeof(out), x.get())) {
fprintf(stderr, "BN_bn2le_padded failed to encode random value.\n");
return false;
}
// Compute the expected value by reversing the big-endian output.
uint8_t expected[sizeof(out)];
if (!BN_bn2bin_padded(expected, sizeof(expected), x.get())) {
return false;
}
for (size_t i = 0; i < sizeof(expected) / 2; i++) {
uint8_t tmp = expected[i];
expected[i] = expected[sizeof(expected) - 1 - i];
expected[sizeof(expected) - 1 - i] = tmp;
}
if (OPENSSL_memcmp(expected, out, sizeof(out))) {
fprintf(stderr, "BN_bn2le_padded failed to encode value correctly.\n");
hexdump(stderr, "Expected: ", expected, sizeof(expected));
hexdump(stderr, "Got: ", out, sizeof(out));
return false;
}
// Make sure the decoding produces the same BIGNUM.
if (!BN_le2bn(out, bytes, y.get()) ||
BN_cmp(x.get(), y.get()) != 0) {
bssl::UniquePtr<char> x_hex(BN_bn2hex(x.get())),
y_hex(BN_bn2hex(y.get()));
if (!x_hex || !y_hex) {
return false;
}
fprintf(stderr, "BN_le2bn failed to decode value correctly.\n");
fprintf(stderr, "Expected: %s\n", x_hex.get());
hexdump(stderr, "Encoding: ", out, bytes);
fprintf(stderr, "Got: %s\n", y_hex.get());
return false;
}
}
return true;
}
static int DecimalToBIGNUM(bssl::UniquePtr<BIGNUM> *out, const char *in) {
BIGNUM *raw = NULL;
int ret = BN_dec2bn(&raw, in);
@@ -894,7 +1039,7 @@ static bool TestMPI() {
}
if (mpi_len != test.mpi_len ||
memcmp(test.mpi, scratch, mpi_len) != 0) {
OPENSSL_memcmp(test.mpi, scratch, mpi_len) != 0) {
fprintf(stderr, "MPI test #%u failed:\n", (unsigned)i);
hexdump(stderr, "Expected: ", test.mpi, test.mpi_len);
hexdump(stderr, "Got: ", scratch, mpi_len);
@@ -1034,7 +1179,8 @@ static bool TestASN1() {
}
bssl::UniquePtr<uint8_t> delete_der(der);
if (der_len != test.der_len ||
memcmp(der, reinterpret_cast<const uint8_t*>(test.der), der_len) != 0) {
OPENSSL_memcmp(der, reinterpret_cast<const uint8_t *>(test.der),
der_len) != 0) {
fprintf(stderr, "Bad serialization.\n");
return false;
}
@@ -1145,42 +1291,35 @@ static bool TestNegativeZero(BN_CTX *ctx) {
return false;
}
for (int consttime = 0; consttime < 2; consttime++) {
bssl::UniquePtr<BIGNUM> numerator(BN_new()), denominator(BN_new());
if (!numerator || !denominator) {
return false;
}
bssl::UniquePtr<BIGNUM> numerator(BN_new()), denominator(BN_new());
if (!numerator || !denominator) {
return false;
}
if (consttime) {
BN_set_flags(numerator.get(), BN_FLG_CONSTTIME);
BN_set_flags(denominator.get(), BN_FLG_CONSTTIME);
}
// Test that BN_div never gives negative zero in the quotient.
if (!BN_set_word(numerator.get(), 1) ||
!BN_set_word(denominator.get(), 2)) {
return false;
}
BN_set_negative(numerator.get(), 1);
if (!BN_div(a.get(), b.get(), numerator.get(), denominator.get(), ctx)) {
return false;
}
if (!BN_is_zero(a.get()) || BN_is_negative(a.get())) {
fprintf(stderr, "Incorrect quotient.\n");
return false;
}
// Test that BN_div never gives negative zero in the quotient.
if (!BN_set_word(numerator.get(), 1) ||
!BN_set_word(denominator.get(), 2)) {
return false;
}
BN_set_negative(numerator.get(), 1);
if (!BN_div(a.get(), b.get(), numerator.get(), denominator.get(), ctx)) {
return false;
}
if (!BN_is_zero(a.get()) || BN_is_negative(a.get())) {
fprintf(stderr, "Incorrect quotient (consttime = %d).\n", consttime);
return false;
}
// Test that BN_div never gives negative zero in the remainder.
if (!BN_set_word(denominator.get(), 1)) {
return false;
}
if (!BN_div(a.get(), b.get(), numerator.get(), denominator.get(), ctx)) {
return false;
}
if (!BN_is_zero(b.get()) || BN_is_negative(b.get())) {
fprintf(stderr, "Incorrect remainder (consttime = %d).\n", consttime);
return false;
}
// Test that BN_div never gives negative zero in the remainder.
if (!BN_set_word(denominator.get(), 1)) {
return false;
}
if (!BN_div(a.get(), b.get(), numerator.get(), denominator.get(), ctx)) {
return false;
}
if (!BN_is_zero(b.get()) || BN_is_negative(b.get())) {
fprintf(stderr, "Incorrect remainder.\n");
return false;
}
// Test that BN_set_negative will not produce a negative zero.
@@ -1203,6 +1342,37 @@ static bool TestNegativeZero(BN_CTX *ctx) {
return false;
}
// Test that |BN_rshift| and |BN_rshift1| will not produce a negative zero.
if (!BN_set_word(a.get(), 1)) {
return false;
}
BN_set_negative(a.get(), 1);
if (!BN_rshift(b.get(), a.get(), 1) ||
!BN_rshift1(c.get(), a.get())) {
return false;
}
if (!BN_is_zero(b.get()) || BN_is_negative(b.get())) {
fprintf(stderr, "BN_rshift(-1, 1) produced the wrong result.\n");
return false;
}
if (!BN_is_zero(c.get()) || BN_is_negative(c.get())) {
fprintf(stderr, "BN_rshift1(-1) produced the wrong result.\n");
return false;
}
// Test that |BN_div_word| will not produce a negative zero.
if (BN_div_word(a.get(), 2) == (BN_ULONG)-1) {
return false;
}
if (!BN_is_zero(a.get()) || BN_is_negative(a.get())) {
fprintf(stderr, "BN_div_word(-1, 2) produced the wrong result.\n");
return false;
}
return true;
}
@@ -1441,7 +1611,7 @@ static bool TestBN2Dec() {
return true;
}
static bool TestBNSetU64() {
static bool TestBNSetGetU64() {
static const struct {
const char *hex;
uint64_t value;
@@ -1463,6 +1633,123 @@ static bool TestBNSetU64() {
ERR_print_errors_fp(stderr);
return false;
}
uint64_t tmp;
if (!BN_get_u64(bn.get(), &tmp) || tmp != test.value) {
fprintf(stderr, "BN_get_u64 test failed for 0x%s.\n", test.hex);
return false;
}
BN_set_negative(bn.get(), 1);
if (!BN_get_u64(bn.get(), &tmp) || tmp != test.value) {
fprintf(stderr, "BN_get_u64 test failed for -0x%s.\n", test.hex);
return false;
}
}
// Test that BN_get_u64 fails on large numbers.
bssl::UniquePtr<BIGNUM> bn(BN_new());
if (!BN_lshift(bn.get(), BN_value_one(), 64)) {
return false;
}
uint64_t tmp;
if (BN_get_u64(bn.get(), &tmp)) {
fprintf(stderr, "BN_get_u64 of 2^64 unexpectedly succeeded.\n");
return false;
}
BN_set_negative(bn.get(), 1);
if (BN_get_u64(bn.get(), &tmp)) {
fprintf(stderr, "BN_get_u64 of -2^64 unexpectedly succeeded.\n");
return false;
}
return true;
}
static bool TestBNPow2(BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM>
power_of_two(BN_new()),
random(BN_new()),
expected(BN_new()),
actual(BN_new());
if (!power_of_two.get() ||
!random.get() ||
!expected.get() ||
!actual.get()) {
return false;
}
// Choose an exponent.
for (size_t e = 3; e < 512; e += 11) {
// Choose a bit length for our randoms.
for (int len = 3; len < 512; len += 23) {
// Set power_of_two = 2^e.
if (!BN_lshift(power_of_two.get(), BN_value_one(), (int) e)) {
fprintf(stderr, "Failed to shiftl.\n");
return false;
}
// Test BN_is_pow2 on power_of_two.
if (!BN_is_pow2(power_of_two.get())) {
fprintf(stderr, "BN_is_pow2 returned false for a power of two.\n");
hexdump(stderr, "Arg: ", power_of_two->d,
power_of_two->top * sizeof(BN_ULONG));
return false;
}
// Pick a large random value, ensuring it isn't a power of two.
if (!BN_rand(random.get(), len, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY)) {
fprintf(stderr, "Failed to generate random in TestBNPow2.\n");
return false;
}
// Test BN_is_pow2 on |r|.
if (BN_is_pow2(random.get())) {
fprintf(stderr, "BN_is_pow2 returned true for a non-power of two.\n");
hexdump(stderr, "Arg: ", random->d, random->top * sizeof(BN_ULONG));
return false;
}
// Test BN_mod_pow2 on |r|.
if (!BN_mod(expected.get(), random.get(), power_of_two.get(), ctx) ||
!BN_mod_pow2(actual.get(), random.get(), e) ||
BN_cmp(actual.get(), expected.get())) {
fprintf(stderr, "BN_mod_pow2 returned the wrong value:\n");
hexdump(stderr, "Expected: ", expected->d,
expected->top * sizeof(BN_ULONG));
hexdump(stderr, "Got: ", actual->d,
actual->top * sizeof(BN_ULONG));
return false;
}
// Test BN_nnmod_pow2 on |r|.
if (!BN_nnmod(expected.get(), random.get(), power_of_two.get(), ctx) ||
!BN_nnmod_pow2(actual.get(), random.get(), e) ||
BN_cmp(actual.get(), expected.get())) {
fprintf(stderr, "BN_nnmod_pow2 failed on positive input:\n");
hexdump(stderr, "Expected: ", expected->d,
expected->top * sizeof(BN_ULONG));
hexdump(stderr, "Got: ", actual->d,
actual->top * sizeof(BN_ULONG));
return false;
}
// Test BN_nnmod_pow2 on -|r|.
BN_set_negative(random.get(), 1);
if (!BN_nnmod(expected.get(), random.get(), power_of_two.get(), ctx) ||
!BN_nnmod_pow2(actual.get(), random.get(), e) ||
BN_cmp(actual.get(), expected.get())) {
fprintf(stderr, "BN_nnmod_pow2 failed on negative input:\n");
hexdump(stderr, "Expected: ", expected->d,
expected->top * sizeof(BN_ULONG));
hexdump(stderr, "Got: ", actual->d,
actual->top * sizeof(BN_ULONG));
return false;
}
}
}
return true;
@@ -1485,6 +1772,7 @@ int main(int argc, char *argv[]) {
!TestDec2BN(ctx.get()) ||
!TestHex2BN(ctx.get()) ||
!TestASC2BN(ctx.get()) ||
!TestLittleEndian() ||
!TestMPI() ||
!TestRand() ||
!TestASN1() ||
@@ -1494,7 +1782,8 @@ int main(int argc, char *argv[]) {
!TestSmallPrime(ctx.get()) ||
!TestCmpWord() ||
!TestBN2Dec() ||
!TestBNSetU64()) {
!TestBNSetGetU64() ||
!TestBNPow2(ctx.get())) {
return 1;
}
+115
View File
@@ -9888,6 +9888,16 @@ B = 7878787878787878787878787878787878787878787878787878787878787878787878787878
M = d78af684e71db0c39cff4e64fb9db567132cb9c50cc98009feb820b26f2ded9b91b9b5e2b83ae0ae4eb4e0523ca726bfbe969b89fd754f674ce99118c3f2d1c5d81fdc7c54e02b60262b241d53c040e99e45826eca37a804668e690e1afc1ca42c9a15d84d4954425f0b7642fc0bd9d7b24e2618d2dcc9b729d944badacfddaf
# ModSquare tests.
#
# These test vectors satisfy A * A = ModSquare (mod M) and 0 <= ModSquare < M.
# Regression test for CVE-2017-3732.
ModSquare = fffffffdfffffd01000009000002f6fffdf403000312000402f3fff5f602fe080a0005fdfafffa00010001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000002000002fefffff7fffffd07000109fdfffef3fffdfd06000405ff00fdfbfffe00010001
A = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff00000000
M = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff
# ModExp tests.
#
# These test vectors satisfy A ^ E = ModExp (mod M) and 0 <= ModExp < M.
@@ -10387,6 +10397,89 @@ E = d7e6df5d755284929b986cd9b61c9c2c8843f24c711fbdbae1a468edcae15940094372557072
M = e4e784aa1fa88625a43ba0185a153a929663920be7fe674a4d33c943d3b898cff051482e7050a070cede53be5e89f31515772c7aea637576f99f82708f89d9e244f6ad3a24a02cbe5c0ff7bcf2dad5491f53db7c3f2698a7c41b44f086652f17bb05fe4c5c0a92433c34086b49d7e1825b28bab6c5a9bd0bc95b53d659afa0d7
# RSAZ 512-bit.
#
# These are regression tests for code which historically reached the RSAZ-512
# code. That has since been removed, but the test vectors remain. Note that the
# lengths of the inputs, especially the *bit* length of |M|, matter a lot.
# Control: No relationship between A and M except that A < M and they're the same number of limbs.
ModExp = 7f34c1cd63377bc3abf2bb5b2d1bf5f06454e1e8040fe19a72245ce9731cbee1bf9e84532300776c8021ed4f3a8de508d85b4cf320bd82065a013754857b50c4
A = 8e4e67da6ff890643d0599387955996ef6f0c2045eb9944576ddb965ca64cdb6247727ce128ef178d4a84e5a56d2e67eb0fe389ecbf691f9244ae80f4c11b364
E = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1
M = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491
# Same as above except A is negative.
ModExp = 71fa6a4c8ae75368eda8cc6282c26afa69e2af12a97fb9444f16b7dd6c99e0a5d6034cab4248cae4357346b211039f4a2bc4c5a20a297372094162417af703cd
A = -8e4e67da6ff890643d0599387955996ef6f0c2045eb9944576ddb965ca64cdb6247727ce128ef178d4a84e5a56d2e67eb0fe389ecbf691f9244ae80f4c11b364
E = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1
M = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491
# A == M - 1 == -1 (mod M) and the exponent is odd so A ^ E (mod M) == A.
ModExp = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725490
A = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725490
E = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1
M = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491
# Same inputs as above except A is negative. Note that A mod M with a "correct top" isn't the right length for RSAZ.
ModExp = 1
A = -f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725490
E = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1
M = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491
# A == M, so A == 0 (mod M) so A ^ E (mod M) == 0. Note that A mod M with a "correct top" isn't the right length for RSAZ.
ModExp = 0
A = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491
E = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1
M = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491
# A is negative, and A (mod M) is the right length for RSAZ.
ModExp = 8d76eb0f8c7bc3160cc8bb0e0c3590fbed26c5932f5f525b48045c0bd46dda287ba5483f97c851fb7c12c2e858ee7a4a4d1af745cbfb3eb311fa54bea12cde25
A = -80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
E = be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1
M = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491
# RSAZ 1024-bit.
# Note that the lengths of the inputs, especially the *bit* length of |M|, matter a lot.
# Control: No relationship between A and M except that A < M and they're the same number of limbs.
ModExp = 8984f8c16044f9c0ad7bd72347af90f58e6e003acda92b76e3c7c4a56ea8e918409d8e9b34884d4c89d0b17cb40fe898f2627c084a0f1698e46beccbf6f48eecc281e11ea9e5135adba460ddae157f2c655b5f589ce29b254d43a960a71cede8a08dbb86be4dac22458da232fb1ec2470856827302ed772c9ddafa408c931aa7
A = 21158da5fe20356825e72b3f5384ec57720d22f727b27ce2f945c8ee311db781add73bf8fae96b775c909bd22fca75c44c2b0584284a5bb1c07f8eefcd6b0a44047a02b185df34f897f11d4fb9a86c9eb841b4cb8d0383441fdc5af3ef385b5e8380f605d73ed41bb42eb2c2a5704d6034b3ad058dafffce83dbbfb6295daaf8
E = ecdebd112b3b5788669449dcddbd479a203ee9ab72a9bb9c406b97623513bf0ab9a22f1f23634d269e16bfd6d3b64202b71fc355057411967b6ac70f8d9cef0a4e06819a9a18cc06bbe438243fa9759303d98be8a65dc1cb13595ee9b99f138554425d50f6fbc025d8ffa3eaea828d6f3b82a3584146bafde34da257995f0575
M = ff3a3e023db3bba929ca4ededbace13d0d1264387b5ef62734e177eaf47a78af56b58aacc8ac5d46f5b066bafb95d93d4442bb948653613eec76837b4ffb7991cb080b6c8b403fb09bc817d026e283ee47ab2fc9af274b12f626eda2fe02004a8e27b9ed7d3b614e8955c7e7c2c0700edd079455237c4475fbd41857e206e4b7
# Same as above except A is negative.
ModExp = 75b54540dd6ec1e87c4e77bb93fd50477ea463fdadb5cab05119b34585d18f971617fc1194240ffa6bdfb53e4785f0a451e03f8c3c444aa6080a96af5906eaa508862a4de15b2c55c023b6f278cd04c1e24fd0711244afeda8e3444256e51261ed99fe66beedb52c43c825b4c7a1adc7d4b111e2208ecd495df91e175573ca10
A = -21158da5fe20356825e72b3f5384ec57720d22f727b27ce2f945c8ee311db781add73bf8fae96b775c909bd22fca75c44c2b0584284a5bb1c07f8eefcd6b0a44047a02b185df34f897f11d4fb9a86c9eb841b4cb8d0383441fdc5af3ef385b5e8380f605d73ed41bb42eb2c2a5704d6034b3ad058dafffce83dbbfb6295daaf8
E = ecdebd112b3b5788669449dcddbd479a203ee9ab72a9bb9c406b97623513bf0ab9a22f1f23634d269e16bfd6d3b64202b71fc355057411967b6ac70f8d9cef0a4e06819a9a18cc06bbe438243fa9759303d98be8a65dc1cb13595ee9b99f138554425d50f6fbc025d8ffa3eaea828d6f3b82a3584146bafde34da257995f0575
M = ff3a3e023db3bba929ca4ededbace13d0d1264387b5ef62734e177eaf47a78af56b58aacc8ac5d46f5b066bafb95d93d4442bb948653613eec76837b4ffb7991cb080b6c8b403fb09bc817d026e283ee47ab2fc9af274b12f626eda2fe02004a8e27b9ed7d3b614e8955c7e7c2c0700edd079455237c4475fbd41857e206e4b7
# A == M - 1 == -1 (mod M) and the exponent is odd so A ^ E (mod M) == A.
ModExp = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d964
A = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d964
E = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103
M = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965
# Same inputs as above except A is negative. Note that A mod M with a "correct top" isn't the right length for RSAZ.
ModExp = 1
A = -b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d964
E = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103
M = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965
# A == M, so A == 0 (mod M) so A ^ E (mod M) == 0. Note that A mod M with a "correct top" isn't the right length for RSAZ.
ModExp = 0
A = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965
E = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103
M = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965
# A is negative, and A (mod M) is the right length for RSAZ.
ModExp = 9cf810b9e89d5cbc4b79ae64e123ea06d92965e2bab077df97a1b906dc2e1ddcf96a9c4ed14e2cd96309b829ea9cc2a74a7d4b43c5f34d792a7c583201427754b8f78b783608070a84b61f18913e3ced7f7f530972de7764667c54e29d756eea38a93cd1703c676a4587231b0ebfeadddf908e2877a7a84b5bfc370ecf0d158d
A = -8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
E = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103
M = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965
# Exp tests.
#
# These test vectors satisfy A ^ E = Exp.
@@ -10737,6 +10830,28 @@ ModSqrt = a1d52989f12f204d3d2167d9b1e6c8a6174c0c786a979a5952383b7b8bd186
A = 2eee37cf06228a387788188e650bc6d8a2ff402931443f69156a29155eca07dcb45f3aac238d92943c0c25c896098716baa433f25bd696a142f5a69d5d937e81
P = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f
# NotModSquare tests.
#
# These test vectors are such that NotModSquare is not a square modulo P.
NotModSquare = 03
P = 07
NotModSquare = 05
P = 07
NotModSquare = 06
P = 07
NotModSquare = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951e
P = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f
# ModInv tests.
#
# These test vectors satisfy ModInv * A = 1 (mod M) and 0 <= ModInv < M.
ModInv = 00
A = 00
M = 01
+14
View File
@@ -212,6 +212,20 @@ int BN_is_odd(const BIGNUM *bn) {
return bn->top > 0 && (bn->d[0] & 1) == 1;
}
int BN_is_pow2(const BIGNUM *bn) {
if (bn->top == 0 || bn->neg) {
return 0;
}
for (int i = 0; i < bn->top - 1; i++) {
if (bn->d[i] != 0) {
return 0;
}
}
return 0 == (bn->d[bn->top-1] & (bn->d[bn->top-1] - 1));
}
int BN_equal_consttime(const BIGNUM *a, const BIGNUM *b) {
if (a->top != b->top) {
return 0;
+73 -2
View File
@@ -118,6 +118,42 @@ BIGNUM *BN_bin2bn(const uint8_t *in, size_t len, BIGNUM *ret) {
return ret;
}
BIGNUM *BN_le2bn(const uint8_t *in, size_t len, BIGNUM *ret) {
BIGNUM *bn = NULL;
if (ret == NULL) {
bn = BN_new();
ret = bn;
}
if (ret == NULL) {
return NULL;
}
if (len == 0) {
ret->top = 0;
ret->neg = 0;
return ret;
}
/* Reserve enough space in |ret|. */
size_t num_words = ((len - 1) / BN_BYTES) + 1;
if (!bn_wexpand(ret, num_words)) {
BN_free(bn);
return NULL;
}
ret->top = num_words;
/* Make sure the top bytes will be zeroed. */
ret->d[num_words - 1] = 0;
/* We only support little-endian platforms, so we can simply memcpy the
* internal representation. */
OPENSSL_memcpy(ret->d, in, len);
bn_correct_top(ret);
return ret;
}
size_t BN_bn2bin(const BIGNUM *in, uint8_t *out) {
size_t n, i;
BN_ULONG l;
@@ -130,6 +166,23 @@ size_t BN_bn2bin(const BIGNUM *in, uint8_t *out) {
return n;
}
int BN_bn2le_padded(uint8_t *out, size_t len, const BIGNUM *in) {
/* If we don't have enough space, fail out. */
size_t num_bytes = BN_num_bytes(in);
if (len < num_bytes) {
return 0;
}
/* We only support little-endian platforms, so we can simply memcpy into the
* internal representation. */
OPENSSL_memcpy(out, in->d, num_bytes);
/* Pad out the rest of the buffer with zeroes. */
OPENSSL_memset(out + num_bytes, 0, len - num_bytes);
return 1;
}
/* constant_time_select_ulong returns |x| if |v| is 1 and |y| if |v| is 0. Its
* behavior is undefined if |v| takes any other value. */
static BN_ULONG constant_time_select_ulong(int v, BN_ULONG x, BN_ULONG y) {
@@ -162,7 +215,7 @@ static BN_ULONG read_word_padded(const BIGNUM *in, size_t i) {
int BN_bn2bin_padded(uint8_t *out, size_t len, const BIGNUM *in) {
/* Special case for |in| = 0. Just branch as the probability is negligible. */
if (BN_is_zero(in)) {
memset(out, 0, len);
OPENSSL_memset(out, 0, len);
return 1;
}
@@ -515,6 +568,24 @@ BN_ULONG BN_get_word(const BIGNUM *bn) {
}
}
int BN_get_u64(const BIGNUM *bn, uint64_t *out) {
switch (bn->top) {
case 0:
*out = 0;
return 1;
case 1:
*out = bn->d[0];
return 1;
#if defined(OPENSSL_32_BIT)
case 2:
*out = (uint64_t) bn->d[0] | (((uint64_t) bn->d[1]) << 32);
return 1;
#endif
default:
return 0;
}
}
size_t BN_bn2mpi(const BIGNUM *in, uint8_t *out) {
const size_t bits = BN_num_bits(in);
const size_t bytes = (bits + 7) / 8;
@@ -532,7 +603,7 @@ size_t BN_bn2mpi(const BIGNUM *in, uint8_t *out) {
/* If we cannot represent the number then we emit zero as the interface
* doesn't allow an error to be signalled. */
if (out) {
memset(out, 0, 4);
OPENSSL_memset(out, 0, 4);
}
return 4;
}
+3 -1
View File
@@ -59,6 +59,8 @@
#include <openssl/err.h>
#include <openssl/mem.h>
#include "../internal.h"
/* How many bignums are in each "pool item"; */
#define BN_CTX_POOL_SIZE 16
@@ -218,7 +220,7 @@ static int BN_STACK_push(BN_STACK *st, unsigned int idx) {
return 0;
}
if (st->depth) {
memcpy(newitems, st->indexes, st->depth * sizeof(unsigned int));
OPENSSL_memcpy(newitems, st->indexes, st->depth * sizeof(unsigned int));
}
OPENSSL_free(st->indexes);
st->indexes = newitems;
+108 -51
View File
@@ -58,6 +58,7 @@
#include <assert.h>
#include <limits.h>
#include <openssl/err.h>
#include "internal.h"
@@ -182,7 +183,12 @@ static inline void bn_div_rem_words(BN_ULONG *quotient_out, BN_ULONG *rem_out,
* Thus:
* dv->neg == num->neg ^ divisor->neg (unless the result is zero)
* rm->neg == num->neg (unless the remainder is zero)
* If 'dv' or 'rm' is NULL, the respective value is not returned. */
* If 'dv' or 'rm' is NULL, the respective value is not returned.
*
* This was specifically designed to contain fewer branches that may leak
* sensitive information; see "New Branch Prediction Vulnerabilities in OpenSSL
* and Necessary Software Countermeasures" by Onur Acıçmez, Shay Gueron, and
* Jean-Pierre Seifert. */
int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
BN_CTX *ctx) {
int norm_shift, i, loop;
@@ -190,7 +196,6 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
BN_ULONG *resp, *wnump;
BN_ULONG d0, d1;
int num_n, div_n;
int no_branch = 0;
/* Invalid zero-padding would have particularly bad consequences
* so don't just rely on bn_check_top() here */
@@ -200,28 +205,11 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
return 0;
}
if ((num->flags & BN_FLG_CONSTTIME) != 0 ||
(divisor->flags & BN_FLG_CONSTTIME) != 0) {
no_branch = 1;
}
if (BN_is_zero(divisor)) {
OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO);
return 0;
}
if (!no_branch && BN_ucmp(num, divisor) < 0) {
if (rm != NULL) {
if (BN_copy(rm, num) == NULL) {
return 0;
}
}
if (dv != NULL) {
BN_zero(dv);
}
return 1;
}
BN_CTX_start(ctx);
tmp = BN_CTX_get(ctx);
snum = BN_CTX_get(ctx);
@@ -247,26 +235,23 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
}
snum->neg = 0;
if (no_branch) {
/* Since we don't know whether snum is larger than sdiv,
* we pad snum with enough zeroes without changing its
* value.
*/
if (snum->top <= sdiv->top + 1) {
if (bn_wexpand(snum, sdiv->top + 2) == NULL) {
goto err;
}
for (i = snum->top; i < sdiv->top + 2; i++) {
snum->d[i] = 0;
}
snum->top = sdiv->top + 2;
} else {
if (bn_wexpand(snum, snum->top + 1) == NULL) {
goto err;
}
snum->d[snum->top] = 0;
snum->top++;
/* Since we don't want to have special-case logic for the case where snum is
* larger than sdiv, we pad snum with enough zeroes without changing its
* value. */
if (snum->top <= sdiv->top + 1) {
if (bn_wexpand(snum, sdiv->top + 2) == NULL) {
goto err;
}
for (i = snum->top; i < sdiv->top + 2; i++) {
snum->d[i] = 0;
}
snum->top = sdiv->top + 2;
} else {
if (bn_wexpand(snum, snum->top + 1) == NULL) {
goto err;
}
snum->d[snum->top] = 0;
snum->top++;
}
div_n = sdiv->top;
@@ -294,7 +279,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
if (!bn_wexpand(res, (loop + 1))) {
goto err;
}
res->top = loop - no_branch;
res->top = loop - 1;
resp = &(res->d[loop - 1]);
/* space for temp */
@@ -302,15 +287,6 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
goto err;
}
if (!no_branch) {
if (BN_ucmp(&wnum, sdiv) >= 0) {
bn_sub_words(wnum.d, wnum.d, sdiv->d, div_n);
*resp = 1;
} else {
res->top--;
}
}
/* if res->top == 0 then clear the neg value otherwise decrease
* the resp pointer */
if (res->top == 0) {
@@ -401,9 +377,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
rm->neg = neg;
}
}
if (no_branch) {
bn_correct_top(res);
}
bn_correct_top(res);
BN_CTX_end(ctx);
return 1;
@@ -628,6 +602,10 @@ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) {
a->top--;
}
if (a->top == 0) {
a->neg = 0;
}
ret >>= j;
return ret;
}
@@ -669,3 +647,82 @@ BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w) {
}
return (BN_ULONG)ret;
}
int BN_mod_pow2(BIGNUM *r, const BIGNUM *a, size_t e) {
if (e == 0 || a->top == 0) {
BN_zero(r);
return 1;
}
size_t num_words = 1 + ((e - 1) / BN_BITS2);
/* If |a| definitely has less than |e| bits, just BN_copy. */
if ((size_t) a->top < num_words) {
return BN_copy(r, a) != NULL;
}
/* Otherwise, first make sure we have enough space in |r|.
* Note that this will fail if num_words > INT_MAX. */
if (bn_wexpand(r, num_words) == NULL) {
return 0;
}
/* Copy the content of |a| into |r|. */
OPENSSL_memcpy(r->d, a->d, num_words * sizeof(BN_ULONG));
/* If |e| isn't word-aligned, we have to mask off some of our bits. */
size_t top_word_exponent = e % (sizeof(BN_ULONG) * 8);
if (top_word_exponent != 0) {
r->d[num_words - 1] &= (((BN_ULONG) 1) << top_word_exponent) - 1;
}
/* Fill in the remaining fields of |r|. */
r->neg = a->neg;
r->top = (int) num_words;
bn_correct_top(r);
return 1;
}
int BN_nnmod_pow2(BIGNUM *r, const BIGNUM *a, size_t e) {
if (!BN_mod_pow2(r, a, e)) {
return 0;
}
/* If the returned value was non-negative, we're done. */
if (BN_is_zero(r) || !r->neg) {
return 1;
}
size_t num_words = 1 + (e - 1) / BN_BITS2;
/* Expand |r| to the size of our modulus. */
if (bn_wexpand(r, num_words) == NULL) {
return 0;
}
/* Clear the upper words of |r|. */
OPENSSL_memset(&r->d[r->top], 0, (num_words - r->top) * BN_BYTES);
/* Set parameters of |r|. */
r->neg = 0;
r->top = (int) num_words;
/* Now, invert every word. The idea here is that we want to compute 2^e-|x|,
* which is actually equivalent to the twos-complement representation of |x|
* in |e| bits, which is -x = ~x + 1. */
for (int i = 0; i < r->top; i++) {
r->d[i] = ~r->d[i];
}
/* If our exponent doesn't span the top word, we have to mask the rest. */
size_t top_word_exponent = e % BN_BITS2;
if (top_word_exponent != 0) {
r->d[r->top - 1] &= (((BN_ULONG) 1) << top_word_exponent) - 1;
}
/* Keep the correct_top invariant for BN_add. */
bn_correct_top(r);
/* Finally, add one, for the reason described above. */
return BN_add(r, r, BN_value_one());
}
+15 -33
View File
@@ -140,12 +140,6 @@ int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
int i, bits, ret = 0;
BIGNUM *v, *rr;
if ((p->flags & BN_FLG_CONSTTIME) != 0) {
/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
BN_CTX_start(ctx);
if (r == a || r == p) {
rr = BN_CTX_get(ctx);
@@ -437,12 +431,6 @@ static int mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
BIGNUM *val[TABLE_SIZE];
BN_RECP_CTX recp;
if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
bits = BN_num_bits(p);
if (bits == 0) {
@@ -593,10 +581,6 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
BIGNUM *val[TABLE_SIZE];
BN_MONT_CTX *new_mont = NULL;
if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, mont);
}
if (!BN_is_odd(m)) {
OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
return 0;
@@ -876,6 +860,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
int powerbufLen = 0;
unsigned char *powerbuf = NULL;
BIGNUM tmp, am;
BIGNUM *new_a = NULL;
if (!BN_is_odd(m)) {
OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
@@ -903,6 +888,15 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
mont = new_mont;
}
if (a->neg || BN_ucmp(a, m) >= 0) {
new_a = BN_new();
if (new_a == NULL ||
!BN_nnmod(new_a, a, m, ctx)) {
goto err;
}
a = new_a;
}
#ifdef RSAZ_ENABLED
/* If the size of the operands allow it, perform the optimized
* RSAZ exponentiation. For further information see
@@ -918,16 +912,6 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
bn_correct_top(rr);
ret = 1;
goto err;
} else if ((8 == a->top) && (8 == p->top) && (BN_num_bits(m) == 512)) {
if (NULL == bn_wexpand(rr, 8)) {
goto err;
}
RSAZ_512_mod_exp(rr->d, a->d, p->d, m->d, mont->n0[0], mont->RR.d);
rr->top = 8;
rr->neg = 0;
bn_correct_top(rr);
ret = 1;
goto err;
}
#endif
@@ -961,7 +945,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
}
powerbuf = MOD_EXP_CTIME_ALIGN(powerbufFree);
memset(powerbuf, 0, powerbufLen);
OPENSSL_memset(powerbuf, 0, powerbufLen);
#ifdef alloca
if (powerbufLen < 3072) {
@@ -991,12 +975,9 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
}
/* prepare a^1 in Montgomery domain */
if (a->neg || BN_ucmp(a, m) >= 0) {
if (!BN_nnmod(&am, a, m, ctx) ||
!BN_to_montgomery(&am, &am, mont, ctx)) {
goto err;
}
} else if (!BN_to_montgomery(&am, a, mont, ctx)) {
assert(!a->neg);
assert(BN_ucmp(a, m) < 0);
if (!BN_to_montgomery(&am, a, mont, ctx)) {
goto err;
}
@@ -1190,6 +1171,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
err:
BN_MONT_CTX_free(new_mont);
BN_clear_free(new_a);
if (powerbuf != NULL) {
OPENSSL_cleanse(powerbuf, powerbufLen);
OPENSSL_free(powerbufFree);
+29 -22
View File
@@ -399,10 +399,6 @@ err:
BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n,
BN_CTX *ctx) {
int no_inverse;
BIGNUM *a_reduced = NULL;
BIGNUM *new_out = NULL;
if (out == NULL) {
new_out = BN_new();
@@ -414,25 +410,20 @@ BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n,
}
int ok = 0;
int no_branch =
(a->flags & BN_FLG_CONSTTIME) != 0 || (n->flags & BN_FLG_CONSTTIME) != 0;
BIGNUM *a_reduced = NULL;
if (a->neg || BN_ucmp(a, n) >= 0) {
a_reduced = BN_dup(a);
if (a_reduced == NULL) {
goto err;
}
if (no_branch) {
BN_set_flags(a_reduced, BN_FLG_CONSTTIME);
}
if (!BN_nnmod(a_reduced, a_reduced, n, ctx)) {
goto err;
}
a = a_reduced;
}
if (no_branch || !BN_is_odd(n)) {
int no_inverse;
if (!BN_is_odd(n)) {
if (!bn_mod_inverse_general(out, &no_inverse, a, n, ctx)) {
goto err;
}
@@ -481,15 +472,13 @@ err:
/* bn_mod_inverse_general is the general inversion algorithm that works for
* both even and odd |n|. It was specifically designed to contain fewer
* branches that may leak sensitive information. See "New Branch Prediction
* branches that may leak sensitive information; see "New Branch Prediction
* Vulnerabilities in OpenSSL and Necessary Software Countermeasures" by
* Onur Acıçmez, Shay Gueron, and Jean-Pierre Seifert. */
static int bn_mod_inverse_general(BIGNUM *out, int *out_no_inverse,
const BIGNUM *a, const BIGNUM *n,
BN_CTX *ctx) {
BIGNUM *A, *B, *X, *Y, *M, *D, *T;
BIGNUM local_A;
BIGNUM *pA;
int ret = 0;
int sign;
@@ -532,14 +521,8 @@ static int bn_mod_inverse_general(BIGNUM *out, int *out_no_inverse,
* sign*Y*a == A (mod |n|)
*/
/* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
* BN_div_no_branch will be called eventually.
*/
pA = &local_A;
BN_with_flags(pA, A, BN_FLG_CONSTTIME);
/* (D, M) := (A/B, A%B) ... */
if (!BN_div(D, M, pA, B, ctx)) {
if (!BN_div(D, M, A, B, ctx)) {
goto err;
}
@@ -626,3 +609,27 @@ err:
BN_CTX_end(ctx);
return ret;
}
int bn_mod_inverse_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p,
BN_CTX *ctx, const BN_MONT_CTX *mont_p) {
BN_CTX_start(ctx);
BIGNUM *p_minus_2 = BN_CTX_get(ctx);
int ok = p_minus_2 != NULL &&
BN_copy(p_minus_2, p) &&
BN_sub_word(p_minus_2, 2) &&
BN_mod_exp_mont(out, a, p_minus_2, p, ctx, mont_p);
BN_CTX_end(ctx);
return ok;
}
int bn_mod_inverse_secret_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p,
BN_CTX *ctx, const BN_MONT_CTX *mont_p) {
BN_CTX_start(ctx);
BIGNUM *p_minus_2 = BN_CTX_get(ctx);
int ok = p_minus_2 != NULL &&
BN_copy(p_minus_2, p) &&
BN_sub_word(p_minus_2, 2) &&
BN_mod_exp_mont_consttime(out, a, p_minus_2, p, ctx, mont_p);
BN_CTX_end(ctx);
return ok;
}
+13
View File
@@ -228,6 +228,7 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
const BN_ULONG *np, const BN_ULONG *n0, int num);
uint64_t bn_mont_n0(const BIGNUM *n);
int bn_mod_exp_base_2_vartime(BIGNUM *r, unsigned p, const BIGNUM *n);
#if defined(OPENSSL_X86_64) && defined(_MSC_VER)
#define BN_UMULT_LOHI(low, high, a, b) ((low) = _umul128((a), (b), &(high)))
@@ -237,6 +238,18 @@ uint64_t bn_mont_n0(const BIGNUM *n);
#error "Either BN_ULLONG or BN_UMULT_LOHI must be defined on every platform."
#endif
/* bn_mod_inverse_prime sets |out| to the modular inverse of |a| modulo |p|,
* computed with Fermat's Little Theorem. It returns one on success and zero on
* error. If |mont_p| is NULL, one will be computed temporarily. */
int bn_mod_inverse_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p,
BN_CTX *ctx, const BN_MONT_CTX *mont_p);
/* bn_mod_inverse_secret_prime behaves like |bn_mod_inverse_prime| but uses
* |BN_mod_exp_mont_consttime| instead of |BN_mod_exp_mont| in hopes of
* protecting the exponent. */
int bn_mod_inverse_secret_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p,
BN_CTX *ctx, const BN_MONT_CTX *mont_p);
#if defined(__cplusplus)
} /* extern C */
+1
View File
@@ -144,6 +144,7 @@ int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) {
i++;
}
if (!BN_rshift(A, A, i)) {
ret = -2;
goto end;
}
if (i & 1) {
+45 -25
View File
@@ -108,6 +108,7 @@
#include <openssl/bn.h>
#include <assert.h>
#include <string.h>
#include <openssl/err.h>
@@ -124,6 +125,11 @@
#define OPENSSL_BN_ASM_MONT
#endif
static int bn_mod_mul_montgomery_fallback(BIGNUM *r, const BIGNUM *a,
const BIGNUM *b,
const BN_MONT_CTX *mont, BN_CTX *ctx);
BN_MONT_CTX *BN_MONT_CTX_new(void) {
BN_MONT_CTX *ret = OPENSSL_malloc(sizeof(BN_MONT_CTX));
@@ -131,7 +137,7 @@ BN_MONT_CTX *BN_MONT_CTX_new(void) {
return NULL;
}
memset(ret, 0, sizeof(BN_MONT_CTX));
OPENSSL_memset(ret, 0, sizeof(BN_MONT_CTX));
BN_init(&ret->RR);
BN_init(&ret->N);
@@ -186,9 +192,6 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) {
OPENSSL_PUT_ERROR(BN, ERR_R_INTERNAL_ERROR);
return 0;
}
if (BN_get_flags(mod, BN_FLG_CONSTTIME)) {
BN_set_flags(&mont->N, BN_FLG_CONSTTIME);
}
/* Find n0 such that n0 * N == -1 (mod r).
*
@@ -207,12 +210,13 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) {
/* Save RR = R**2 (mod N). R is the smallest power of 2**BN_BITS such that R
* > mod. Even though the assembly on some 32-bit platforms works with 64-bit
* values, using |BN_BITS2| here, rather than |BN_MONT_CTX_N0_LIMBS *
* BN_BITS2|, is correct because because R^2 will still be a multiple of the
* latter as |BN_MONT_CTX_N0_LIMBS| is either one or two. */
* BN_BITS2|, is correct because R**2 will still be a multiple of the latter
* as |BN_MONT_CTX_N0_LIMBS| is either one or two.
*
* XXX: This is not constant time with respect to |mont->N|, but it should
* be. */
unsigned lgBigR = (BN_num_bits(mod) + (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2;
BN_zero(&mont->RR);
if (!BN_set_bit(&mont->RR, lgBigR * 2) ||
!BN_mod(&mont->RR, &mont->RR, &mont->N, ctx)) {
if (!bn_mod_exp_base_2_vartime(&mont->RR, lgBigR * 2, &mont->N)) {
return 0;
}
@@ -279,7 +283,7 @@ static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r,
/* clear the top words of T */
if (max > r->top) {
memset(&rp[r->top], 0, (max - r->top) * sizeof(BN_ULONG));
OPENSSL_memset(&rp[r->top], 0, (max - r->top) * sizeof(BN_ULONG));
}
r->top = max;
@@ -362,27 +366,43 @@ err:
int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
const BN_MONT_CTX *mont, BN_CTX *ctx) {
BIGNUM *tmp;
int ret = 0;
#if defined(OPENSSL_BN_ASM_MONT)
#if !defined(OPENSSL_BN_ASM_MONT)
return bn_mod_mul_montgomery_fallback(r, a, b, mont, ctx);
#else
int num = mont->N.top;
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);
return 1;
}
/* |bn_mul_mont| requires at least 128 bits of limbs, at least for x86. */
if (num < (128 / BN_BITS2) ||
a->top != num ||
b->top != num) {
return bn_mod_mul_montgomery_fallback(r, a, b, mont, ctx);
}
if (bn_wexpand(r, num) == NULL) {
return 0;
}
if (!bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) {
/* The check above ensures this won't happen. */
assert(0);
OPENSSL_PUT_ERROR(BN, ERR_R_INTERNAL_ERROR);
return 0;
}
r->neg = a->neg ^ b->neg;
r->top = num;
bn_correct_top(r);
return 1;
#endif
}
static int bn_mod_mul_montgomery_fallback(BIGNUM *r, const BIGNUM *a,
const BIGNUM *b,
const BN_MONT_CTX *mont,
BN_CTX *ctx) {
int ret = 0;
BN_CTX_start(ctx);
tmp = BN_CTX_get(ctx);
BIGNUM *tmp = BN_CTX_get(ctx);
if (tmp == NULL) {
goto err;
}
+47
View File
@@ -158,3 +158,50 @@ static uint64_t bn_neg_inv_mod_r_u64(uint64_t n) {
return v;
}
/* bn_mod_exp_base_2_vartime calculates r = 2**p (mod n). |p| must be larger
* than log_2(n); i.e. 2**p must be larger than |n|. |n| must be positive and
* odd. */
int bn_mod_exp_base_2_vartime(BIGNUM *r, unsigned p, const BIGNUM *n) {
assert(!BN_is_zero(n));
assert(!BN_is_negative(n));
assert(BN_is_odd(n));
BN_zero(r);
unsigned n_bits = BN_num_bits(n);
assert(n_bits != 0);
if (n_bits == 1) {
return 1;
}
/* Set |r| to the smallest power of two larger than |n|. */
assert(p > n_bits);
if (!BN_set_bit(r, n_bits)) {
return 0;
}
/* Unconditionally reduce |r|. */
assert(BN_cmp(r, n) > 0);
if (!BN_usub(r, r, n)) {
return 0;
}
assert(BN_cmp(r, n) < 0);
for (unsigned i = n_bits; i < p; ++i) {
/* This is like |BN_mod_lshift1_quick| except using |BN_usub|.
*
* TODO: Replace this with the use of a constant-time variant of
* |BN_mod_lshift1_quick|. */
if (!BN_lshift1(r, r)) {
return 0;
}
if (BN_cmp(r, n) >= 0) {
if (!BN_usub(r, r, n)) {
return 0;
}
}
}
return 1;
}
+11 -9
View File
@@ -312,7 +312,8 @@ static void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL) {
bn_mul_normal(r, a, n2 + dna, b, n2 + dnb);
if ((dna + dnb) < 0) {
memset(&r[2 * n2 + dna + dnb], 0, sizeof(BN_ULONG) * -(dna + dnb));
OPENSSL_memset(&r[2 * n2 + dna + dnb], 0,
sizeof(BN_ULONG) * -(dna + dnb));
}
return;
}
@@ -358,7 +359,7 @@ static void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
if (!zero) {
bn_mul_comba4(&(t[n2]), t, &(t[n]));
} else {
memset(&(t[n2]), 0, 8 * sizeof(BN_ULONG));
OPENSSL_memset(&(t[n2]), 0, 8 * sizeof(BN_ULONG));
}
bn_mul_comba4(r, a, b);
@@ -368,7 +369,7 @@ static void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
if (!zero) {
bn_mul_comba8(&(t[n2]), t, &(t[n]));
} else {
memset(&(t[n2]), 0, 16 * sizeof(BN_ULONG));
OPENSSL_memset(&(t[n2]), 0, 16 * sizeof(BN_ULONG));
}
bn_mul_comba8(r, a, b);
@@ -378,7 +379,7 @@ static void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
if (!zero) {
bn_mul_recursive(&(t[n2]), t, &(t[n]), n, 0, 0, p);
} else {
memset(&(t[n2]), 0, n2 * sizeof(BN_ULONG));
OPENSSL_memset(&(t[n2]), 0, n2 * sizeof(BN_ULONG));
}
bn_mul_recursive(r, a, b, n, 0, 0, p);
bn_mul_recursive(&(r[n2]), &(a[n]), &(b[n]), n, dna, dnb, p);
@@ -473,7 +474,7 @@ static void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n,
bn_mul_comba8(&(t[n2]), t, &(t[n]));
bn_mul_comba8(r, a, b);
bn_mul_normal(&(r[n2]), &(a[n]), tna, &(b[n]), tnb);
memset(&(r[n2 + tna + tnb]), 0, sizeof(BN_ULONG) * (n2 - tna - tnb));
OPENSSL_memset(&(r[n2 + tna + tnb]), 0, sizeof(BN_ULONG) * (n2 - tna - tnb));
} else {
p = &(t[n2 * 2]);
bn_mul_recursive(&(t[n2]), t, &(t[n]), n, 0, 0, p);
@@ -489,14 +490,15 @@ static void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n,
if (j == 0) {
bn_mul_recursive(&(r[n2]), &(a[n]), &(b[n]), i, tna - i, tnb - i, p);
memset(&(r[n2 + i * 2]), 0, sizeof(BN_ULONG) * (n2 - i * 2));
OPENSSL_memset(&(r[n2 + i * 2]), 0, sizeof(BN_ULONG) * (n2 - i * 2));
} else if (j > 0) {
/* eg, n == 16, i == 8 and tn == 11 */
bn_mul_part_recursive(&(r[n2]), &(a[n]), &(b[n]), i, tna - i, tnb - i, p);
memset(&(r[n2 + tna + tnb]), 0, sizeof(BN_ULONG) * (n2 - tna - tnb));
OPENSSL_memset(&(r[n2 + tna + tnb]), 0,
sizeof(BN_ULONG) * (n2 - tna - tnb));
} else {
/* (j < 0) eg, n == 16, i == 8 and tn == 5 */
memset(&(r[n2]), 0, sizeof(BN_ULONG) * n2);
OPENSSL_memset(&(r[n2]), 0, sizeof(BN_ULONG) * n2);
if (tna < BN_MUL_RECURSIVE_SIZE_NORMAL &&
tnb < BN_MUL_RECURSIVE_SIZE_NORMAL) {
bn_mul_normal(&(r[n2]), &(a[n]), tna, &(b[n]), tnb);
@@ -735,7 +737,7 @@ static void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t
if (!zero) {
bn_sqr_recursive(&(t[n2]), t, n, p);
} else {
memset(&(t[n2]), 0, n2 * sizeof(BN_ULONG));
OPENSSL_memset(&(t[n2]), 0, n2 * sizeof(BN_ULONG));
}
bn_sqr_recursive(r, a, n, p);
bn_sqr_recursive(&(r[n2]), &(a[n]), n, p);
+6 -3
View File
@@ -115,6 +115,9 @@
#include <openssl/rand.h>
#include <openssl/sha.h>
#include "../internal.h"
int BN_rand(BIGNUM *rnd, int bits, int top, int bottom) {
uint8_t *buf = NULL;
int ret = 0, bit, bytes, mask;
@@ -298,8 +301,8 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, const BIGNUM *priv,
OPENSSL_PUT_ERROR(BN, BN_R_PRIVATE_KEY_TOO_LARGE);
goto err;
}
memcpy(private_bytes, priv->d, todo);
memset(private_bytes + todo, 0, sizeof(private_bytes) - todo);
OPENSSL_memcpy(private_bytes, priv->d, todo);
OPENSSL_memset(private_bytes + todo, 0, sizeof(private_bytes) - todo);
for (attempt = 0;; attempt++) {
for (done = 0; done < num_k_bytes;) {
@@ -318,7 +321,7 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, const BIGNUM *priv,
if (todo > SHA512_DIGEST_LENGTH) {
todo = SHA512_DIGEST_LENGTH;
}
memcpy(k_bytes + done, digest, todo);
OPENSSL_memcpy(k_bytes + done, digest, todo);
done += todo;
}
-65
View File
@@ -251,69 +251,4 @@ void RSAZ_1024_mod_exp_avx2(BN_ULONG result_norm[16],
OPENSSL_cleanse(storage,sizeof(storage));
}
/*
* See crypto/bn/rsaz-x86_64.pl for further details.
*/
void rsaz_512_mul(void *ret,const void *a,const void *b,const void *n,BN_ULONG k);
void rsaz_512_mul_scatter4(void *ret,const void *a,const void *n,BN_ULONG k,const void *tbl,unsigned int power);
void rsaz_512_mul_gather4(void *ret,const void *a,const void *tbl,const void *n,BN_ULONG k,unsigned int power);
void rsaz_512_mul_by_one(void *ret,const void *a,const void *n,BN_ULONG k);
void rsaz_512_sqr(void *ret,const void *a,const void *n,BN_ULONG k,int cnt);
void rsaz_512_scatter4(void *tbl, const BN_ULONG *val, int power);
void rsaz_512_gather4(BN_ULONG *val, const void *tbl, int power);
void RSAZ_512_mod_exp(BN_ULONG result[8],
const BN_ULONG base[8], const BN_ULONG exponent[8],
const BN_ULONG m[8], BN_ULONG k0, const BN_ULONG RR[8])
{
alignas(64) uint8_t storage[(16*8*8) + (64 * 2)]; /* 1.2KB */
unsigned char *table = storage;
BN_ULONG *a_inv = (BN_ULONG *)(table+16*8*8),
*temp = (BN_ULONG *)(table+16*8*8+8*8);
int index;
unsigned int wvalue;
/* table[0] = 1_inv */
temp[0] = 0-m[0]; temp[1] = ~m[1];
temp[2] = ~m[2]; temp[3] = ~m[3];
temp[4] = ~m[4]; temp[5] = ~m[5];
temp[6] = ~m[6]; temp[7] = ~m[7];
rsaz_512_scatter4(table, temp, 0);
/* table [1] = a_inv^1 */
rsaz_512_mul(a_inv, base, RR, m, k0);
rsaz_512_scatter4(table, a_inv, 1);
/* table [2] = a_inv^2 */
rsaz_512_sqr(temp, a_inv, m, k0, 1);
rsaz_512_scatter4(table, temp, 2);
for (index=3; index<16; index++)
rsaz_512_mul_scatter4(temp, a_inv, m, k0, table, index);
const uint8_t *p_str = (const uint8_t *)exponent;
/* load first window */
wvalue = p_str[63];
rsaz_512_gather4(temp, table, wvalue>>4);
rsaz_512_sqr(temp, temp, m, k0, 4);
rsaz_512_mul_gather4(temp, temp, table, m, k0, wvalue&0xf);
for (index=62; index>=0; index--) {
wvalue = p_str[index];
rsaz_512_sqr(temp, temp, m, k0, 4);
rsaz_512_mul_gather4(temp, temp, table, m, k0, wvalue>>4);
rsaz_512_sqr(temp, temp, m, k0, 4);
rsaz_512_mul_gather4(temp, temp, table, m, k0, wvalue&0x0f);
}
/* from Montgomery */
rsaz_512_mul_by_one(result, temp, m, k0);
OPENSSL_cleanse(storage,sizeof(storage));
}
#endif /* OPENSSL_X86_64 */
-3
View File
@@ -50,7 +50,4 @@ void RSAZ_1024_mod_exp_avx2(BN_ULONG result[16],
const BN_ULONG m_norm[16], const BN_ULONG RR[16], BN_ULONG k0);
int rsaz_avx2_eligible(void);
void RSAZ_512_mod_exp(BN_ULONG result[8],
const BN_ULONG base_norm[8], const BN_ULONG exponent[8],
const BN_ULONG m_norm[8], BN_ULONG k0, const BN_ULONG RR[8]);
#endif
+9 -1
View File
@@ -94,7 +94,7 @@ int BN_lshift(BIGNUM *r, const BIGNUM *a, int n) {
t[nw + i] = (l << lb) & BN_MASK2;
}
}
memset(t, 0, nw * sizeof(t[0]));
OPENSSL_memset(t, 0, nw * sizeof(t[0]));
r->top = a->top + nw + 1;
bn_correct_top(r);
@@ -182,6 +182,10 @@ int BN_rshift(BIGNUM *r, const BIGNUM *a, int n) {
}
}
if (r->top == 0) {
r->neg = 0;
}
return 1;
}
@@ -215,6 +219,10 @@ int BN_rshift1(BIGNUM *r, const BIGNUM *a) {
}
r->top = j;
if (r->top == 0) {
r->neg = 0;
}
return 1;
}
+7 -5
View File
@@ -148,7 +148,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
}
q->neg = 0;
if (!BN_add_word(q, 1) ||
!BN_mod_exp(ret, A, q, p, ctx)) {
!BN_mod_exp_mont(ret, A, q, p, ctx, NULL)) {
goto end;
}
err = 0;
@@ -193,7 +193,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
goto end;
}
q->neg = 0;
if (!BN_mod_exp(b, t, q, p, ctx)) {
if (!BN_mod_exp_mont(b, t, q, p, ctx, NULL)) {
goto end;
}
@@ -281,7 +281,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
/* Now that we have some non-square, we can find an element
* of order 2^e by computing its q'th power. */
if (!BN_mod_exp(y, y, q, p, ctx)) {
if (!BN_mod_exp_mont(y, y, q, p, ctx, NULL)) {
goto end;
}
if (BN_is_one(y)) {
@@ -327,7 +327,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
goto end;
}
} else {
if (!BN_mod_exp(x, A, t, p, ctx)) {
if (!BN_mod_exp_mont(x, A, t, p, ctx, NULL)) {
goto end;
}
if (BN_is_zero(x)) {
@@ -456,7 +456,9 @@ int BN_sqrt(BIGNUM *out_sqrt, const BIGNUM *in, BN_CTX *ctx) {
}
/* We estimate that the square root of an n-bit number is 2^{n/2}. */
BN_lshift(estimate, BN_value_one(), BN_num_bits(in)/2);
if (!BN_lshift(estimate, BN_value_one(), BN_num_bits(in)/2)) {
goto err;
}
/* This is Newton's method for finding a root of the equation |estimate|^2 -
* |in| = 0. */
+6 -4
View File
@@ -61,6 +61,8 @@
#include <openssl/mem.h>
#include <openssl/err.h>
#include "../internal.h"
BUF_MEM *BUF_MEM_new(void) {
BUF_MEM *ret;
@@ -71,7 +73,7 @@ BUF_MEM *BUF_MEM_new(void) {
return NULL;
}
memset(ret, 0, sizeof(BUF_MEM));
OPENSSL_memset(ret, 0, sizeof(BUF_MEM));
return ret;
}
@@ -137,7 +139,7 @@ static size_t buf_mem_grow(BUF_MEM *buf, size_t len, int clean) {
return 0;
}
if (buf->length < len) {
memset(&buf->data[buf->length], 0, len - buf->length);
OPENSSL_memset(&buf->data[buf->length], 0, len - buf->length);
}
buf->length = len;
return len;
@@ -193,7 +195,7 @@ char *BUF_strndup(const char *buf, size_t size) {
return NULL;
}
memcpy(ret, buf, size);
OPENSSL_memcpy(ret, buf, size);
ret[size] = '\0';
return ret;
}
@@ -234,6 +236,6 @@ void *BUF_memdup(const void *data, size_t dst_size) {
return NULL;
}
memcpy(ret, data, dst_size);
OPENSSL_memcpy(ret, data, dst_size);
return ret;
}
+2 -1
View File
@@ -22,6 +22,7 @@
#include <openssl/mem.h>
#include "internal.h"
#include "../internal.h"
int CBB_finish_i2d(CBB *cbb, uint8_t **outp) {
@@ -42,7 +43,7 @@ int CBB_finish_i2d(CBB *cbb, uint8_t **outp) {
*outp = der;
der = NULL;
} else {
memcpy(*outp, der, der_len);
OPENSSL_memcpy(*outp, der, der_len);
*outp += der_len;
}
}
+3 -2
View File
@@ -18,6 +18,7 @@
#include <string.h>
#include "internal.h"
#include "../internal.h"
/* kMaxDepth is a just a sanity limit. The code should be such that the length
@@ -37,7 +38,7 @@ static int is_string_type(unsigned tag) {
case CBS_ASN1_UTF8STRING:
case CBS_ASN1_NUMERICSTRING:
case CBS_ASN1_PRINTABLESTRING:
case CBS_ASN1_T16STRING:
case CBS_ASN1_T61STRING:
case CBS_ASN1_VIDEOTEXSTRING:
case CBS_ASN1_IA5STRING:
case CBS_ASN1_GRAPHICSTRING:
@@ -100,7 +101,7 @@ static int cbs_find_ber(const CBS *orig_in, char *ber_found, unsigned depth) {
* |CBS_get_any_ber_asn1_element|, indicate an "end of contents" (EOC) value. */
static char is_eoc(size_t header_len, CBS *contents) {
return header_len == 2 && CBS_len(contents) == 2 &&
memcmp(CBS_data(contents), "\x00\x00", 2) == 0;
OPENSSL_memcmp(CBS_data(contents), "\x00\x00", 2) == 0;
}
/* cbs_convert_ber reads BER data from |in| and writes DER data to |out|. If
+108 -32
View File
@@ -28,7 +28,6 @@
#include "internal.h"
#include "../internal.h"
namespace bssl {
static bool TestSkip() {
static const uint8_t kData[] = {1, 2, 3};
@@ -133,7 +132,7 @@ static bool TestGetASN1() {
}
if (!CBS_get_asn1(&data, &contents, 0x30) ||
CBS_len(&contents) != 2 ||
memcmp(CBS_data(&contents), "\x01\x02", 2) != 0) {
OPENSSL_memcmp(CBS_data(&contents), "\x01\x02", 2) != 0) {
return false;
}
@@ -194,7 +193,7 @@ static bool TestGetASN1() {
!CBS_get_optional_asn1(&data, &contents, &present, 0xa1) ||
!present ||
CBS_len(&contents) != 3 ||
memcmp(CBS_data(&contents), "\x04\x01\x01", 3) != 0) {
OPENSSL_memcmp(CBS_data(&contents), "\x04\x01\x01", 3) != 0) {
return false;
}
@@ -236,7 +235,7 @@ static bool TestGetASN1() {
if (!CBS_get_any_asn1(&data, &contents, &tag) ||
tag != CBS_ASN1_SEQUENCE ||
CBS_len(&contents) != 2 ||
memcmp(CBS_data(&contents), "\x01\x02", 2) != 0) {
OPENSSL_memcmp(CBS_data(&contents), "\x01\x02", 2) != 0) {
return false;
}
@@ -246,7 +245,7 @@ static bool TestGetASN1() {
tag != CBS_ASN1_SEQUENCE ||
header_len != 2 ||
CBS_len(&contents) != 4 ||
memcmp(CBS_data(&contents), "\x30\x02\x01\x02", 2) != 0) {
OPENSSL_memcmp(CBS_data(&contents), "\x30\x02\x01\x02", 2) != 0) {
return false;
}
@@ -313,11 +312,12 @@ static bool TestCBBBasic() {
}
bssl::UniquePtr<uint8_t> scoper(buf);
return buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0;
return buf_len == sizeof(kExpected) &&
OPENSSL_memcmp(buf, kExpected, buf_len) == 0;
}
static bool TestCBBFixed() {
ScopedCBB cbb;
bssl::ScopedCBB cbb;
uint8_t buf[1];
uint8_t *out_buf;
size_t out_size;
@@ -397,11 +397,12 @@ static bool TestCBBPrefixed() {
}
bssl::UniquePtr<uint8_t> scoper(buf);
return buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0;
return buf_len == sizeof(kExpected) &&
OPENSSL_memcmp(buf, kExpected, buf_len) == 0;
}
static bool TestCBBDiscardChild() {
ScopedCBB cbb;
bssl::ScopedCBB cbb;
CBB contents, inner_contents, inner_inner_contents;
if (!CBB_init(cbb.get(), 0) ||
@@ -446,7 +447,8 @@ static bool TestCBBDiscardChild() {
0, 0, 3, 0xdd, 0xdd, 0xdd,
1, 0xff,
};
return buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0;
return buf_len == sizeof(kExpected) &&
OPENSSL_memcmp(buf, kExpected, buf_len) == 0;
}
static bool TestCBBMisuse() {
@@ -485,7 +487,7 @@ static bool TestCBBMisuse() {
bssl::UniquePtr<uint8_t> scoper(buf);
if (buf_len != 3 ||
memcmp(buf, "\x01\x01\x02", 3) != 0) {
OPENSSL_memcmp(buf, "\x01\x01\x02", 3) != 0) {
return false;
}
return true;
@@ -508,7 +510,8 @@ static bool TestCBBASN1() {
}
bssl::UniquePtr<uint8_t> scoper(buf);
if (buf_len != sizeof(kExpected) || memcmp(buf, kExpected, buf_len) != 0) {
if (buf_len != sizeof(kExpected) ||
OPENSSL_memcmp(buf, kExpected, buf_len) != 0) {
return false;
}
@@ -526,8 +529,8 @@ static bool TestCBBASN1() {
scoper.reset(buf);
if (buf_len != 3 + 130 ||
memcmp(buf, "\x30\x81\x82", 3) != 0 ||
memcmp(buf + 3, test_data.data(), 130) != 0) {
OPENSSL_memcmp(buf, "\x30\x81\x82", 3) != 0 ||
OPENSSL_memcmp(buf + 3, test_data.data(), 130) != 0) {
return false;
}
@@ -543,8 +546,8 @@ static bool TestCBBASN1() {
scoper.reset(buf);
if (buf_len != 4 + 1000 ||
memcmp(buf, "\x30\x82\x03\xe8", 4) != 0 ||
memcmp(buf + 4, test_data.data(), 1000)) {
OPENSSL_memcmp(buf, "\x30\x82\x03\xe8", 4) != 0 ||
OPENSSL_memcmp(buf + 4, test_data.data(), 1000)) {
return false;
}
@@ -561,8 +564,9 @@ static bool TestCBBASN1() {
scoper.reset(buf);
if (buf_len != 5 + 5 + 100000 ||
memcmp(buf, "\x30\x83\x01\x86\xa5\x30\x83\x01\x86\xa0", 10) != 0 ||
memcmp(buf + 10, test_data.data(), 100000)) {
OPENSSL_memcmp(buf, "\x30\x83\x01\x86\xa5\x30\x83\x01\x86\xa0", 10) !=
0 ||
OPENSSL_memcmp(buf + 10, test_data.data(), 100000)) {
return false;
}
@@ -585,7 +589,7 @@ static bool DoBerConvert(const char *name,
if (out == NULL) {
if (ber_len != der_len ||
memcmp(der_expected, ber, ber_len) != 0) {
OPENSSL_memcmp(der_expected, ber, ber_len) != 0) {
fprintf(stderr, "%s: incorrect unconverted result.\n", name);
return false;
}
@@ -594,7 +598,7 @@ static bool DoBerConvert(const char *name,
}
if (out_len != der_len ||
memcmp(out, der_expected, der_len) != 0) {
OPENSSL_memcmp(out, der_expected, der_len) != 0) {
fprintf(stderr, "%s: incorrect converted result.\n", name);
return false;
}
@@ -703,7 +707,7 @@ static bool TestImplicitString() {
}
if (ok && (CBS_len(&out) != test.out_len ||
memcmp(CBS_data(&out), test.out, test.out_len) != 0)) {
OPENSSL_memcmp(CBS_data(&out), test.out, test.out_len) != 0)) {
fprintf(stderr, "CBS_get_asn1_implicit_string gave the wrong output\n");
return false;
}
@@ -773,7 +777,8 @@ static bool TestASN1Uint64() {
return false;
}
bssl::UniquePtr<uint8_t> scoper(out);
if (len != test->encoding_len || memcmp(out, test->encoding, len) != 0) {
if (len != test->encoding_len ||
OPENSSL_memcmp(out, test->encoding, len) != 0) {
return false;
}
}
@@ -804,7 +809,7 @@ static bool TestCBBReserve() {
uint8_t buf[10];
uint8_t *ptr;
size_t len;
ScopedCBB cbb;
bssl::ScopedCBB cbb;
if (!CBB_init_fixed(cbb.get(), buf, sizeof(buf)) ||
// Too large.
CBB_reserve(cbb.get(), &ptr, 11)) {
@@ -827,7 +832,7 @@ static bool TestCBBReserve() {
static bool TestStickyError() {
// Write an input that exceeds the limit for its length prefix.
ScopedCBB cbb;
bssl::ScopedCBB cbb;
CBB child;
static const uint8_t kZeros[256] = {0};
if (!CBB_init(cbb.get(), 0) ||
@@ -890,7 +895,83 @@ static bool TestStickyError() {
return true;
}
static int Main() {
static bool TestBitString() {
static const std::vector<uint8_t> kValidBitStrings[] = {
{0x00}, // 0 bits
{0x07, 0x80}, // 1 bit
{0x04, 0xf0}, // 4 bits
{0x00, 0xff}, // 8 bits
{0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0}, // 42 bits
};
for (const auto& test : kValidBitStrings) {
CBS cbs;
CBS_init(&cbs, test.data(), test.size());
if (!CBS_is_valid_asn1_bitstring(&cbs)) {
return false;
}
}
static const std::vector<uint8_t> kInvalidBitStrings[] = {
// BIT STRINGs always have a leading byte.
std::vector<uint8_t>{},
// It's not possible to take an unused bit off the empty string.
{0x01},
// There can be at most 7 unused bits.
{0x08, 0xff},
{0xff, 0xff},
// All unused bits must be cleared.
{0x06, 0xff, 0xc1},
};
for (const auto& test : kInvalidBitStrings) {
CBS cbs;
CBS_init(&cbs, test.data(), test.size());
if (CBS_is_valid_asn1_bitstring(&cbs)) {
return false;
}
// CBS_asn1_bitstring_has_bit returns false on invalid inputs.
if (CBS_asn1_bitstring_has_bit(&cbs, 0)) {
return false;
}
}
static const struct {
std::vector<uint8_t> in;
unsigned bit;
bool bit_set;
} kBitTests[] = {
// Basic tests.
{{0x00}, 0, false},
{{0x07, 0x80}, 0, true},
{{0x06, 0x0f, 0x40}, 0, false},
{{0x06, 0x0f, 0x40}, 1, false},
{{0x06, 0x0f, 0x40}, 2, false},
{{0x06, 0x0f, 0x40}, 3, false},
{{0x06, 0x0f, 0x40}, 4, true},
{{0x06, 0x0f, 0x40}, 5, true},
{{0x06, 0x0f, 0x40}, 6, true},
{{0x06, 0x0f, 0x40}, 7, true},
{{0x06, 0x0f, 0x40}, 8, false},
{{0x06, 0x0f, 0x40}, 9, true},
// Out-of-bounds bits return 0.
{{0x06, 0x0f, 0x40}, 10, false},
{{0x06, 0x0f, 0x40}, 15, false},
{{0x06, 0x0f, 0x40}, 16, false},
{{0x06, 0x0f, 0x40}, 1000, false},
};
for (const auto& test : kBitTests) {
CBS cbs;
CBS_init(&cbs, test.in.data(), test.in.size());
if (CBS_asn1_bitstring_has_bit(&cbs, test.bit) !=
static_cast<int>(test.bit_set)) {
return false;
}
}
return true;
}
int main() {
CRYPTO_library_init();
if (!TestSkip() ||
@@ -911,16 +992,11 @@ static int Main() {
!TestGetOptionalASN1Bool() ||
!TestZero() ||
!TestCBBReserve() ||
!TestStickyError()) {
!TestStickyError() ||
!TestBitString()) {
return 1;
}
printf("PASS\n");
return 0;
}
} // namespace bssl
int main() {
return bssl::Main();
}
+9 -7
View File
@@ -19,9 +19,11 @@
#include <openssl/mem.h>
#include "../internal.h"
void CBB_zero(CBB *cbb) {
memset(cbb, 0, sizeof(CBB));
OPENSSL_memset(cbb, 0, sizeof(CBB));
}
static int cbb_init(CBB *cbb, uint8_t *buf, size_t cap) {
@@ -252,8 +254,8 @@ int CBB_flush(CBB *cbb) {
if (!cbb_buffer_add(cbb->base, NULL, extra_bytes)) {
goto err;
}
memmove(cbb->base->buf + child_start + extra_bytes,
cbb->base->buf + child_start, len);
OPENSSL_memmove(cbb->base->buf + child_start + extra_bytes,
cbb->base->buf + child_start, len);
}
cbb->base->buf[cbb->child->offset++] = initial_length_byte;
cbb->child->pending_len_len = len_len - 1;
@@ -303,8 +305,8 @@ static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents,
return 0;
}
memset(prefix_bytes, 0, len_len);
memset(out_contents, 0, sizeof(CBB));
OPENSSL_memset(prefix_bytes, 0, len_len);
OPENSSL_memset(out_contents, 0, sizeof(CBB));
out_contents->base = cbb->base;
cbb->child = out_contents;
cbb->child->offset = offset;
@@ -346,7 +348,7 @@ int CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned tag) {
return 0;
}
memset(out_contents, 0, sizeof(CBB));
OPENSSL_memset(out_contents, 0, sizeof(CBB));
out_contents->base = cbb->base;
cbb->child = out_contents;
cbb->child->offset = offset;
@@ -363,7 +365,7 @@ int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len) {
!cbb_buffer_add(cbb->base, &dest, len)) {
return 0;
}
memcpy(dest, data, len);
OPENSSL_memcpy(dest, data, len);
return 1;
}
+40 -2
View File
@@ -20,6 +20,7 @@
#include <string.h>
#include "internal.h"
#include "../internal.h"
void CBS_init(CBS *cbs, const uint8_t *data, size_t len) {
@@ -76,7 +77,7 @@ int CBS_strdup(const CBS *cbs, char **out_ptr) {
}
int CBS_contains_zero_byte(const CBS *cbs) {
return memchr(cbs->data, 0, cbs->len) != NULL;
return OPENSSL_memchr(cbs->data, 0, cbs->len) != NULL;
}
int CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len) {
@@ -150,7 +151,7 @@ int CBS_copy_bytes(CBS *cbs, uint8_t *out, size_t len) {
if (!cbs_get(cbs, &v, len)) {
return 0;
}
memcpy(out, v, len);
OPENSSL_memcpy(out, v, len);
return 1;
}
@@ -451,3 +452,40 @@ int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag,
}
return 1;
}
int CBS_is_valid_asn1_bitstring(const CBS *cbs) {
CBS in = *cbs;
uint8_t num_unused_bits;
if (!CBS_get_u8(&in, &num_unused_bits) ||
num_unused_bits > 7) {
return 0;
}
if (num_unused_bits == 0) {
return 1;
}
/* All num_unused_bits bits must exist and be zeros. */
uint8_t last;
if (!CBS_get_last_u8(&in, &last) ||
(last & ((1 << num_unused_bits) - 1)) != 0) {
return 0;
}
return 1;
}
int CBS_asn1_bitstring_has_bit(const CBS *cbs, unsigned bit) {
if (!CBS_is_valid_asn1_bitstring(cbs)) {
return 0;
}
const unsigned byte_num = (bit >> 3) + 1;
const unsigned bit_num = 7 - (bit & 7);
/* Unused bits are zero, and this function does not distinguish between
* missing and unset bits. Thus it is sufficient to do a byte-level length
* check. */
return byte_num < CBS_len(cbs) &&
(CBS_data(cbs)[byte_num] & (1 << bit_num)) != 0;
}
+1 -11
View File
@@ -42,17 +42,7 @@ add_library(
${CHACHA_ARCH_SOURCES}
)
add_executable(
chacha_test
chacha_test.cc
$<TARGET_OBJECTS:test_support>
)
target_link_libraries(chacha_test crypto)
add_dependencies(all_tests chacha_test)
perlasm(chacha-armv4.${ASM_EXT} asm/chacha-armv4.pl)
perlasm(chacha-armv8.${ASM_EXT} asm/chacha-armv8.pl)
perlasm(chacha-x86.${ASM_EXT} asm/chacha-x86.pl)
perlasm(chacha-x86_64.${ASM_EXT} asm/chacha-x86_64.pl)
perlasm(chacha-x86_64.${ASM_EXT} asm/chacha-x86_64.pl)
+3 -3
View File
@@ -8,7 +8,7 @@
# ====================================================================
#
# December 2014
#
#
# ChaCha20 for ARMv4.
#
# Performance in cycles per byte out of large buffer.
@@ -713,7 +713,7 @@ ChaCha20_neon:
vadd.i32 $d2,$d1,$t0 @ counter+2
str @t[3], [sp,#4*(16+15)]
mov @t[3],#10
add @x[12],@x[12],#3 @ counter+3
add @x[12],@x[12],#3 @ counter+3
b .Loop_neon
.align 4
@@ -1127,7 +1127,7 @@ $code.=<<___;
ldrb @t[1],[r12],#1 @ read input
subs @t[3],@t[3],#1
eor @t[0],@t[0],@t[1]
strb @t[0],[r14],#1 @ store ouput
strb @t[0],[r14],#1 @ store output
bne .Loop_tail_neon
.Ldone_neon:
+2 -2
View File
@@ -8,7 +8,7 @@
# ====================================================================
#
# June 2015
#
#
# ChaCha20 for ARMv8.
#
# Performance in cycles per byte out of large buffer.
@@ -193,7 +193,7 @@ ChaCha20_ctr32:
mov $ctr,#10
subs $len,$len,#64
.Loop:
sub $ctr,$ctr,#1
sub $ctr,$ctr,#1
___
foreach (&ROUND(0, 4, 8,12)) { eval; }
foreach (&ROUND(0, 5,10,15)) { eval; }
+11 -4
View File
@@ -21,7 +21,9 @@
# Westmere 9.50/+45% 3.35
# Sandy Bridge 10.5/+47% 3.20
# Haswell 8.15/+50% 2.83
# Skylake 7.53/+22% 2.75
# Silvermont 17.4/+36% 8.35
# Goldmont 13.4/+40% 4.36
# Sledgehammer 10.2/+54%
# Bulldozer 13.4/+50% 4.38(*)
#
@@ -38,10 +40,8 @@ open STDOUT,">$output";
&asm_init($ARGV[0],"chacha-x86.pl",$ARGV[$#ARGV] eq "386");
$xmm=$ymm=0;
for (@ARGV) { $xmm=1 if (/-DOPENSSL_IA32_SSE2/); }
$ymm=$xmm;
$xmm=$ymm=1;
$gasver=999; # enable everything
$a="eax";
($b,$b_)=("ebx","ebp");
@@ -438,6 +438,12 @@ my ($ap,$bp,$cp,$dp)=map(($_&~3)+(($_-1)&3),($ai,$bi,$ci,$di)); # previous
&label("pic_point"),"eax"));
&movdqu ("xmm3",&QWP(0,"ebx")); # counter and nonce
if (defined($gasver) && $gasver>=2.17) { # even though we encode
# pshufb manually, we
# handle only register
# operands, while this
# segment uses memory
# operand...
&cmp ($len,64*4);
&jb (&label("1x"));
@@ -619,6 +625,7 @@ my ($ap,$bp,$cp,$dp)=map(($_&~3)+(($_-1)&3),($ai,$bi,$ci,$di)); # previous
&paddd ("xmm2",&QWP(16*6,"eax")); # +four
&pand ("xmm3",&QWP(16*7,"eax"));
&por ("xmm3","xmm2"); # counter value
}
{
my ($a,$b,$c,$d,$t,$t1,$rot16,$rot24)=map("xmm$_",(0..7));
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -96,7 +96,7 @@ static void chacha_core(uint8_t output[64], const uint32_t input[16]) {
uint32_t x[16];
int i;
memcpy(x, input, sizeof(uint32_t) * 16);
OPENSSL_memcpy(x, input, sizeof(uint32_t) * 16);
for (i = 20; i > 0; i -= 2) {
QUARTERROUND(0, 4, 8, 12)
QUARTERROUND(1, 5, 9, 13)
+16 -28
View File
@@ -18,9 +18,14 @@
#include <memory>
#include <gtest/gtest.h>
#include <openssl/crypto.h>
#include <openssl/chacha.h>
#include "../internal.h"
#include "../test/test_util.h"
static const uint8_t kKey[32] = {
0x98, 0xbe, 0xf1, 0x46, 0x9b, 0xe7, 0x26, 0x98, 0x37, 0xa4, 0x5b,
@@ -214,35 +219,18 @@ static const uint8_t kOutput[] = {
static_assert(sizeof(kInput) == sizeof(kOutput),
"Input and output lengths don't match.");
static bool TestChaCha20(size_t len) {
std::unique_ptr<uint8_t[]> buf(new uint8_t[len]);
CRYPTO_chacha_20(buf.get(), kInput, len, kKey, kNonce, kCounter);
if (memcmp(buf.get(), kOutput, len) != 0) {
fprintf(stderr, "Mismatch at length %zu.\n", len);
return false;
}
// Test in-place.
memcpy(buf.get(), kInput, len);
CRYPTO_chacha_20(buf.get(), buf.get(), len, kKey, kNonce, kCounter);
if (memcmp(buf.get(), kOutput, len) != 0) {
fprintf(stderr, "Mismatch at length %zu, in-place.\n", len);
return false;
}
return true;
}
int main(int argc, char **argv) {
CRYPTO_library_init();
TEST(ChaChaTest, TestVector) {
// Run the test with the test vector at all lengths.
for (size_t len = 0; len <= sizeof(kInput); len++) {
if (!TestChaCha20(len)) {
return 1;
}
}
SCOPED_TRACE(len);
printf("PASS\n");
return 0;
std::unique_ptr<uint8_t[]> buf(new uint8_t[len]);
CRYPTO_chacha_20(buf.get(), kInput, len, kKey, kNonce, kCounter);
EXPECT_EQ(Bytes(kOutput, len), Bytes(buf.get(), len));
// Test the in-place version.
OPENSSL_memcpy(buf.get(), kInput, len);
CRYPTO_chacha_20(buf.get(), buf.get(), len, kKey, kNonce, kCounter);
EXPECT_EQ(Bytes(kOutput, len), Bytes(buf.get(), len));
}
}
+12
View File
@@ -1,5 +1,13 @@
include_directories(../../include)
if (${ARCH} STREQUAL "x86_64")
set(
CIPHER_ARCH_SOURCES
chacha20_poly1305_x86_64.${ASM_EXT}
)
endif()
add_library(
cipher
@@ -19,6 +27,8 @@ add_library(
tls_cbc.c
e_tls.c
e_ssl3.c
${CIPHER_ARCH_SOURCES}
)
add_executable(
@@ -35,6 +45,8 @@ add_executable(
$<TARGET_OBJECTS:test_support>
)
perlasm(chacha20_poly1305_x86_64.${ASM_EXT} asm/chacha20_poly1305_x86_64.pl)
target_link_libraries(cipher_test crypto)
target_link_libraries(aead_test crypto)
add_dependencies(all_tests cipher_test aead_test)
+3 -3
View File
@@ -32,7 +32,7 @@ size_t EVP_AEAD_max_overhead(const EVP_AEAD *aead) { return aead->overhead; }
size_t EVP_AEAD_max_tag_len(const EVP_AEAD *aead) { return aead->max_tag_len; }
void EVP_AEAD_CTX_zero(EVP_AEAD_CTX *ctx) {
memset(ctx, 0, sizeof(EVP_AEAD_CTX));
OPENSSL_memset(ctx, 0, sizeof(EVP_AEAD_CTX));
}
int EVP_AEAD_CTX_init(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead,
@@ -116,7 +116,7 @@ int EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
error:
/* In the event of an error, clear the output buffer so that a caller
* that doesn't check the return value doesn't send raw data. */
memset(out, 0, max_out_len);
OPENSSL_memset(out, 0, max_out_len);
*out_len = 0;
return 0;
}
@@ -139,7 +139,7 @@ error:
/* In the event of an error, clear the output buffer so that a caller
* that doesn't check the return value doesn't try and process bad
* data. */
memset(out, 0, max_out_len);
OPENSSL_memset(out, 0, max_out_len);
*out_len = 0;
return 0;
}
+133 -45
View File
@@ -12,6 +12,7 @@
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <assert.h>
#include <stdint.h>
#include <string.h>
@@ -21,9 +22,18 @@
#include <openssl/crypto.h>
#include <openssl/err.h>
#include "../internal.h"
#include "../test/file_test.h"
namespace bssl {
#if defined(OPENSSL_SMALL)
const EVP_AEAD* EVP_aead_aes_128_gcm_siv(void) {
return nullptr;
}
const EVP_AEAD* EVP_aead_aes_256_gcm_siv(void) {
return nullptr;
}
#endif
// This program tests an AEAD against a series of test vectors from a file,
// using the FileTest format. As an example, here's a valid test case:
@@ -48,7 +58,7 @@ static bool TestAEAD(FileTest *t, void *arg) {
return false;
}
ScopedEVP_AEAD_CTX ctx;
bssl::ScopedEVP_AEAD_CTX ctx;
if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead, key.data(), key.size(),
tag.size(), evp_aead_seal)) {
t->PrintLine("Failed to init AEAD.");
@@ -78,8 +88,8 @@ static bool TestAEAD(FileTest *t, void *arg) {
}
} else {
out.resize(ct.size() + tag.size());
memcpy(out.data(), ct.data(), ct.size());
memcpy(out.data() + ct.size(), tag.data(), tag.size());
OPENSSL_memcpy(out.data(), ct.data(), ct.size());
OPENSSL_memcpy(out.data() + ct.size(), tag.data(), tag.size());
}
// The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
@@ -159,16 +169,12 @@ static bool TestAEAD(FileTest *t, void *arg) {
}
static int TestCleanupAfterInitFailure(const EVP_AEAD *aead) {
EVP_AEAD_CTX ctx;
uint8_t key[128];
memset(key, 0, sizeof(key));
uint8_t key[EVP_AEAD_MAX_KEY_LENGTH];
OPENSSL_memset(key, 0, sizeof(key));
const size_t key_len = EVP_AEAD_key_length(aead);
if (key_len > sizeof(key)) {
fprintf(stderr, "Key length of AEAD too long.\n");
return 0;
}
assert(sizeof(key) >= key_len);
EVP_AEAD_CTX ctx;
if (EVP_AEAD_CTX_init(&ctx, aead, key, key_len,
9999 /* a silly tag length to trigger an error */,
NULL /* ENGINE */) != 0) {
@@ -192,13 +198,87 @@ static int TestCleanupAfterInitFailure(const EVP_AEAD *aead) {
return 1;
}
static int TestTruncatedTags(const EVP_AEAD *aead) {
uint8_t key[EVP_AEAD_MAX_KEY_LENGTH];
OPENSSL_memset(key, 0, sizeof(key));
const size_t key_len = EVP_AEAD_key_length(aead);
assert(sizeof(key) >= key_len);
uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
OPENSSL_memset(nonce, 0, sizeof(nonce));
const size_t nonce_len = EVP_AEAD_nonce_length(aead);
assert(sizeof(nonce) >= nonce_len);
bssl::ScopedEVP_AEAD_CTX ctx;
if (!EVP_AEAD_CTX_init(ctx.get(), aead, key, key_len, 1 /* one byte tag */,
NULL /* ENGINE */)) {
fprintf(stderr, "Couldn't initialise AEAD with truncated tag.\n");
return 1;
}
const uint8_t plaintext[1] = {'A'};
uint8_t ciphertext[128];
size_t ciphertext_len;
constexpr uint8_t kSentinel = 42;
OPENSSL_memset(ciphertext, kSentinel, sizeof(ciphertext));
if (!EVP_AEAD_CTX_seal(ctx.get(), ciphertext, &ciphertext_len,
sizeof(ciphertext), nonce, nonce_len, plaintext,
sizeof(plaintext), nullptr /* ad */, 0)) {
fprintf(stderr, "Sealing with truncated tag didn't work.\n");
return 0;
}
for (size_t i = ciphertext_len; i < sizeof(ciphertext); i++) {
// Sealing must not write past where it said it did.
if (ciphertext[i] != kSentinel) {
fprintf(stderr, "Sealing wrote off the end of the buffer.\n");
return 0;
}
}
const size_t overhead_used = ciphertext_len - sizeof(plaintext);
if (overhead_used != 1) {
fprintf(stderr, "AEAD is probably ignoring request to truncate tags.\n");
return 0;
}
uint8_t plaintext2[sizeof(plaintext) + 16];
OPENSSL_memset(plaintext2, kSentinel, sizeof(plaintext2));
size_t plaintext2_len;
if (!EVP_AEAD_CTX_open(ctx.get(), plaintext2, &plaintext2_len,
sizeof(plaintext2), nonce, nonce_len, ciphertext,
ciphertext_len, nullptr /* ad */, 0)) {
fprintf(stderr, "Opening with truncated tag didn't work.\n");
return 0;
}
for (size_t i = plaintext2_len; i < sizeof(plaintext2); i++) {
// Likewise, opening should also stay within bounds.
if (plaintext2[i] != kSentinel) {
fprintf(stderr, "Opening wrote off the end of the buffer.\n");
return 0;
}
}
if (plaintext2_len != sizeof(plaintext) ||
OPENSSL_memcmp(plaintext2, plaintext, sizeof(plaintext)) != 0) {
fprintf(stderr, "Opening with truncated tag gave wrong result.\n");
return 0;
}
return 1;
}
static bool TestWithAliasedBuffers(const EVP_AEAD *aead) {
const size_t key_len = EVP_AEAD_key_length(aead);
const size_t nonce_len = EVP_AEAD_nonce_length(aead);
const size_t max_overhead = EVP_AEAD_max_overhead(aead);
std::vector<uint8_t> key(key_len, 'a');
ScopedEVP_AEAD_CTX ctx;
bssl::ScopedEVP_AEAD_CTX ctx;
if (!EVP_AEAD_CTX_init(ctx.get(), aead, key.data(), key_len,
EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr)) {
return false;
@@ -231,7 +311,7 @@ static bool TestWithAliasedBuffers(const EVP_AEAD *aead) {
uint8_t *out1 = buffer.data();
uint8_t *out2 = buffer.data() + 2;
memcpy(in, kPlaintext, sizeof(kPlaintext));
OPENSSL_memcpy(in, kPlaintext, sizeof(kPlaintext));
size_t out_len;
if (EVP_AEAD_CTX_seal(ctx.get(), out1, &out_len,
sizeof(kPlaintext) + max_overhead, nonce.data(),
@@ -244,7 +324,7 @@ static bool TestWithAliasedBuffers(const EVP_AEAD *aead) {
}
ERR_clear_error();
memcpy(in, valid_encryption.data(), valid_encryption_len);
OPENSSL_memcpy(in, valid_encryption.data(), valid_encryption_len);
if (EVP_AEAD_CTX_open(ctx.get(), out1, &out_len, valid_encryption_len,
nonce.data(), nonce_len, in, valid_encryption_len,
nullptr, 0) ||
@@ -257,7 +337,7 @@ static bool TestWithAliasedBuffers(const EVP_AEAD *aead) {
ERR_clear_error();
// Test with out == in, which we expect to work.
memcpy(in, kPlaintext, sizeof(kPlaintext));
OPENSSL_memcpy(in, kPlaintext, sizeof(kPlaintext));
if (!EVP_AEAD_CTX_seal(ctx.get(), in, &out_len,
sizeof(kPlaintext) + max_overhead, nonce.data(),
@@ -267,12 +347,12 @@ static bool TestWithAliasedBuffers(const EVP_AEAD *aead) {
}
if (out_len != valid_encryption_len ||
memcmp(in, valid_encryption.data(), out_len) != 0) {
OPENSSL_memcmp(in, valid_encryption.data(), out_len) != 0) {
fprintf(stderr, "EVP_AEAD_CTX_seal produced bad output in-place.\n");
return false;
}
memcpy(in, valid_encryption.data(), valid_encryption_len);
OPENSSL_memcpy(in, valid_encryption.data(), valid_encryption_len);
if (!EVP_AEAD_CTX_open(ctx.get(), in, &out_len, valid_encryption_len,
nonce.data(), nonce_len, in, valid_encryption_len,
nullptr, 0)) {
@@ -281,7 +361,7 @@ static bool TestWithAliasedBuffers(const EVP_AEAD *aead) {
}
if (out_len != sizeof(kPlaintext) ||
memcmp(in, kPlaintext, out_len) != 0) {
OPENSSL_memcmp(in, kPlaintext, out_len) != 0) {
fprintf(stderr, "EVP_AEAD_CTX_open produced bad output in-place.\n");
return false;
}
@@ -297,31 +377,35 @@ struct KnownAEAD {
// handle inputs that are a multiple of eight bytes in length and the
// SSLv3/TLS AEADs have the concept of “direction”.
bool limited_implementation;
// truncated_tags is true if the AEAD supports truncating tags to arbitrary
// lengths.
bool truncated_tags;
};
static const struct KnownAEAD kAEADs[] = {
{ "aes-128-gcm", EVP_aead_aes_128_gcm, false },
{ "aes-256-gcm", EVP_aead_aes_256_gcm, false },
{ "chacha20-poly1305", EVP_aead_chacha20_poly1305, false },
{ "chacha20-poly1305-old", EVP_aead_chacha20_poly1305_old, false },
{ "aes-128-cbc-sha1-tls", EVP_aead_aes_128_cbc_sha1_tls, true },
{ "aes-128-cbc-sha1-tls-implicit-iv", EVP_aead_aes_128_cbc_sha1_tls_implicit_iv, true },
{ "aes-128-cbc-sha256-tls", EVP_aead_aes_128_cbc_sha256_tls, true },
{ "aes-256-cbc-sha1-tls", EVP_aead_aes_256_cbc_sha1_tls, true },
{ "aes-256-cbc-sha1-tls-implicit-iv", EVP_aead_aes_256_cbc_sha1_tls_implicit_iv, true },
{ "aes-256-cbc-sha256-tls", EVP_aead_aes_256_cbc_sha256_tls, true },
{ "aes-256-cbc-sha384-tls", EVP_aead_aes_256_cbc_sha384_tls, true },
{ "des-ede3-cbc-sha1-tls", EVP_aead_des_ede3_cbc_sha1_tls, true },
{ "des-ede3-cbc-sha1-tls-implicit-iv", EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv, true },
{ "aes-128-cbc-sha1-ssl3", EVP_aead_aes_128_cbc_sha1_ssl3, true },
{ "aes-256-cbc-sha1-ssl3", EVP_aead_aes_256_cbc_sha1_ssl3, true },
{ "des-ede3-cbc-sha1-ssl3", EVP_aead_des_ede3_cbc_sha1_ssl3, true },
{ "aes-128-ctr-hmac-sha256", EVP_aead_aes_128_ctr_hmac_sha256, false },
{ "aes-256-ctr-hmac-sha256", EVP_aead_aes_256_ctr_hmac_sha256, false },
{ "", NULL, false },
{ "aes-128-gcm", EVP_aead_aes_128_gcm, false, true },
{ "aes-256-gcm", EVP_aead_aes_256_gcm, false, true },
{ "aes-128-gcm-siv", EVP_aead_aes_128_gcm_siv, false, false },
{ "aes-256-gcm-siv", EVP_aead_aes_256_gcm_siv, false, false },
{ "chacha20-poly1305", EVP_aead_chacha20_poly1305, false, true },
{ "aes-128-cbc-sha1-tls", EVP_aead_aes_128_cbc_sha1_tls, true, false },
{ "aes-128-cbc-sha1-tls-implicit-iv", EVP_aead_aes_128_cbc_sha1_tls_implicit_iv, true, false },
{ "aes-128-cbc-sha256-tls", EVP_aead_aes_128_cbc_sha256_tls, true, false },
{ "aes-256-cbc-sha1-tls", EVP_aead_aes_256_cbc_sha1_tls, true, false },
{ "aes-256-cbc-sha1-tls-implicit-iv", EVP_aead_aes_256_cbc_sha1_tls_implicit_iv, true, false },
{ "aes-256-cbc-sha256-tls", EVP_aead_aes_256_cbc_sha256_tls, true, false },
{ "aes-256-cbc-sha384-tls", EVP_aead_aes_256_cbc_sha384_tls, true, false },
{ "des-ede3-cbc-sha1-tls", EVP_aead_des_ede3_cbc_sha1_tls, true, false },
{ "des-ede3-cbc-sha1-tls-implicit-iv", EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv, true, false },
{ "aes-128-cbc-sha1-ssl3", EVP_aead_aes_128_cbc_sha1_ssl3, true, false },
{ "aes-256-cbc-sha1-ssl3", EVP_aead_aes_256_cbc_sha1_ssl3, true, false },
{ "des-ede3-cbc-sha1-ssl3", EVP_aead_des_ede3_cbc_sha1_ssl3, true, false },
{ "aes-128-ctr-hmac-sha256", EVP_aead_aes_128_ctr_hmac_sha256, false, true },
{ "aes-256-ctr-hmac-sha256", EVP_aead_aes_256_ctr_hmac_sha256, false, true },
{ "", NULL, false, false },
};
static int Main(int argc, char **argv) {
int main(int argc, char **argv) {
CRYPTO_library_init();
if (argc != 3) {
@@ -342,11 +426,21 @@ static int Main(int argc, char **argv) {
}
const EVP_AEAD *const aead = known_aead->func();
if (aead == NULL) {
// AEAD is not compiled in this configuration.
printf("PASS\n");
return 0;
}
if (!TestCleanupAfterInitFailure(aead)) {
return 1;
}
if (known_aead->truncated_tags && !TestTruncatedTags(aead)) {
fprintf(stderr, "Truncated tags test failed for %s.\n", known_aead->name);
return 1;
}
if (!known_aead->limited_implementation && !TestWithAliasedBuffers(aead)) {
fprintf(stderr, "Aliased buffers test failed for %s.\n", known_aead->name);
return 1;
@@ -354,9 +448,3 @@ static int Main(int argc, char **argv) {
return FileTestMain(TestAEAD, const_cast<EVP_AEAD*>(aead), argv[2]);
}
} // namespace bssl
int main(int argc, char **argv) {
return bssl::Main(argc, argv);
}
File diff suppressed because it is too large Load Diff
+18 -13
View File
@@ -64,6 +64,7 @@
#include <openssl/nid.h>
#include "internal.h"
#include "../internal.h"
const EVP_CIPHER *EVP_get_cipherbynid(int nid) {
@@ -88,7 +89,7 @@ const EVP_CIPHER *EVP_get_cipherbynid(int nid) {
}
void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) {
memset(ctx, 0, sizeof(EVP_CIPHER_CTX));
OPENSSL_memset(ctx, 0, sizeof(EVP_CIPHER_CTX));
}
EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void) {
@@ -108,7 +109,7 @@ int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c) {
}
OPENSSL_free(c->cipher_data);
memset(c, 0, sizeof(EVP_CIPHER_CTX));
OPENSSL_memset(c, 0, sizeof(EVP_CIPHER_CTX));
return 1;
}
@@ -126,19 +127,23 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) {
}
EVP_CIPHER_CTX_cleanup(out);
memcpy(out, in, sizeof(EVP_CIPHER_CTX));
OPENSSL_memcpy(out, in, sizeof(EVP_CIPHER_CTX));
if (in->cipher_data && in->cipher->ctx_size) {
out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size);
if (!out->cipher_data) {
out->cipher = NULL;
OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
return 0;
}
memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size);
OPENSSL_memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size);
}
if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY) {
return in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out);
if (!in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out)) {
out->cipher = NULL;
return 0;
}
}
return 1;
@@ -210,9 +215,9 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
case EVP_CIPH_CBC_MODE:
assert(EVP_CIPHER_CTX_iv_length(ctx) <= sizeof(ctx->iv));
if (iv) {
memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
OPENSSL_memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
}
memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
OPENSSL_memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
break;
case EVP_CIPH_CTR_MODE:
@@ -220,7 +225,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
ctx->num = 0;
/* Don't reuse IV for CTR mode */
if (iv) {
memcpy(ctx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx));
OPENSSL_memcpy(ctx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx));
}
break;
@@ -285,13 +290,13 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len,
assert(bl <= (int)sizeof(ctx->buf));
if (i != 0) {
if (bl - i > in_len) {
memcpy(&ctx->buf[i], in, in_len);
OPENSSL_memcpy(&ctx->buf[i], in, in_len);
ctx->buf_len += in_len;
*out_len = 0;
return 1;
} else {
j = bl - i;
memcpy(&ctx->buf[i], in, j);
OPENSSL_memcpy(&ctx->buf[i], in, j);
if (!ctx->cipher->cipher(ctx, out, ctx->buf, bl)) {
return 0;
}
@@ -314,7 +319,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len,
}
if (i != 0) {
memcpy(ctx->buf, &in[in_len], i);
OPENSSL_memcpy(ctx->buf, &in[in_len], i);
}
ctx->buf_len = i;
return 1;
@@ -393,7 +398,7 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len,
assert(b <= sizeof(ctx->final));
if (ctx->final_used) {
memcpy(out, ctx->final, b);
OPENSSL_memcpy(out, ctx->final, b);
out += b;
fix_len = 1;
} else {
@@ -409,7 +414,7 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len,
if (b > 1 && !ctx->buf_len) {
*out_len -= b;
ctx->final_used = 1;
memcpy(ctx->final, &out[*out_len], b);
OPENSSL_memcpy(ctx->final, &out[*out_len], b);
} else {
ctx->final_used = 0;
}
+2 -9
View File
@@ -63,7 +63,6 @@
#include "../test/file_test.h"
namespace bssl {
static const EVP_CIPHER *GetCipher(const std::string &name) {
if (name == "DES-CBC") {
@@ -127,7 +126,7 @@ static bool TestOperation(FileTest *t,
bool is_aead = EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE;
ScopedEVP_CIPHER_CTX ctx;
bssl::ScopedEVP_CIPHER_CTX ctx;
if (!EVP_CipherInit_ex(ctx.get(), cipher, nullptr, nullptr, nullptr,
encrypt ? 1 : 0)) {
return false;
@@ -284,7 +283,7 @@ static bool TestCipher(FileTest *t, void *arg) {
return true;
}
static int Main(int argc, char **argv) {
int main(int argc, char **argv) {
CRYPTO_library_init();
if (argc != 2) {
@@ -294,9 +293,3 @@ static int Main(int argc, char **argv) {
return FileTestMain(TestCipher, nullptr, argv[1]);
}
} // namespace bssl
int main(int argc, char **argv) {
return bssl::Main(argc, argv);
}
+335 -21
View File
@@ -479,7 +479,7 @@ static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
if (gctx->key_set) {
CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, iv, gctx->ivlen);
} else {
memcpy(gctx->iv, iv, gctx->ivlen);
OPENSSL_memcpy(gctx->iv, iv, gctx->ivlen);
}
gctx->iv_set = 1;
gctx->iv_gen = 0;
@@ -545,7 +545,7 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) {
if (arg <= 0 || arg > 16 || c->encrypt) {
return 0;
}
memcpy(c->buf, ptr, arg);
OPENSSL_memcpy(c->buf, ptr, arg);
gctx->taglen = arg;
return 1;
@@ -553,13 +553,13 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) {
if (arg <= 0 || arg > 16 || !c->encrypt || gctx->taglen < 0) {
return 0;
}
memcpy(ptr, c->buf, arg);
OPENSSL_memcpy(ptr, c->buf, arg);
return 1;
case EVP_CTRL_GCM_SET_IV_FIXED:
/* Special case: -1 length restores whole IV */
if (arg == -1) {
memcpy(gctx->iv, ptr, gctx->ivlen);
OPENSSL_memcpy(gctx->iv, ptr, gctx->ivlen);
gctx->iv_gen = 1;
return 1;
}
@@ -569,7 +569,7 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) {
return 0;
}
if (arg) {
memcpy(gctx->iv, ptr, arg);
OPENSSL_memcpy(gctx->iv, ptr, arg);
}
if (c->encrypt && !RAND_bytes(gctx->iv + arg, gctx->ivlen - arg)) {
return 0;
@@ -585,7 +585,7 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) {
if (arg <= 0 || arg > gctx->ivlen) {
arg = gctx->ivlen;
}
memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg);
OPENSSL_memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg);
/* 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. */
@@ -597,7 +597,7 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) {
if (gctx->iv_gen == 0 || gctx->key_set == 0 || c->encrypt) {
return 0;
}
memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg);
OPENSSL_memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg);
CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, gctx->iv, gctx->ivlen);
gctx->iv_set = 1;
return 1;
@@ -612,7 +612,7 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) {
if (!gctx_out->iv) {
return 0;
}
memcpy(gctx_out->iv, gctx->iv, gctx->ivlen);
OPENSSL_memcpy(gctx_out->iv, gctx->iv, gctx->ivlen);
}
return 1;
}
@@ -860,7 +860,7 @@ static int aesni_gcm_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
if (gctx->key_set) {
CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, iv, gctx->ivlen);
} else {
memcpy(gctx->iv, iv, gctx->ivlen);
OPENSSL_memcpy(gctx->iv, iv, gctx->ivlen);
}
gctx->iv_set = 1;
gctx->iv_gen = 0;
@@ -1073,7 +1073,7 @@ static int aead_aes_gcm_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
const AES_KEY *key = &gcm_ctx->ks.ks;
memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm));
OPENSSL_memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm));
CRYPTO_gcm128_setiv(&gcm, key, nonce, nonce_len);
if (ad_len > 0 && !CRYPTO_gcm128_aad(&gcm, ad, ad_len)) {
@@ -1120,7 +1120,7 @@ static int aead_aes_gcm_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
const AES_KEY *key = &gcm_ctx->ks.ks;
memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm));
OPENSSL_memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm));
CRYPTO_gcm128_setiv(&gcm, key, nonce, nonce_len);
if (!CRYPTO_gcm128_aad(&gcm, ad, ad_len)) {
@@ -1198,8 +1198,8 @@ static void hmac_init(SHA256_CTX *out_inner, SHA256_CTX *out_outer,
const uint8_t hmac_key[32]) {
static const size_t hmac_key_len = 32;
uint8_t block[SHA256_CBLOCK];
memcpy(block, hmac_key, hmac_key_len);
memset(block + hmac_key_len, 0x36, sizeof(block) - hmac_key_len);
OPENSSL_memcpy(block, hmac_key, hmac_key_len);
OPENSSL_memset(block + hmac_key_len, 0x36, sizeof(block) - hmac_key_len);
unsigned i;
for (i = 0; i < hmac_key_len; i++) {
@@ -1209,7 +1209,7 @@ static void hmac_init(SHA256_CTX *out_inner, SHA256_CTX *out_outer,
SHA256_Init(out_inner);
SHA256_Update(out_inner, block, sizeof(block));
memset(block + hmac_key_len, 0x5c, sizeof(block) - hmac_key_len);
OPENSSL_memset(block + hmac_key_len, 0x5c, sizeof(block) - hmac_key_len);
for (i = 0; i < hmac_key_len; i++) {
block[i] ^= (0x36 ^ 0x5c);
}
@@ -1284,7 +1284,7 @@ static void hmac_calculate(uint8_t out[SHA256_DIGEST_LENGTH],
const uint8_t *nonce, const uint8_t *ciphertext,
size_t ciphertext_len) {
SHA256_CTX sha256;
memcpy(&sha256, inner_init_state, sizeof(sha256));
OPENSSL_memcpy(&sha256, inner_init_state, sizeof(sha256));
hmac_update_uint64(&sha256, ad_len);
hmac_update_uint64(&sha256, ciphertext_len);
SHA256_Update(&sha256, nonce, EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN);
@@ -1297,7 +1297,7 @@ static void hmac_calculate(uint8_t out[SHA256_DIGEST_LENGTH],
SHA256_CBLOCK)) %
SHA256_CBLOCK;
uint8_t padding[SHA256_CBLOCK];
memset(padding, 0, num_padding);
OPENSSL_memset(padding, 0, num_padding);
SHA256_Update(&sha256, padding, num_padding);
SHA256_Update(&sha256, ciphertext, ciphertext_len);
@@ -1305,7 +1305,7 @@ static void hmac_calculate(uint8_t out[SHA256_DIGEST_LENGTH],
uint8_t inner_digest[SHA256_DIGEST_LENGTH];
SHA256_Final(inner_digest, &sha256);
memcpy(&sha256, outer_init_state, sizeof(sha256));
OPENSSL_memcpy(&sha256, outer_init_state, sizeof(sha256));
SHA256_Update(&sha256, inner_digest, sizeof(inner_digest));
SHA256_Final(out, &sha256);
}
@@ -1317,11 +1317,11 @@ static void aead_aes_ctr_hmac_sha256_crypt(
* bytes is pointless. However, |CRYPTO_ctr128_encrypt| requires it. */
uint8_t partial_block_buffer[AES_BLOCK_SIZE];
unsigned partial_block_offset = 0;
memset(partial_block_buffer, 0, sizeof(partial_block_buffer));
OPENSSL_memset(partial_block_buffer, 0, sizeof(partial_block_buffer));
uint8_t counter[AES_BLOCK_SIZE];
memcpy(counter, nonce, EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN);
memset(counter + EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN, 0, 4);
OPENSSL_memcpy(counter, nonce, EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN);
OPENSSL_memset(counter + EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN, 0, 4);
if (aes_ctx->ctr) {
CRYPTO_ctr128_encrypt_ctr32(in, out, len, &aes_ctx->ks.ks, counter,
@@ -1364,7 +1364,7 @@ static int aead_aes_ctr_hmac_sha256_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
uint8_t hmac_result[SHA256_DIGEST_LENGTH];
hmac_calculate(hmac_result, &aes_ctx->inner_init_state,
&aes_ctx->outer_init_state, ad, ad_len, nonce, out, in_len);
memcpy(out + in_len, hmac_result, aes_ctx->tag_len);
OPENSSL_memcpy(out + in_len, hmac_result, aes_ctx->tag_len);
*out_len = in_len + aes_ctx->tag_len;
return 1;
@@ -1446,6 +1446,320 @@ const EVP_AEAD *EVP_aead_aes_256_ctr_hmac_sha256(void) {
return &aead_aes_256_ctr_hmac_sha256;
}
#if !defined(OPENSSL_SMALL)
#define EVP_AEAD_AES_GCM_SIV_NONCE_LEN 12
#define EVP_AEAD_AES_GCM_SIV_TAG_LEN 16
struct aead_aes_gcm_siv_ctx {
union {
double align;
AES_KEY ks;
} ks;
block128_f kgk_block;
unsigned is_256:1;
};
static int aead_aes_gcm_siv_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
size_t key_len, size_t tag_len) {
const size_t key_bits = key_len * 8;
if (key_bits != 128 && key_bits != 256) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
return 0; /* EVP_AEAD_CTX_init should catch this. */
}
if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) {
tag_len = EVP_AEAD_AES_GCM_SIV_TAG_LEN;
}
if (tag_len != EVP_AEAD_AES_GCM_SIV_TAG_LEN) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE);
return 0;
}
struct aead_aes_gcm_siv_ctx *gcm_siv_ctx =
OPENSSL_malloc(sizeof(struct aead_aes_gcm_siv_ctx));
if (gcm_siv_ctx == NULL) {
return 0;
}
OPENSSL_memset(gcm_siv_ctx, 0, sizeof(struct aead_aes_gcm_siv_ctx));
if (aesni_capable()) {
aesni_set_encrypt_key(key, key_len * 8, &gcm_siv_ctx->ks.ks);
gcm_siv_ctx->kgk_block = (block128_f)aesni_encrypt;
} else if (hwaes_capable()) {
aes_hw_set_encrypt_key(key, key_len * 8, &gcm_siv_ctx->ks.ks);
gcm_siv_ctx->kgk_block = (block128_f)aes_hw_encrypt;
} else if (vpaes_capable()) {
vpaes_set_encrypt_key(key, key_len * 8, &gcm_siv_ctx->ks.ks);
gcm_siv_ctx->kgk_block = (block128_f)vpaes_encrypt;
} else {
AES_set_encrypt_key(key, key_len * 8, &gcm_siv_ctx->ks.ks);
gcm_siv_ctx->kgk_block = (block128_f)AES_encrypt;
}
gcm_siv_ctx->is_256 = (key_len == 32);
ctx->aead_state = gcm_siv_ctx;
return 1;
}
static void aead_aes_gcm_siv_cleanup(EVP_AEAD_CTX *ctx) {
struct aead_aes_gcm_siv_ctx *gcm_siv_ctx = ctx->aead_state;
OPENSSL_cleanse(gcm_siv_ctx, sizeof(struct aead_aes_gcm_siv_ctx));
OPENSSL_free(gcm_siv_ctx);
}
/* gcm_siv_crypt encrypts (or decrypts—it's the same thing) |in_len| bytes from
* |in| to |out|, using the block function |enc_block| with |key| in counter
* mode, starting at |initial_counter|. This differs from the traditional
* counter mode code in that the counter is handled little-endian, only the
* first four bytes are used and the GCM-SIV tweak to the final byte is
* applied. The |in| and |out| pointers may be equal but otherwise must not
* alias. */
static void gcm_siv_crypt(uint8_t *out, const uint8_t *in, size_t in_len,
const uint8_t initial_counter[AES_BLOCK_SIZE],
block128_f enc_block, const AES_KEY *key) {
union {
uint32_t w[4];
uint8_t c[16];
} counter;
OPENSSL_memcpy(counter.c, initial_counter, AES_BLOCK_SIZE);
counter.c[15] |= 0x80;
for (size_t done = 0; done < in_len;) {
uint8_t keystream[AES_BLOCK_SIZE];
enc_block(counter.c, keystream, key);
counter.w[0]++;
size_t todo = AES_BLOCK_SIZE;
if (in_len - done < todo) {
todo = in_len - done;
}
for (size_t i = 0; i < todo; i++) {
out[done + i] = keystream[i] ^ in[done + i];
}
done += todo;
}
}
/* gcm_siv_polyval evaluates POLYVAL at |auth_key| on the given plaintext and
* AD. The result is written to |out_tag|. */
static void gcm_siv_polyval(
uint8_t out_tag[16], const uint8_t *in, size_t in_len, const uint8_t *ad,
size_t ad_len, const uint8_t auth_key[16],
const uint8_t nonce[EVP_AEAD_AES_GCM_SIV_NONCE_LEN]) {
struct polyval_ctx polyval_ctx;
CRYPTO_POLYVAL_init(&polyval_ctx, auth_key);
CRYPTO_POLYVAL_update_blocks(&polyval_ctx, ad, ad_len & ~15);
uint8_t scratch[16];
if (ad_len & 15) {
OPENSSL_memset(scratch, 0, sizeof(scratch));
OPENSSL_memcpy(scratch, &ad[ad_len & ~15], ad_len & 15);
CRYPTO_POLYVAL_update_blocks(&polyval_ctx, scratch, sizeof(scratch));
}
CRYPTO_POLYVAL_update_blocks(&polyval_ctx, in, in_len & ~15);
if (in_len & 15) {
OPENSSL_memset(scratch, 0, sizeof(scratch));
OPENSSL_memcpy(scratch, &in[in_len & ~15], in_len & 15);
CRYPTO_POLYVAL_update_blocks(&polyval_ctx, scratch, sizeof(scratch));
}
union {
uint8_t c[16];
struct {
uint64_t ad;
uint64_t in;
} bitlens;
} length_block;
length_block.bitlens.ad = ad_len * 8;
length_block.bitlens.in = in_len * 8;
CRYPTO_POLYVAL_update_blocks(&polyval_ctx, length_block.c,
sizeof(length_block));
CRYPTO_POLYVAL_finish(&polyval_ctx, out_tag);
for (size_t i = 0; i < EVP_AEAD_AES_GCM_SIV_NONCE_LEN; i++) {
out_tag[i] ^= nonce[i];
}
out_tag[15] &= 0x7f;
}
/* gcm_siv_record_keys contains the keys used for a specific GCM-SIV record. */
struct gcm_siv_record_keys {
uint8_t auth_key[16];
union {
double align;
AES_KEY ks;
} enc_key;
block128_f enc_block;
};
/* gcm_siv_keys calculates the keys for a specific GCM-SIV record with the
* given nonce and writes them to |*out_keys|. */
static void gcm_siv_keys(
const struct aead_aes_gcm_siv_ctx *gcm_siv_ctx,
struct gcm_siv_record_keys *out_keys,
const uint8_t nonce[EVP_AEAD_AES_GCM_SIV_NONCE_LEN]) {
const AES_KEY *const key = &gcm_siv_ctx->ks.ks;
uint8_t key_material[(128 /* POLYVAL key */ + 256 /* max AES key */) / 8];
const size_t blocks_needed = gcm_siv_ctx->is_256 ? 6 : 4;
uint8_t counter[AES_BLOCK_SIZE];
OPENSSL_memset(counter, 0, AES_BLOCK_SIZE - EVP_AEAD_AES_GCM_SIV_NONCE_LEN);
OPENSSL_memcpy(counter + AES_BLOCK_SIZE - EVP_AEAD_AES_GCM_SIV_NONCE_LEN,
nonce, EVP_AEAD_AES_GCM_SIV_NONCE_LEN);
for (size_t i = 0; i < blocks_needed; i++) {
counter[0] = i;
uint8_t ciphertext[AES_BLOCK_SIZE];
gcm_siv_ctx->kgk_block(counter, ciphertext, key);
OPENSSL_memcpy(&key_material[i * 8], ciphertext, 8);
}
OPENSSL_memcpy(out_keys->auth_key, key_material, 16);
aes_ctr_set_key(&out_keys->enc_key.ks, NULL, &out_keys->enc_block,
key_material + 16, gcm_siv_ctx->is_256 ? 32 : 16);
}
static int aead_aes_gcm_siv_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
size_t *out_len, size_t max_out_len,
const uint8_t *nonce, size_t nonce_len,
const uint8_t *in, size_t in_len,
const uint8_t *ad, size_t ad_len) {
const struct aead_aes_gcm_siv_ctx *gcm_siv_ctx = ctx->aead_state;
const uint64_t in_len_64 = in_len;
const uint64_t ad_len_64 = ad_len;
if (in_len + EVP_AEAD_AES_GCM_SIV_TAG_LEN < in_len ||
in_len_64 > (UINT64_C(1) << 36) ||
ad_len_64 >= (UINT64_C(1) << 61)) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
if (max_out_len < in_len + EVP_AEAD_AES_GCM_SIV_TAG_LEN) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
if (nonce_len != EVP_AEAD_AES_GCM_SIV_NONCE_LEN) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
return 0;
}
struct gcm_siv_record_keys keys;
gcm_siv_keys(gcm_siv_ctx, &keys, nonce);
uint8_t tag[16];
gcm_siv_polyval(tag, in, in_len, ad, ad_len, keys.auth_key, nonce);
keys.enc_block(tag, tag, &keys.enc_key.ks);
gcm_siv_crypt(out, in, in_len, tag, keys.enc_block, &keys.enc_key.ks);
OPENSSL_memcpy(&out[in_len], tag, EVP_AEAD_AES_GCM_SIV_TAG_LEN);
*out_len = in_len + EVP_AEAD_AES_GCM_SIV_TAG_LEN;
return 1;
}
static int aead_aes_gcm_siv_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
size_t *out_len, size_t max_out_len,
const uint8_t *nonce, size_t nonce_len,
const uint8_t *in, size_t in_len,
const uint8_t *ad, size_t ad_len) {
const uint64_t ad_len_64 = ad_len;
if (ad_len_64 >= (UINT64_C(1) << 61)) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
const uint64_t in_len_64 = in_len;
if (in_len < EVP_AEAD_AES_GCM_SIV_TAG_LEN ||
in_len_64 > (UINT64_C(1) << 36) + AES_BLOCK_SIZE) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
if (nonce_len != EVP_AEAD_AES_GCM_SIV_NONCE_LEN) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
return 0;
}
const struct aead_aes_gcm_siv_ctx *gcm_siv_ctx = ctx->aead_state;
const size_t plaintext_len = in_len - EVP_AEAD_AES_GCM_SIV_TAG_LEN;
if (max_out_len < plaintext_len) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
struct gcm_siv_record_keys keys;
gcm_siv_keys(gcm_siv_ctx, &keys, nonce);
gcm_siv_crypt(out, in, plaintext_len, &in[plaintext_len], keys.enc_block,
&keys.enc_key.ks);
uint8_t expected_tag[EVP_AEAD_AES_GCM_SIV_TAG_LEN];
gcm_siv_polyval(expected_tag, out, plaintext_len, ad, ad_len, keys.auth_key,
nonce);
keys.enc_block(expected_tag, expected_tag, &keys.enc_key.ks);
if (CRYPTO_memcmp(expected_tag, &in[plaintext_len], sizeof(expected_tag)) !=
0) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
*out_len = plaintext_len;
return 1;
}
static const EVP_AEAD aead_aes_128_gcm_siv = {
16, /* key length */
EVP_AEAD_AES_GCM_SIV_NONCE_LEN, /* nonce length */
EVP_AEAD_AES_GCM_SIV_TAG_LEN, /* overhead */
EVP_AEAD_AES_GCM_SIV_TAG_LEN, /* max tag length */
aead_aes_gcm_siv_init,
NULL /* init_with_direction */,
aead_aes_gcm_siv_cleanup,
aead_aes_gcm_siv_seal,
aead_aes_gcm_siv_open,
NULL /* get_iv */,
};
static const EVP_AEAD aead_aes_256_gcm_siv = {
32, /* key length */
EVP_AEAD_AES_GCM_SIV_NONCE_LEN, /* nonce length */
EVP_AEAD_AES_GCM_SIV_TAG_LEN, /* overhead */
EVP_AEAD_AES_GCM_SIV_TAG_LEN, /* max tag length */
aead_aes_gcm_siv_init,
NULL /* init_with_direction */,
aead_aes_gcm_siv_cleanup,
aead_aes_gcm_siv_seal,
aead_aes_gcm_siv_open,
NULL /* get_iv */,
};
const EVP_AEAD *EVP_aead_aes_128_gcm_siv(void) {
return &aead_aes_128_gcm_siv;
}
const EVP_AEAD *EVP_aead_aes_256_gcm_siv(void) {
return &aead_aes_256_gcm_siv;
}
#endif /* !OPENSSL_SMALL */
int EVP_has_aes_hardware(void) {
#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
return aesni_capable() && crypto_gcm_clmul_enabled();
+112 -136
View File
@@ -18,6 +18,7 @@
#include <openssl/chacha.h>
#include <openssl/cipher.h>
#include <openssl/cpu.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/poly1305.h>
@@ -33,6 +34,51 @@ struct aead_chacha20_poly1305_ctx {
unsigned char tag_len;
};
#if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM) && \
!defined(OPENSSL_WINDOWS)
static int asm_capable(void) {
const int sse41_capable = (OPENSSL_ia32cap_P[1] & (1 << 19)) != 0;
return sse41_capable;
}
// chacha20_poly1305_open is defined in chacha20_poly1305_x86_64.pl. It
// decrypts |plaintext_len| bytes from |ciphertext| and writes them to
// |out_plaintext|. On entry, |aead_data| must contain the final 48 bytes of
// the initial ChaCha20 block, i.e. the key, followed by four zeros, followed
// by the nonce. On exit, it will contain the calculated tag value, which the
// caller must check.
extern void chacha20_poly1305_open(uint8_t *out_plaintext,
const uint8_t *ciphertext,
size_t plaintext_len, const uint8_t *ad,
size_t ad_len, uint8_t *aead_data);
// chacha20_poly1305_open is defined in chacha20_poly1305_x86_64.pl. It
// encrypts |plaintext_len| bytes from |plaintext| and writes them to
// |out_ciphertext|. On entry, |aead_data| must contain the final 48 bytes of
// the initial ChaCha20 block, i.e. the key, followed by four zeros, followed
// by the nonce. On exit, it will contain the calculated tag value, which the
// caller must append to the ciphertext.
extern void chacha20_poly1305_seal(uint8_t *out_ciphertext,
const uint8_t *plaintext,
size_t plaintext_len, const uint8_t *ad,
size_t ad_len, uint8_t *aead_data);
#else
static int asm_capable(void) {
return 0;
}
static void chacha20_poly1305_open(uint8_t *out_plaintext,
const uint8_t *ciphertext,
size_t plaintext_len, const uint8_t *ad,
size_t ad_len, uint8_t *aead_data) {}
static void chacha20_poly1305_seal(uint8_t *out_ciphertext,
const uint8_t *plaintext,
size_t plaintext_len, const uint8_t *ad,
size_t ad_len, uint8_t *aead_data) {}
#endif
static int aead_chacha20_poly1305_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
size_t key_len, size_t tag_len) {
struct aead_chacha20_poly1305_ctx *c20_ctx;
@@ -55,7 +101,7 @@ static int aead_chacha20_poly1305_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
return 0;
}
memcpy(c20_ctx->key, key, key_len);
OPENSSL_memcpy(c20_ctx->key, key, key_len);
c20_ctx->tag_len = tag_len;
ctx->aead_state = c20_ctx;
@@ -70,9 +116,8 @@ static void aead_chacha20_poly1305_cleanup(EVP_AEAD_CTX *ctx) {
static void poly1305_update_length(poly1305_state *poly1305, size_t data_len) {
uint8_t length_bytes[8];
unsigned i;
for (i = 0; i < sizeof(length_bytes); i++) {
for (unsigned i = 0; i < sizeof(length_bytes); i++) {
length_bytes[i] = data_len;
data_len >>= 8;
}
@@ -80,37 +125,49 @@ static void poly1305_update_length(poly1305_state *poly1305, size_t data_len) {
CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes));
}
typedef void (*aead_poly1305_update)(poly1305_state *ctx, const uint8_t *ad,
size_t ad_len, const uint8_t *ciphertext,
size_t ciphertext_len);
static void poly1305_update_padded_16(poly1305_state *poly1305,
const uint8_t *data, size_t data_len) {
static const uint8_t padding[16] = { 0 }; /* Padding is all zeros. */
/* aead_poly1305 fills |tag| with the authentication tag for the given
* inputs, using |update| to control the order and format that the inputs are
* signed/authenticated. */
static void aead_poly1305(aead_poly1305_update update,
uint8_t tag[POLY1305_TAG_LEN],
const struct aead_chacha20_poly1305_ctx *c20_ctx,
const uint8_t nonce[12], const uint8_t *ad,
size_t ad_len, const uint8_t *ciphertext,
size_t ciphertext_len) {
CRYPTO_poly1305_update(poly1305, data, data_len);
if (data_len % 16 != 0) {
CRYPTO_poly1305_update(poly1305, padding,
sizeof(padding) - (data_len % 16));
}
}
/* calc_tag fills |tag| with the authentication tag for the given inputs. */
static void calc_tag(uint8_t tag[POLY1305_TAG_LEN],
const struct aead_chacha20_poly1305_ctx *c20_ctx,
const uint8_t nonce[12], const uint8_t *ad, size_t ad_len,
const uint8_t *ciphertext, size_t ciphertext_len) {
alignas(16) uint8_t poly1305_key[32];
memset(poly1305_key, 0, sizeof(poly1305_key));
OPENSSL_memset(poly1305_key, 0, sizeof(poly1305_key));
CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key),
c20_ctx->key, nonce, 0);
poly1305_state ctx;
CRYPTO_poly1305_init(&ctx, poly1305_key);
update(&ctx, ad, ad_len, ciphertext, ciphertext_len);
poly1305_update_padded_16(&ctx, ad, ad_len);
poly1305_update_padded_16(&ctx, ciphertext, ciphertext_len);
poly1305_update_length(&ctx, ad_len);
poly1305_update_length(&ctx, ciphertext_len);
CRYPTO_poly1305_finish(&ctx, tag);
}
static int seal_impl(aead_poly1305_update poly1305_update,
const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
size_t max_out_len, const uint8_t nonce[12],
const uint8_t *in, size_t in_len, const uint8_t *ad,
size_t ad_len) {
static int aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
size_t *out_len, size_t max_out_len,
const uint8_t *nonce, size_t nonce_len,
const uint8_t *in, size_t in_len,
const uint8_t *ad, size_t ad_len) {
const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
const uint64_t in_len_64 = in_len;
if (nonce_len != 12) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
return 0;
}
/* |CRYPTO_chacha_20| uses a 32-bit block counter. Therefore we disallow
* individual operations that work on more than 256GB at a time.
* |in_len_64| is needed because, on 32-bit platforms, size_t is only
@@ -132,25 +189,37 @@ static int seal_impl(aead_poly1305_update poly1305_update,
return 0;
}
CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1);
alignas(16) uint8_t tag[48];
alignas(16) uint8_t tag[POLY1305_TAG_LEN];
aead_poly1305(poly1305_update, tag, c20_ctx, nonce, ad, ad_len, out, in_len);
if (asm_capable()) {
OPENSSL_memcpy(tag, c20_ctx->key, 32);
OPENSSL_memset(tag + 32, 0, 4);
OPENSSL_memcpy(tag + 32 + 4, nonce, 12);
chacha20_poly1305_seal(out, in, in_len, ad, ad_len, tag);
} else {
CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1);
calc_tag(tag, c20_ctx, nonce, ad, ad_len, out, in_len);
}
memcpy(out + in_len, tag, c20_ctx->tag_len);
OPENSSL_memcpy(out + in_len, tag, c20_ctx->tag_len);
*out_len = in_len + c20_ctx->tag_len;
return 1;
}
static int open_impl(aead_poly1305_update poly1305_update,
const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
size_t max_out_len, const uint8_t nonce[12],
const uint8_t *in, size_t in_len, const uint8_t *ad,
size_t ad_len) {
static int aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
size_t *out_len, size_t max_out_len,
const uint8_t *nonce, size_t nonce_len,
const uint8_t *in, size_t in_len,
const uint8_t *ad, size_t ad_len) {
const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
size_t plaintext_len;
const uint64_t in_len_64 = in_len;
if (nonce_len != 12) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
return 0;
}
if (in_len < c20_ctx->tag_len) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
@@ -168,64 +237,27 @@ static int open_impl(aead_poly1305_update poly1305_update,
}
plaintext_len = in_len - c20_ctx->tag_len;
alignas(16) uint8_t tag[POLY1305_TAG_LEN];
aead_poly1305(poly1305_update, tag, c20_ctx, nonce, ad, ad_len, in,
plaintext_len);
alignas(16) uint8_t tag[48];
if (asm_capable()) {
OPENSSL_memcpy(tag, c20_ctx->key, 32);
OPENSSL_memset(tag + 32, 0, 4);
OPENSSL_memcpy(tag + 32 + 4, nonce, 12);
chacha20_poly1305_open(out, in, plaintext_len, ad, ad_len, tag);
} else {
calc_tag(tag, c20_ctx, nonce, ad, ad_len, in, plaintext_len);
CRYPTO_chacha_20(out, in, plaintext_len, c20_ctx->key, nonce, 1);
}
if (CRYPTO_memcmp(tag, in + plaintext_len, c20_ctx->tag_len) != 0) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
CRYPTO_chacha_20(out, in, plaintext_len, c20_ctx->key, nonce, 1);
*out_len = plaintext_len;
return 1;
}
static void poly1305_update_padded_16(poly1305_state *poly1305,
const uint8_t *data, size_t data_len) {
static const uint8_t padding[16] = { 0 }; /* Padding is all zeros. */
CRYPTO_poly1305_update(poly1305, data, data_len);
if (data_len % 16 != 0) {
CRYPTO_poly1305_update(poly1305, padding, sizeof(padding) - (data_len % 16));
}
}
static void poly1305_update(poly1305_state *ctx, const uint8_t *ad,
size_t ad_len, const uint8_t *ciphertext,
size_t ciphertext_len) {
poly1305_update_padded_16(ctx, ad, ad_len);
poly1305_update_padded_16(ctx, ciphertext, ciphertext_len);
poly1305_update_length(ctx, ad_len);
poly1305_update_length(ctx, ciphertext_len);
}
static int aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
size_t *out_len, size_t max_out_len,
const uint8_t *nonce, size_t nonce_len,
const uint8_t *in, size_t in_len,
const uint8_t *ad, size_t ad_len) {
if (nonce_len != 12) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
return 0;
}
return seal_impl(poly1305_update, ctx, out, out_len, max_out_len, nonce, in,
in_len, ad, ad_len);
}
static int aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
size_t *out_len, size_t max_out_len,
const uint8_t *nonce, size_t nonce_len,
const uint8_t *in, size_t in_len,
const uint8_t *ad, size_t ad_len) {
if (nonce_len != 12) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
return 0;
}
return open_impl(poly1305_update, ctx, out, out_len, max_out_len, nonce, in,
in_len, ad, ad_len);
}
static const EVP_AEAD aead_chacha20_poly1305 = {
32, /* key len */
12, /* nonce len */
@@ -242,59 +274,3 @@ static const EVP_AEAD aead_chacha20_poly1305 = {
const EVP_AEAD *EVP_aead_chacha20_poly1305(void) {
return &aead_chacha20_poly1305;
}
static void poly1305_update_old(poly1305_state *ctx, const uint8_t *ad,
size_t ad_len, const uint8_t *ciphertext,
size_t ciphertext_len) {
CRYPTO_poly1305_update(ctx, ad, ad_len);
poly1305_update_length(ctx, ad_len);
CRYPTO_poly1305_update(ctx, ciphertext, ciphertext_len);
poly1305_update_length(ctx, ciphertext_len);
}
static int aead_chacha20_poly1305_old_seal(
const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, size_t max_out_len,
const uint8_t *nonce, size_t nonce_len, const uint8_t *in, size_t in_len,
const uint8_t *ad, size_t ad_len) {
if (nonce_len != 8) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
return 0;
}
uint8_t nonce_96[12];
memset(nonce_96, 0, 4);
memcpy(nonce_96 + 4, nonce, 8);
return seal_impl(poly1305_update_old, ctx, out, out_len, max_out_len,
nonce_96, in, in_len, ad, ad_len);
}
static int aead_chacha20_poly1305_old_open(
const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, size_t max_out_len,
const uint8_t *nonce, size_t nonce_len, const uint8_t *in, size_t in_len,
const uint8_t *ad, size_t ad_len) {
if (nonce_len != 8) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
return 0;
}
uint8_t nonce_96[12];
memset(nonce_96, 0, 4);
memcpy(nonce_96 + 4, nonce, 8);
return open_impl(poly1305_update_old, ctx, out, out_len, max_out_len,
nonce_96, in, in_len, ad, ad_len);
}
static const EVP_AEAD aead_chacha20_poly1305_old = {
32, /* key len */
8, /* nonce len */
POLY1305_TAG_LEN, /* overhead */
POLY1305_TAG_LEN, /* max tag length */
aead_chacha20_poly1305_init,
NULL, /* init_with_direction */
aead_chacha20_poly1305_cleanup,
aead_chacha20_poly1305_old_seal,
aead_chacha20_poly1305_old_open,
NULL, /* get_iv */
};
const EVP_AEAD *EVP_aead_chacha20_poly1305_old(void) {
return &aead_chacha20_poly1305_old;
}

Some files were not shown because too many files have changed in this diff Show More