Compare commits

...

182 Commits

Author SHA1 Message Date
Adam Langley f41eb86149 Switch an assert back to a check.
The assert was supposed to be *added* in fcf25833 but instead replaced
the check.

BUG=465557

Change-Id: I0d3db5038515021e5bdd1ccb9ff08d4f78552621
Reviewed-on: https://boringssl-review.googlesource.com/3850
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-03-09 19:17:48 -07:00
David Benjamin 10bec39d0e Use SSL_CLIENT_USE_TLS1_2_CIPHERS instead of ssl3_version_from_wire.
The latter was only added after branch point.

Change-Id: I19970478ee301ad85c8f2fb2c76ebde26ebd9887
Reviewed-on: https://boringssl-review.googlesource.com/3250
Reviewed-by: Adam Langley <agl@google.com>
2015-02-02 18:30:50 +00:00
David Benjamin 84edfee6a7 Only send sigalgs extension in 1.2-capable ClientHellos.
BUG=https://code.google.com/p/webrtc/issues/detail?id=4223

Change-Id: I88eb036fdc6da17bc6a5179df02f35486abe9add
Reviewed-on: https://boringssl-review.googlesource.com/3030
Reviewed-by: Adam Langley <agl@google.com>
(cherry picked from commit 6ae7f072e3)
2015-01-26 10:47:11 -08:00
Adam Langley ca9a538aa0 Fix various certificate fingerprint issues.
By using non-DER or invalid encodings outside the signed portion of a
certificate the fingerprint can be changed without breaking the signature.
Although no details of the signed portion of the certificate can be changed
this can cause problems with some applications: e.g. those using the
certificate fingerprint for blacklists.

1. Reject signatures with non zero unused bits.

If the BIT STRING containing the signature has non zero unused bits reject the
signature. All current signature algorithms require zero unused bits.

2. Check certificate algorithm consistency.

Check the AlgorithmIdentifier inside TBS matches the one in the certificate
signature. NB: this will result in signature failure errors for some broken
certificates.

3. Check DSA/ECDSA signatures use DER.

Reencode DSA/ECDSA signatures and compare with the original received signature.
Return an error if there is a mismatch.

This will reject various cases including garbage after signature (thanks to
Antti Karjalainen and Tuomo Untinen from the Codenomicon CROSS program for
discovering this case) and use of BER or invalid ASN.1 INTEGERs (negative or
with leading zeroes).

CVE-2014-8275

(Imported from upstream's 85cfc188c06bd046420ae70dd6e302f9efe022a9 and
4c52816d35681c0533c25fdd3abb4b7c6962302d)

Change-Id: Ic901aea8ea6457df27dc542a11c30464561e322b
Reviewed-on: https://boringssl-review.googlesource.com/2783
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-01-09 19:41:59 +00:00
Adam Langley 44e2709cd6 Fix DTLS memory leak.
A memory leak can occur in dtls1_buffer_record if either of the calls to
ssl3_setup_buffers or pqueue_insert fail. The former will fail if there
is a malloc failure, whilst the latter will fail if attempting to add a
duplicate record to the queue. This should never happen because
duplicate records should be detected and dropped before any attempt to
add them to the queue. Unfortunately records that arrive that are for
the next epoch are not being recorded correctly, and therefore replays
are not being detected. Additionally, these "should not happen" failures
that can occur in dtls1_buffer_record are not being treated as fatal and
therefore an attacker could exploit this by sending repeated replay
records for the next epoch, eventually causing a DoS through memory
exhaustion.

Thanks to Chris Mueller for reporting this issue and providing initial
analysis and a patch. Further analysis and the final patch was performed
by Matt Caswell from the OpenSSL development team.

CVE-2015-0206

(Imported from upstream's 7c6a3cf2375f5881ef3f3a58ac0fbd0b4663abd1).

Change-Id: I765fe61c75bc295bcc4ab356b8a5ce88c8964764
Reviewed-on: https://boringssl-review.googlesource.com/2782
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-01-09 19:41:47 +00:00
Adam Langley a83cc803b1 Fix for CVE-2014-3570.
(With minor bn/generic.c revamp.)

(Imported from upstream's 56df92efb6893abe323307939425957ce878c8f0)

Change-Id: I9d85cfde4dfb29e64ff7417f781d0c9f1685e905
Reviewed-on: https://boringssl-review.googlesource.com/2780
Reviewed-by: Adam Langley <agl@google.com>
2015-01-09 02:49:10 +00:00
Adam Langley 7cc3f992ae Add declarations for Android compatibility funcs.
Some parts of Android can't be updated yet so this change adds
declarations (only) for some functions that will be stubbed in
Android-specific code. (That Android-specific code will live in the
Android repo, not the BoringSSL repo.)

Trying to use these functions outside of Android will result in a link
error.

Change-Id: Iaa9b956e6408d21cd8fc34d90d9c15657e429877
Reviewed-on: https://boringssl-review.googlesource.com/2760
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-01-08 00:22:22 +00:00
Eric Roman aac2f6a6a0 Fix a compile error on Windows.
Write the array literal of all zeros as {0} rather than {}.

Change-Id: If15330d96d019be671d3bcbbdea60c2b3ecc2128
Reviewed-on: https://boringssl-review.googlesource.com/2740
Reviewed-by: Adam Langley <agl@google.com>
2015-01-06 19:46:52 +00:00
Adam Langley 0ed0cf6f38 s/comparision/comparison/.
I typoed this word and then auto-complete duplicated it all over the
place. This change fixes all the comments.

This change has no semantic effect (comment only).

Change-Id: I8952e9e71302043574757cd74a05e66500008432
2015-01-06 10:49:48 -08:00
Adam Langley 46a7ca0fa3 Condition the use of UI64 on _MSC_VER.
Using OPENSSL_WINDOWS for this is inaccurate because it's really a
feature of the compiler, not the platform. I think it's only MSVC that
uses the UI64 suffix.

Change-Id: I4a95961b94e69e72b93f5ed1e0457661b74242c8
Reviewed-on: https://boringssl-review.googlesource.com/2730
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-01-06 18:47:49 +00:00
David Benjamin 780d6dd0fe Treat handshake_failure in response to ClientHello special.
Add a dedicated error code to the queue for a handshake_failure alert in
response to ClientHello. This matches NSS's client behavior and gives a better
error on a (probable) failure to negotiate initial parameters.

BUG=https://crbug.com/446505

Change-Id: I34368712085a6cbf0031902daf2c00393783d96d
Reviewed-on: https://boringssl-review.googlesource.com/2751
Reviewed-by: Adam Langley <agl@google.com>
2015-01-06 18:31:49 +00:00
David Benjamin 2be62c304c Test which direction ERR_get_error reads from the error queue.
ERR_get_error returns the least recent error, not the most recent error.
Nothing in err_test was actually asserting on that.

Change-Id: Ia49e29c231de4bbec77d037860ad1ffa8cce4779
Reviewed-on: https://boringssl-review.googlesource.com/2750
Reviewed-by: Adam Langley <agl@google.com>
2015-01-06 18:29:45 +00:00
Nick Harper 4dd053e059 Cast ca_list to (void *) to silence msvc warning 4090
Change-Id: If1fad46f14286ba98b86754605731a7be31de901
Reviewed-on: https://boringssl-review.googlesource.com/2680
Reviewed-by: Adam Langley <agl@google.com>
2015-01-06 01:14:03 +00:00
Eric Roman 517073cd4b Set output EC_KEY to NULL when d2i_ECPrivateKey() fails.
BUG=crbug.com/445679

Change-Id: Ia012d806964bd7240148779797eccd326484f364
Reviewed-on: https://boringssl-review.googlesource.com/2722
Reviewed-by: Adam Langley <agl@google.com>
2015-01-06 00:55:19 +00:00
Adam Langley b9e0ccc650 Fix a couple of minor compiler warnings.
One about a possible uninitialised variable (incorrect, but it's easier
to keep the compiler happy) and one warning about "const static" being
backwards.

Change-Id: Ic5976a5f0b48f32e09682e31b65d8ea1c27e5b88
Reviewed-on: https://boringssl-review.googlesource.com/2632
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-01-06 00:27:22 +00:00
Adam Langley a7f6d3c1dc Add void in place of empty function arguments.
Since this is C89 we need to maintain this ancient practice.

Change-Id: I7223e7c38a35cf551b6e3c9159d2e21ebf7e62be
Reviewed-on: https://boringssl-review.googlesource.com/2631
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-01-06 00:27:07 +00:00
Adam Langley 93efb7228b Rename hexdump to hexdump_write.
It's a static function anyway so it doesn't affect anything and it's
colliding with a debugging function on one platform.

Change-Id: Iae0595cce7cb2bdd4c56217f6f1de51ff3134a8b
Reviewed-on: https://boringssl-review.googlesource.com/2630
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-01-06 00:26:53 +00:00
Nick Harper d3bcf13165 Properly handle key_len=0 for HMAC
The expectation when calling HMAC with key=NULL and keylen=0 is to compute
HMAC on the provided data with a key of length 0 instead of using the
"previous" key, which in the case of HMAC() is whatever bytes happen to be
left on the stack when the HMAC_CTX struct is allocated.

Change-Id: I52a95e262ee4e15f1af3136cb9c07f42f40ce122
Reviewed-on: https://boringssl-review.googlesource.com/2660
Reviewed-by: Adam Langley <agl@google.com>
2014-12-19 18:18:08 +00:00
Adam Langley fcf25833bc Reformat the rest of ssl/.
Change-Id: I7dc264f7e29b3ba8be4c717583467edf71bf8dd9
2014-12-18 17:43:03 -08:00
Nick Harper 4685e87746 Implement HKDF.
See https://tools.ietf.org/html/rfc5869.

Change-Id: I6d012d8c38806df80aa44350d3a86eaff499ac05
Reviewed-on: https://boringssl-review.googlesource.com/2533
Reviewed-by: Adam Langley <agl@google.com>
2014-12-18 20:13:06 +00:00
Adam Langley be2900a6a3 Reformat s3_{enc|lib}.c.
Change-Id: I4f2a241ef996952195b9bcdd9ee305e28b2aff5d
2014-12-18 12:09:22 -08:00
David Benjamin cf70188d53 Update EVP_Cipher documentation some more.
It doesn't retain partial blocks but it DOES update internal cipher state. ssl/
depends on this property.

Change-Id: I1e44b612c2e1549e096de8b71726007dcbc68de3
Reviewed-on: https://boringssl-review.googlesource.com/2640
Reviewed-by: Adam Langley <agl@google.com>
2014-12-18 19:37:24 +00:00
Adam Langley 1bea173fd4 Reformatting of s3_{cbc|clnt}.c
Change-Id: Ie873bdf0dd5a66e76e6ebf909b1f1fe29b6fa611
2014-12-17 19:06:57 -08:00
Adam Langley 6e73d62dcc Touch up ssl3_get_message.
The |skip_message| variable was overly complex and, since we have at
least 32-bit ints, we know that a 24-bit value doesn't overflow an int.

Change-Id: I5c16fa979e1716f39cc47882c033bcf5bce3284c
Reviewed-on: https://boringssl-review.googlesource.com/2610
Reviewed-by: Adam Langley <agl@google.com>
2014-12-17 00:16:23 +00:00
David Benjamin f49196052c Tidy up DSA paramgen stylistically.
No braceless ifs.

Change-Id: I8f559a6bcd7029e642b8b56aa082949570b4c1fb
Reviewed-on: https://boringssl-review.googlesource.com/2622
Reviewed-by: Adam Langley <agl@google.com>
2014-12-16 19:16:31 +00:00
David Benjamin a6d81018f8 Consistently use RAND_bytes and check for failure.
RAND_pseudo_bytes just calls RAND_bytes now and only returns 0 or 1. Switch all
callers within the library call the new one and use the simpler failure check.
This fixes a few error checks that no longer work (< 0) and some missing ones.

Change-Id: Id51c79deec80075949f73fa1fbd7b76aac5570c6
Reviewed-on: https://boringssl-review.googlesource.com/2621
Reviewed-by: Adam Langley <agl@google.com>
2014-12-16 19:15:59 +00:00
David Benjamin 263eac02f5 Remove X509 parameter from ssl_cert_type.
No current use of ssl_cert_type passes a NULL EVP_PKEY, so it can be simplified
a little.

Change-Id: I2052cc3b6069cd30e4685ba8a6d0014016a4d712
Reviewed-on: https://boringssl-review.googlesource.com/2620
Reviewed-by: Adam Langley <agl@google.com>
2014-12-16 19:10:44 +00:00
David Benjamin 9cf708807c Consistently order ECDHE_ECDSA over ECDHE_RSA.
Currently we don't express an opinion. Most sites aren't likely to have a
choice since it depends on what certificates they have available. But we may as
well order them.

Change-Id: I4fffa5e392f42e19823cb8faa2e9e15a6bb91086
Reviewed-on: https://boringssl-review.googlesource.com/2607
Reviewed-by: Adam Langley <agl@google.com>
2014-12-16 02:56:36 +00:00
Adam Langley 2481975857 Reformat d1_{srtp|srvr}.c and s3_both.c
Change-Id: I4dc1463b75b12e15673da32e4945f83aaea123e6
2014-12-15 18:42:07 -08:00
David Benjamin 4841ce49a0 Fix EVP_Cipher error-handling.
Turns out the EVP_CIPH_FLAG_CUSTOM_CIPHER ciphers (i.e. legacy EVP_CIPHER
AES-GCM) have a completely different return value setup than the normal ones
which are the standard one/zero. (Except that they never return zero; see
TODO.)

Fix checks in ssl/ and remove remnants of EVP_CIPH_FLAG_CUSTOM_CIPHER in ssl/
as we're using EVP_AEAD now.

See CHANGES entry added in upstream's 3da0ca796cae6625bd26418afe0a1dc47bf5a77f.

Change-Id: Ia4d0ff59b03c35fab3a08141c60b9534cb7172e2
Reviewed-on: https://boringssl-review.googlesource.com/2606
Reviewed-by: Adam Langley <agl@google.com>
2014-12-16 01:51:55 +00:00
David Benjamin ef5885e410 Don't change s->version after have_version is set.
Those version checks are if renego tried to change the version, but at that
point we're out of the initial null cipher and should leave the version fixed.

(On the server end, the code in question was dead after the version negotiation
rewrite anyway.)

Change-Id: I3242ba11bc9981ccf7fdb867176d59846cc49dd9
Reviewed-on: https://boringssl-review.googlesource.com/2605
Reviewed-by: Adam Langley <agl@google.com>
2014-12-16 01:44:35 +00:00
David Benjamin e4824e8af0 Add outgoing messages to the handshake hash at set_handshake_header.
This avoids needing a should_add_to_finished_hash boolean on do_write. The
logic in do_write was a little awkward because do_write would be called
multiple times if the write took several iterations. This also gets complex if
DTLS retransmits are involved. (At a glance, it's not obvious the
BIO_CTRL_DGRAM_MTU_EXCEEDED case actually works.)

Doing it as the handshake message is being prepared avoids this concern. It
also gives a natural point for the extended master secret logic which needs to
do work after the finished hash has been sampled.

As a bonus, we can remove s->d1->retransmitting which was only used to deal
with this issue.

Change-Id: Ifedf23ee4a6c5e08f960d296a6eb1f337a16dc7a
Reviewed-on: https://boringssl-review.googlesource.com/2604
Reviewed-by: Adam Langley <agl@google.com>
2014-12-16 01:43:51 +00:00
David Benjamin 44f2d1a9bf Use EVP_MAX_MD_SIZE to size the Finished message.
That comment is wrong as of TLS 1.2.

Change-Id: I900d5efc09d7468f2601d85f867833e43d046f6a
Reviewed-on: https://boringssl-review.googlesource.com/2603
Reviewed-by: Adam Langley <agl@google.com>
2014-12-16 01:38:51 +00:00
David Benjamin bf42f82ad9 Add comments explaining what NETSCAPE_HANG_BUG does.
(Or should we just drop this? It only matters for servers trying to use client
auth.)

Change-Id: I50b6999375dc8f9246bf617f17929ae304503c57
Reviewed-on: https://boringssl-review.googlesource.com/2602
Reviewed-by: Adam Langley <agl@google.com>
2014-12-16 01:37:33 +00:00
David Benjamin 07046a0946 Consistently use ssl_handshake_start and ssl_set_handshake_header.
Some of the messages did the computation manually which would bite us if we
tried to transplant them between DTLS and TLS. More importantly, it precludes
moving the handshake hash computation from ssl_do_write to
ssl_set_handshake_header.

Change-Id: I9d400deb0720e62cb1ab905242eb0679ad650a46
Reviewed-on: https://boringssl-review.googlesource.com/2600
Reviewed-by: Adam Langley <agl@google.com>
2014-12-16 01:35:53 +00:00
David Benjamin 16d031a493 Fold dtls1_set_message_header into dtls1_set_handshake_header.
The frag_off/frag_len parameters are always zero, and the return value is never
used.

Change-Id: If7487b23c55f2a996e411b25b76a8e1651f25d8b
Reviewed-on: https://boringssl-review.googlesource.com/2601
Reviewed-by: Adam Langley <agl@google.com>
2014-12-16 01:33:31 +00:00
Adam Langley 71d8a085d0 Reformatting of several DTLS source files.
This change has no semantic effect (I hope!). It's just a reformatting
of a few files in ssl/. This is just a start – the other files in ssl/
should follow in the coming days.

Change-Id: I5eb3f4b18d0d46349d0f94d3fe5ab2003db5364e
2014-12-13 16:28:18 -08:00
Adam Langley 139ed19580 Address code-review comments from prev changes.
David is heading out so I didn't want to block the previous batch of
changes for weeks. Thus I landed them as-is and this change tweaks a
couple of things that would normally have been addressed in code-review.

Change-Id: I2579dbc43d93fea34a52b4041f5511d70217aaf7
2014-12-13 15:35:50 -08:00
David Benjamin 87909c0445 Add tests for version negotiation failure alerts.
Ensure that both the client and the server emit a protocol_version alert
(except in SSLv3 where it doesn't exist) with a record-layer version which the
peer will recognize.

Change-Id: I31650a64fe9b027ff3d51e303711910a00b43d6f
2014-12-13 15:23:28 -08:00
David Benjamin 82c9e90a58 Merge SSLv23_method and DTLS_ANY_VERSION.
This makes SSLv23_method go through DTLS_ANY_VERSION's version negotiation
logic. This allows us to get rid of duplicate ClientHello logic. For
compatibility, SSL_METHOD is now split into SSL_PROTOCOL_METHOD and a version.
The legacy version-locked methods set min_version and max_version based this
version field to emulate the original semantics.

As a bonus, we can now handle fragmented ClientHello versions now.

Because SSLv23_method is a silly name, deprecate that too and introduce
TLS_method.

Change-Id: I8b3df2b427ae34c44ecf972f466ad64dc3dbb171
2014-12-13 15:22:21 -08:00
David Benjamin 4b755cb0da Implement the V2ClientHello sniff in version-locked methods.
Tested manually by replacing SSLv23_method() with TLSv1_2_method() in
bssl_shim. This is a large chunk of code which is not run in SSLv23_method(),
but it will be run after unification. It's split out separately to ease review.

Change-Id: I6bd241daca17aa0f9b3e36e51864a29755a41097
2014-12-13 15:22:21 -08:00
David Benjamin 63c55a8e35 Fix memory leak on failure.
Match the server logic to the client state machine and free if BUF_MEM_grow
fails.

Change-Id: I1a249f7b8c222cd710e969e17a1cba1f469f73e3
2014-12-13 15:22:21 -08:00
David Benjamin 1f48fba861 Use have_version in clamping TLS record-layer version to 1.0.
Match the DTLS code. Rather than sniffing the handshake state, use the
have_version bit.

Change-Id: I40e92f187647417c34b4cfdc3ad258f5562e781b
Reviewed-on: https://boringssl-review.googlesource.com/2588
Reviewed-by: Adam Langley <agl@google.com>
2014-12-13 23:19:36 +00:00
David Benjamin accb454e44 Add min_version tests.
These tests use both APIs. This also modifies the inline version negotiation's
error codes (currently only used for DTLS) to align with SSLv23's error codes.
Note: the peer should send a protocol_version alert which is currently untested
because it's broken.

Upstream would send such an alert if TLS 1.0 was supported but not otherwise,
which is somewhat bizarre. We've actually regressed and never send the alert in
SSLv23. When version negotiation is unified, we'll get the alerts back.

Change-Id: I4c77bcef3a3cd54a039a642f189785cd34387410
Reviewed-on: https://boringssl-review.googlesource.com/2584
Reviewed-by: Adam Langley <agl@google.com>
2014-12-13 23:00:02 +00:00
David Benjamin 1eb367c03e Add min_version and max_version APIs.
Amend the version negotiation tests to test this new spelling of max_version.
min_version will be tested in a follow-up.

Change-Id: Ic4bfcd43bc4e5f951140966f64bb5fd3e2472b01
Reviewed-on: https://boringssl-review.googlesource.com/2583
Reviewed-by: Adam Langley <agl@google.com>
2014-12-13 22:48:20 +00:00
David Benjamin 9ec6bcaebe Remove method swap in DTLS_ANY_VERSION.
DTLS_method() can now negotiate versions without switching methods.

Change-Id: I0655b3221b6e7e4b3ed4acc45f1f41c594447021
Reviewed-on: https://boringssl-review.googlesource.com/2582
Reviewed-by: Adam Langley <agl@google.com>
2014-12-13 22:39:46 +00:00
David Benjamin e99e912bea Pull SSL3_ENC_METHOD out of SSL_METHOD.
SSL3_ENC_METHOD will remain version-specific while SSL_METHOD will become
protocol-specific. This finally removes all the version-specific portions of
SSL_METHOD but the version tag itself.

(SSL3_ENC_METHOD's version-specific bits themselves can probably be handled by
tracking a canonicalized protocol version. It would simplify version
comparisons anyway. The one catch is SSLv3 has a very different table. But
that's a cleanup for future. Then again, perhaps a version-specific method
table swap somewhere will be useful later for TLS 1.3.)

Much of this commit was generated with sed invocation:
    s/method->ssl3_enc/enc_method/g

Change-Id: I2b192507876aadd4f9310240687e562e56e6c0b1
Reviewed-on: https://boringssl-review.googlesource.com/2581
Reviewed-by: Adam Langley <agl@google.com>
2014-12-13 22:38:27 +00:00
David Benjamin ceb6f2880f Factor out remaining version-related functions.
Now SSLv23 and DTLS_ANY_VERSION share version-related helper functions.
ssl3_get_method is temporary until the method switch is no longer necessary.

Put them all together so there's one place to refactor them when we add a new
version or implement min_version/max_version controls.

Change-Id: Ic28a145cad22db08a87fdb854480b22886c451c6
Reviewed-on: https://boringssl-review.googlesource.com/2580
Reviewed-by: Adam Langley <agl@google.com>
2014-12-13 22:35:52 +00:00
David Benjamin 69b9e597ae Remove SSL_CTX_set_ssl_version.
Missed this one. It requires that we be able to change an SSL_METHOD after the
after, which complicates compiling the version locking into min_version /
max_version configurations.

Change-Id: I24ba54b7939360bbfafe3feb355a65840bda7611
Reviewed-on: https://boringssl-review.googlesource.com/2579
Reviewed-by: Adam Langley <agl@google.com>
2014-12-13 22:31:31 +00:00
David Benjamin 7e23746dd4 Remove redundant SSL_ST_BEFORE-related checks.
SSL_ST_BEFORE isn't a possible state anymore. It seems this state meant the
side wasn't known, back in the early SSLeay days. Now upstream guesses
(sometimes incorrectly with generic methods), and we don't initialize until
later. SSL_shutdown also doesn't bother to call ssl3_shutdown at all if the
side isn't initialized and SSL_ST_BEFORE isn't the uninitialized state, which
seems a much more sensible arrangement.

Likewise, because bare SSL_ST_BEFOREs no longer exist, SSL_in_init implies
SSL_in_before and there is no need to check both.

Change-Id: Ie680838b2f860b895073dabb4d759996e21c2824
Reviewed-on: https://boringssl-review.googlesource.com/2564
Reviewed-by: Adam Langley <agl@google.com>
2014-12-13 22:31:16 +00:00
David Benjamin 138c2ac627 Drop unnecessary version checks.
These may as well be replaced with assertions. Get them out of the way of the
initialization.

Change-Id: Ie4ab8bdc018e4a1def7d3f6b3b172a77896bfc0a
Reviewed-on: https://boringssl-review.googlesource.com/2563
Reviewed-by: Adam Langley <agl@google.com>
2014-12-13 22:30:08 +00:00
David Benjamin 28014cb4f2 Remove s_accept and s_connect parameters IMPLEMENT* macros.
They're always known now. Also fix the SSLv23_{client,server}_method
definitions still had their own macro invocations.

Change-Id: Ia13f29a27f2331d25a4051e83f2d5abc62fab981
Reviewed-on: https://boringssl-review.googlesource.com/2562
Reviewed-by: Adam Langley <agl@google.com>
2014-12-13 22:29:45 +00:00
David Benjamin 338fcafe76 Mark SSL3_ENC_METHODs const and remove an unused one.
There's an undefined one not used anywhere. The others ought to be const.  Also
move the forward declaration to ssl.h so we don't have to use the struct name.

Change-Id: I76684cf65255535c677ec19154cac74317c289ba
Reviewed-on: https://boringssl-review.googlesource.com/2561
Reviewed-by: Adam Langley <agl@google.com>
2014-12-13 22:28:58 +00:00
David Benjamin f080ecd86d Don't infinite loop on garbage server input.
else block got lost in a rewrite of this code.

Change-Id: I51f1655474ec8bbd4eccb4297124e8584329444e
Reviewed-on: https://boringssl-review.googlesource.com/2560
Reviewed-by: Adam Langley <agl@google.com>
2014-12-11 23:55:38 +00:00
David Benjamin 226a872d2f Don't set client_version to the ServerHello version.
The client_version needs to be preserved, both for the RSA key exchange and
(when this codepath is used for TLS) for the SChannel renego workaround. Fix
the tests to enforce this so the cipher suite version tests catch this.

Change-Id: I0c42dc3ec4830f3724026b400e5066e7a7f1ee97
Reviewed-on: https://boringssl-review.googlesource.com/2551
Reviewed-by: Adam Langley <agl@google.com>
2014-12-11 18:49:42 +00:00
David Benjamin d14c6ee234 Remove TLSEXT_TYPE_padding ifdef.
There's no need to make that conditional.

Change-Id: Idac1aba42b22e3fe8e7731ae4ecb5ebc4183336c
Reviewed-on: https://boringssl-review.googlesource.com/2550
Reviewed-by: Adam Langley <agl@google.com>
2014-12-11 18:48:26 +00:00
Dave Tapuska b8a824d70d Add the ability to run a server from the command line tool.
Change-Id: Ia8588aeaad8b44a6a306d7d5bfecc895adde1910
2014-12-11 10:47:21 -08:00
David Benjamin e3594df7f1 Shorten certificate parsing code a little.
Comparing data is a much easier idiom than CBS_skip + a CBS_len check.

Change-Id: I3efe925734c76f3494cad682445291ae83750a7e
Reviewed-on: https://boringssl-review.googlesource.com/2500
Reviewed-by: Adam Langley <agl@google.com>
2014-12-11 00:05:56 +00:00
David Benjamin 1e29a6b7c5 Add assertions on the initial record version number.
The record-layer version of the ServerHello should match the final version. The
record-layer version of the ClientHello should be the advertised version, but
clamped at TLS 1.0. This is to ensure future rewrites do not regress this.

Change-Id: I96f1f0674944997ff38b562453a322ce61652635
Reviewed-on: https://boringssl-review.googlesource.com/2540
Reviewed-by: Adam Langley <agl@google.com>
2014-12-11 00:04:37 +00:00
Adam Langley af7e74ba9f Remove variable shadowing.
Bruce Dawson pointed out that the shadowing of |ret| in |s3_srvr.c|
looked dodgy. It was actually deliberate (we don't want to reset the
default value of the function's |ret| variable with a successful return
from the callback) but it does look dodgy.

This change adds -Wshadow to ban variable shadowing and fixes all
current instances.

Change-Id: I1268f88b9f26245c7d16d6ead5bb9014ea471c01
Reviewed-on: https://boringssl-review.googlesource.com/2520
Reviewed-by: Adam Langley <agl@google.com>
2014-12-09 21:32:49 +00:00
Håvard Molland 3547688ee0 Remove EC_GROUP_set_point_conversion_form
All serialization functions take point format as input, and
asn1_form is never used.

Change-Id: Ib1ede692e815ac0c929e3b589c3a5869adb0dc8b
Reviewed-on: https://boringssl-review.googlesource.com/2511
Reviewed-by: Adam Langley <agl@google.com>
2014-12-09 18:47:03 +00:00
Håvard Molland 306e520cda Remove ec hybrid point format
According to rfc5480 and rfc4492 the hybrid format is not allowed
neither in certificates or the tls protocol.

Change-Id: I1d3fb5bef765bc7b58d29bdd60e15247fac4dc7a
Reviewed-on: https://boringssl-review.googlesource.com/2510
Reviewed-by: Adam Langley <agl@google.com>
2014-12-08 22:47:41 +00:00
David Benjamin 8c37cb60d4 Advance to the next state variant when reusing messages (PR3597).
(Imported from upstream's 7a04b854d655785798d471df25ffd5036f3cc46b.)

This does not affect BoringSSL as ssl3_get_client_hello advances to yet another
state immediately after reading the message. But the state advance is correct.
It matches the normal exit for this function.

Change-Id: I8a664f2ad5f80beacbaf3e17a7786a5c9e8ef30e
Reviewed-on: https://boringssl-review.googlesource.com/2480
Reviewed-by: Piotr Sikora <piotr@cloudflare.com>
Reviewed-by: Adam Langley <agl@google.com>
2014-12-05 17:31:28 +00:00
David Benjamin 0ac86b0220 Remove dtls1_enc.
(Imported from upstream's 4b87706d20f0a2fdf2e8f1b90256e141c487ef47 and
eceef8fb865eb5de329b27ea472d4fdea4c290fe.)

Dead code.

Change-Id: I58120c3a9c42cb9db27f404774778222c3bb642a
Reviewed-on: https://boringssl-review.googlesource.com/2479
Reviewed-by: Adam Langley <agl@google.com>
2014-12-05 17:30:33 +00:00
David Benjamin 129992360a Check EVP_Cipher return values.
PR#1767

(Imported from upstream's fe78f08d1541211566a5656395186bfbdc61b6f8)

Not sure this is reachable (upstream's PR references custom engines), but
better be tidy. Note this is slightly different from upstream's: EVP_Cipher is
documented to return -1 on failure, not 0.

Change-Id: I836f12b73c6912a8ae8cbd37cfd3d33466acbc9e
Reviewed-on: https://boringssl-review.googlesource.com/2478
Reviewed-by: Adam Langley <agl@google.com>
2014-12-05 17:30:13 +00:00
David Benjamin 8278184631 Remove redundant checks in ssl_cert_dup.
PR#3613

(Imported from upstream's fc3968a25ce0c16cab8730ec0d68a59856158029)

We don't care about GOST, but removing redundant code is reasonable. Also
switch that CRYPTO_add to EVP_PKEY_dup. Missed a spot.

Change-Id: I768ec546d987fb3d8bc3decf7ebf1a5590fbb6c2
Reviewed-on: https://boringssl-review.googlesource.com/2477
Reviewed-by: Adam Langley <agl@google.com>
2014-12-05 17:27:23 +00:00
David Benjamin 83abdd6e58 Fixed memory leak due to incorrect freeing of DTLS reassembly bit mask
PR#3608

(Imported from upstream's 8a35dbb6d89a16d792b79b157b3e89443639ec94.)

Change-Id: Iab9d91f9b96793f2275a23770f1275ff4edf0386
Reviewed-on: https://boringssl-review.googlesource.com/2476
Reviewed-by: Adam Langley <agl@google.com>
2014-12-05 17:26:48 +00:00
David Benjamin e518f65d2c Update references to RFCs.
Some code predated the RFCs themselves, but the RFCs now exist. Also remove
now obsolete comments and some unused #defines.

See upstream's cffeacd91e70712c99c431bf32a655fa1b561482. (Though this predates
it; I just remembered I never uploaded it.)

Change-Id: I5e56f0ab6b7f558820f72e84dfdbc71a8c23cb91
Reviewed-on: https://boringssl-review.googlesource.com/2475
Reviewed-by: Adam Langley <agl@google.com>
2014-12-05 17:26:13 +00:00
Feng Lu 41aa325c6a ClientHello Padding for Fast Radio Opening in 3G.
The ClientHello record is padded to 1024 bytes when
fastradio_padding is enabled. As a result, the 3G cellular radio
is fast forwarded to DCH (high data rate) state. This mechanism
leads to a substantial redunction in terms of TLS handshake
latency, and benefits mobile apps that are running on top of TLS.

Change-Id: I3d55197b6d601761c94c0f22871774b5a3dad614
2014-12-04 14:30:16 -08:00
David Benjamin 74c68e5e37 Renegerate OID outputs.
The files should round-trip now. This corrects some discrepancies between
obj_mac.h and obj_mac.num which were also present in upstream. There seems to
be a mismerge in upstream's eebd5e5dd7dff58297ea52e1c21df8fccd593965.

(The discrepancy is harmless; those OIDs are not in obj_xref.txt.)

Change-Id: I1f6cda016533ec3182750310f9936f7e072b54a0
Reviewed-on: https://boringssl-review.googlesource.com/2474
Reviewed-by: Adam Langley <agl@google.com>
2014-12-04 22:13:50 +00:00
David Benjamin a6689b0488 Keep the obj_mac.h license header round-tripping.
Probably best to keep the original format, trailing whitespace and all.

Change-Id: I81a0ac46fd4ab4bb9d2b03d930b191024971447c
Reviewed-on: https://boringssl-review.googlesource.com/2473
Reviewed-by: Adam Langley <agl@google.com>
2014-12-04 22:13:17 +00:00
David Benjamin 687759db79 Restore obj_mac.num from upstream.
This got reset at some point, but not the files generated from it.
obj_mac.num is an input/output parameter to objects.pl and used to keep the
NIDs stable.

Imported from f2d678e6e89b6508147086610e985d4e8416e867, the point at which we
forked.

Change-Id: Ifd52b1aaa55054d37bc1217f2375a93302839e23
Reviewed-on: https://boringssl-review.googlesource.com/2472
Reviewed-by: Adam Langley <agl@google.com>
2014-12-04 22:12:55 +00:00
David Benjamin 7baab87798 Add documentation for the OID scripts.
Make the commands print a short usage summary and add a README file that
explains the dependencies.

Change-Id: I0c3f0713749ecfca23afaa2b536ac70dbdd7db0a
Reviewed-on: https://boringssl-review.googlesource.com/2471
Reviewed-by: Adam Langley <agl@google.com>
2014-12-04 22:12:26 +00:00
David Benjamin f1eba30292 Don't include undef in cross reference table.
From upstream's 55f7fb8848b6e4bec291724a479e1580d6f407d6.

Change-Id: I54ebc182addbf643bebc78aab03ba1327e24e2e7
Reviewed-on: https://boringssl-review.googlesource.com/2470
Reviewed-by: Adam Langley <agl@google.com>
2014-12-04 22:11:13 +00:00
David Benjamin 61f1085ee9 Switch crypto/bn back to _umul128 on Windows clang.
Upstream (impressively quickly) fixed the missing intrinsic. Switch Windows
clang back to building the same code as MSVC. Also include the intrin.h header
rather than forward-declare the intrinsic. clang only works if the header is
explicitly included. Chromium forcibly includes it to work around these kinds
of issues, but we shouldn't rely on it.

BUG=crbug.com/438382

Change-Id: I0ff6d48e1a3aa455cff99f8dc4c407e88b84d446
Reviewed-on: https://boringssl-review.googlesource.com/2461
Reviewed-by: Adam Langley <agl@google.com>
2014-12-04 00:23:15 +00:00
David Benjamin d8a3e78223 Shush a MSVC bool/int comparison warning.
MSVC doesn't like it when you compare the two.

Change-Id: I03c5ff2e2668ac2e536de8278e3a7c98a3dfd117
Reviewed-on: https://boringssl-review.googlesource.com/2460
Reviewed-by: Adam Langley <agl@google.com>
2014-12-04 00:22:31 +00:00
David Benjamin 90eeb11652 Remove SSL_set_debug.
It just inserts extra flushes everywhere and isn't used.

Change-Id: I082e4bada405611f4986ba852dd5575265854036
Reviewed-on: https://boringssl-review.googlesource.com/2456
Reviewed-by: Adam Langley <agl@google.com>
2014-12-04 00:22:14 +00:00
David Benjamin edb03cf31f Remove some unimplemented prototypes.
Change-Id: Ib9cb54ef11cebb6e8e0b77d6d02c4c6acd7d03db
Reviewed-on: https://boringssl-review.googlesource.com/2455
Reviewed-by: Adam Langley <agl@google.com>
2014-12-04 00:21:53 +00:00
David Benjamin 00505ec2e1 Add EVP_md5_sha1.
Use it in ssl3_cert_verify_hash so signing a pre-TLS-1.2 handshake hash can go
through RSA_sign and be intercepted via RSA_METHOD appropriately. This avoids
Windows needing to intercept sign_raw. (CAPI keys cannot provide sign_raw,
unless the input size happens to be that of NID_md5_sha1.)

Also use it in processing ServerKeyExchange to avoid special-casing RSA.

BUG=crbug.com/437023

Change-Id: Ia07433f468b75fdf7bfc8fa90c9751639b2478e6
Reviewed-on: https://boringssl-review.googlesource.com/2420
Reviewed-by: David Benjamin <davidben@google.com>
2014-12-02 20:45:07 +00:00
David Benjamin af9d9419a6 Don't use _umul128 for Windows clang.
Windows clang lacks _umul128, but it has inline assembly so just use
that.

Change-Id: I6ff5d2465edc703a4d47ef0efbcea43d6fcc79fa
Reviewed-on: https://boringssl-review.googlesource.com/2454
Reviewed-by: Adam Langley <agl@google.com>
2014-12-02 20:28:25 +00:00
David Benjamin 0105ece171 Fix standalone Windows build.
Don't link with dl, except on Linux where we have malloc tests.

Change-Id: I7b23acc854172e64628a55acecfaa9a661f74f77
Reviewed-on: https://boringssl-review.googlesource.com/2453
Reviewed-by: Adam Langley <agl@google.com>
2014-12-02 20:27:57 +00:00
David Benjamin 94d701b7e8 Left-pad a V2ClientHello's random, not right-pad.
The comment has it right, but the rewritten code was wrong.

Change-Id: I450193c39fb62eae32aae090a3834dd83db53421
Reviewed-on: https://boringssl-review.googlesource.com/2444
Reviewed-by: Adam Langley <agl@google.com>
2014-12-02 19:44:12 +00:00
David Benjamin d0f257dc2c Don't manually extern OPENSSL_ia32cap_P.
This probably snuck in when adapting the code from upstream. There's a header
file for it now. (Also it's uint32_t now rather than unsigned int.)

Change-Id: Ie8f45bc7a88988744174182a70512c0eff37cc1c
Reviewed-on: https://boringssl-review.googlesource.com/2441
Reviewed-by: Adam Langley <agl@google.com>
2014-12-02 19:43:01 +00:00
David Benjamin 128dbc30f6 Factor out the client max-version logic into a helper function.
Replace the comment with a clearer one and reimplement it much more tidily. The
mask thing was more complicated than was needed.

This slightly changes behavior on the DTLS_ANY_VERSION side in that, if only
one method is enabled, we no longer short-circuit to the version-locked method
early. This "optimization" seems unnecessary.

Change-Id: I571c8b60ed16bd4357c67d65df0dd1ef9cc5eb57
Reviewed-on: https://boringssl-review.googlesource.com/2451
Reviewed-by: Adam Langley <agl@google.com>
2014-12-02 19:42:39 +00:00
David Benjamin beb47022b0 Remove redundant s->server assignments in handshake.
It should be set correctly prior to entering the handshake. Don't mask bugs by
assigning it.

Change-Id: Ib9bca8fad68916b3b242aad8819e3760e59e777a
Reviewed-on: https://boringssl-review.googlesource.com/2443
Reviewed-by: Adam Langley <agl@google.com>
2014-12-02 19:35:38 +00:00
David Benjamin 8c6fe45c2f Replace s->first_packet with a s->s3->have_version bit.
first_packet is a temporary connection-global flag set for the duration of some
call and then queried from other code. This kind of logic is too difficult to
reason through. It also incorrectly treats renegotiate ClientHellos as
pre-version-negotiation records. This eliminates the need to query
enc_write_ctx (which wasn't EVP_AEAD-aware anyway).

Instead, take a leaf from Go TLS's book and add a have_version bit. This is
placed on s->s3 as it is connection state; s->s3 automatically gets reset on
SSL_clear while s doesn't.

This new flag will also be used to determine whether to do the V2ClientHello
sniff when the version-locked methods merge into SSLv23_method. It will also
replace needing to condition s->method against a dummy DTLS_ANY_VERSION value
to determine whether DTLS version negotiation has happened yet.

Change-Id: I5c8bc6258b182ba4ab175a48a84eab6d3a001333
Reviewed-on: https://boringssl-review.googlesource.com/2442
Reviewed-by: Adam Langley <agl@google.com>
2014-12-02 19:35:27 +00:00
David Benjamin cde8abae14 Merge client/server SSL_METHODs into the generic one.
Supporting both schemes seems pointless. Now that s->server and s->state are
set appropriately late and get_ssl_method is gone, the only difference is that
the client/server ones have non-functional ssl_accept or ssl_connect hooks. We
can't lose the generic ones, so let's unify on that.

Note: this means a static linker will no longer drop the client or server
handshake code if unused by a consumer linking statically. However, Chromium
needs the server half anyway for DTLS and WebRTC, so that's probably a lost
cause. Android also exposes server APIs.

Change-Id: I290f5fb4ed558f59fadb5d1f84e9d9c405004c23
Reviewed-on: https://boringssl-review.googlesource.com/2440
Reviewed-by: Adam Langley <agl@google.com>
2014-12-02 19:35:15 +00:00
David Benjamin f34a009834 Don't set s->state and s->server before the side is known.
If SSL_clear is called before SSL_set_{connect,accept}_state (as SSL_new does
internally), s->state will get set prematurely. Likewise, s->server is set
based on the method's ssl_accept hook, but client SSL's may be initialized from
a generic SSL_METHOD too.

Since we can't easily get rid of the generic SSL_METHODs, defer s->state and
s->server initialization until the side is known.

Change-Id: I0972e17083df22a3c09f6f087011b54c699a22e7
Reviewed-on: https://boringssl-review.googlesource.com/2439
Reviewed-by: Adam Langley <agl@google.com>
2014-12-02 19:34:49 +00:00
David Benjamin 63246e8a99 Remove s->type from SSL.
It's redundant with s->server.

Change-Id: Idb4ca44618477b54f3be5f0630f0295f0708b0f4
Reviewed-on: https://boringssl-review.googlesource.com/2438
Reviewed-by: Adam Langley <agl@google.com>
2014-12-02 19:34:28 +00:00
David Benjamin e319a2f73a Remove SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS.
It's unused. Also per the previous commit message, it historically had a bug
anyway.

Change-Id: I5868641e7938ddebbc0ffd72d218c81cd17c7739
Reviewed-on: https://boringssl-review.googlesource.com/2437
Reviewed-by: Adam Langley <agl@google.com>
2014-12-02 19:33:04 +00:00
David Benjamin 533ef7304d Remove SSL_clear calls in handshake functions.
If the state is SSL_ST_BEFORE, the SSL* was just initialized. Otherwise, we
don't want to call SSL_clear. The one case I found where we do is if a
handshake message is received and someone sets
SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS. This is apparently intended for external
consumers to set, but I see no code in Google that does.

Which is fortunate because it'll trigger SSL_clear. This retains the BIOs but
drops all connection state, including the record. If the client just initiated
renego, that's the ClientHello that's lost. The connection then hangs: the now
reset SSL* wants a ClientHello (under the null cipher because that too's been
dropped) while the peer wants an encrypted ServerHello.

Change-Id: Iddb3e0bb86d39d98155b060f9273a0856f2d1409
Reviewed-on: https://boringssl-review.googlesource.com/2436
Reviewed-by: Adam Langley <agl@google.com>
2014-12-02 19:32:39 +00:00
David Benjamin 8c88153465 Remove a place where SSL_clear cleans up after client/server confusion.
SSL_clear sets s->state and dtls1_clear sets cookie_len on the server. Setting
cookie_len on the server seems to serve no purpose but to let the callback know
how large the buffer is. This can be done just before calling the callback.

It also avoids a bug where the cookie check can be bypassed, should the server
not specify an app_verify_cookie_cb, by supplying a cookie of all zeros of the
maximum size. (Zero is fine because an empty cookie is rejected.)

The goal here is to avoid needing the SSL_clear calls in the handshake
functions. They are currently needed to fix the cookie_len setting when using
the generic method. (They get set wrong and then flipped back.)

Change-Id: I5095891bc0f7df62d83a9c84312fcf0b84826faa
Reviewed-on: https://boringssl-review.googlesource.com/2435
Reviewed-by: Adam Langley <agl@google.com>
2014-12-02 19:31:57 +00:00
David Benjamin ff42cc1eac Fix FALLBACK_SCSV, Channel ID, OCSP stapling, and SCTs with the generic method.
s->server's value isn't final until SSL_connect or SSL_accept is called when
using the generic SSLv23_method or DTLS_method rather than the version-locked
ones. This makes the tests pass if bssl_shim uses those methods.

It would be nicer if the generic methods were gone and an SSL* could know from
creation which half it's destined for. Unfortunately, there's a lot of code
that uses those generic methods, so we probably can't get rid of them. If they
have to stay, it seems better to standardize on only having those, rather than
support both, even if standardizing on the side-specific ones would be
preferable.

Change-Id: I40e65a8842cd6706da92263a263f664336a7f3b3
Reviewed-on: https://boringssl-review.googlesource.com/2434
Reviewed-by: Adam Langley <agl@google.com>
2014-12-02 19:31:35 +00:00
David Benjamin e58a71b9b3 Trim impossible state combinations.
SSL_ST_BEFORE is never standalone. As of upstream's
413c4f45ed0508d2242638696b7665f499d68265, SSL_ST_BEFORE is only ever set paired
with SSL_ST_ACCEPT or SSL_ST_CONNECT.

Conversely, SSL_ST_OK is never paired with SSL_ST_ACCEPT or SSL_ST_CONNECT. As
far as I can tell, this combination has never been possible.

Change-Id: Ifbc8f147be821026cf59f3d5038f0dbad3b0a1d2
Reviewed-on: https://boringssl-review.googlesource.com/2433
Reviewed-by: Adam Langley <agl@google.com>
2014-12-02 19:31:00 +00:00
David Benjamin 0b145c29a3 Don't assign handshake_func in the handshake functions.
It should already be assigned, as of upstream's
b31b04d951e9b65bde29657e1ae057b76f0f0a73. I believe these assignments are part
of the reason it used to appear to work. Replace them with assertions. So the
assertions are actually valid, check in SSL_connect / SSL_accept that they are
never called if the socket had been placed in the opposite state. (Or we'd be
in another place where it would have appeared to work with the handshake
functions fixing things afterwards.)

Now the only places handshake_func is set are in SSL_set_{connect,accept}_state
and the method switches.

Change-Id: Ib249212bf4aa889b94c35965a62ca06bdbcf52e1
Reviewed-on: https://boringssl-review.googlesource.com/2432
Reviewed-by: Adam Langley <agl@google.com>
2014-12-02 19:30:49 +00:00
David Benjamin 8c6a295c39 Remove obsolete comment.
This comment is no longer true. It dates from OpenSSL's initial commit, but
stopped being true in upstream's 413c4f45ed0508d2242638696b7665f499d68265.

Change-Id: I47377d992a00e3d57c795fef893e19e109dd6945
Reviewed-on: https://boringssl-review.googlesource.com/2431
Reviewed-by: Adam Langley <agl@google.com>
2014-12-02 19:30:37 +00:00
David Benjamin 9cbd4a809e Remove SSL_(CTX_)get_ssl_method.
We intend to deprecate the version-locked methods and unify them. Don't expose
that there's a method swap. (The existing version-locked methods will merely be
a shorthand for configuring minimum/maximum versions.)

There is one consumer of SSL_get_ssl_method in internal code, but it's just
some logging in test-only code. All it's doing is getting the version as a
string which should be SSL_get_version instead.

While here, also remove dead ssl_bad_method function. Also the bogus
ssl_crock_st forward-declaration. The forward declaration in base.h should be
perfectly sufficient.

Change-Id: I50480808f51022e05b078a285f58ec85d5ad7c8e
Reviewed-on: https://boringssl-review.googlesource.com/2408
Reviewed-by: Adam Langley <agl@google.com>
2014-12-02 19:30:25 +00:00
David Benjamin 502a909bd6 Recover SSL_OP_CIPHER_SERVER_PREFERENCE documentation.
b9cc33a4d6 deleted its documentation rather than
SSL_OP_EPHEMERAL_RSA's.

Change-Id: I2e099a2dc498f145c5a3ccaac824edbda27f7e89
Reviewed-on: https://boringssl-review.googlesource.com/2407
Reviewed-by: Adam Langley <agl@google.com>
2014-12-02 19:30:04 +00:00
David Benjamin 95eeb191c0 Make it clear that SSL_OP_NO_DTLS* are the same as the TLS ones.
They're mapped to the same value, which is the only reason the tests work right
now.

Change-Id: I22f6e3a6b3a2c88b0f92b6d261e86111b4172cd6
Reviewed-on: https://boringssl-review.googlesource.com/2406
Reviewed-by: Adam Langley <agl@google.com>
2014-12-02 19:29:46 +00:00
David Benjamin c44b1df459 Add test for renego client_version quirk.
In upstream's f4e1169341ad1217e670387db5b0c12d680f95f4, the client_version was
made constant across renegotiations, even if the server negotiated a lower
version. NSS has the same quirk, reportedly for SChannel:

https://code.google.com/p/chromium/codesearch#chromium/src/net/third_party/nss/ssl/ssl3con.c&sq=package:chromium&l=5103

Add a test to ensure we do not regress this.

Change-Id: I214e062463c203b86a9bab00f8503442e1bf74fe
Reviewed-on: https://boringssl-review.googlesource.com/2405
Reviewed-by: Adam Langley <agl@google.com>
2014-12-02 19:29:23 +00:00
David Benjamin 81ea0bf538 Delay creating s->session until resumption is resolved.
When not offering to resume a session, the client populates s->session with a
fresh SSL_SESSION before the ServerHello is processed and, in DTLS_ANY_VERSION,
before the version is even determined. Don't create a fresh SSL_SESSION until
we know we are doing a full handshake.

This brings ssl3_send_client_hello closer to ssl23_client_hello in behavior. It
also fixes ssl_version in the client in DTLS_ANY_VERSION.

SSLv23_client_method is largely unchanged. If no session is offered, s->session
continues to be NULL until the ServerHello is received. The one difference is
that s->session isn't populated until the entire ServerHello is received,
rather than just the first half, in the case of a fragmented ServerHello. Apart
from info_callback, no external hooks get called between those points, so this
shouldn't expose new missing NULL checks.

The other client methods change significantly to match SSLv23_client_method's
behavior. For TLS, any exposed missing NULL checks are also in
SSLv23_client_method (and version-specific methods are already weird), so that
should be safe. For DTLS, I've verified that accesses in d1_*.c either handle
NULL or are after the ServerHello.

Change-Id: Idcae6bd242480e28a57dbba76ce67f1ac1ae1d1d
Reviewed-on: https://boringssl-review.googlesource.com/2404
Reviewed-by: Adam Langley <agl@google.com>
2014-12-02 19:28:18 +00:00
David Benjamin 8b8c006564 Fix DTLS_ANY_VERSION and add tests.
This fixes bugs that kept the tests from working:

- Resolve DTLS version and cookie before the session.

- In DTLS_ANY_VERSION, ServerHello should be read with first_packet = 1. This
  is a regression from f2fedefdca. We'll want to
  do the same for TLS, but first let's change this to a boolean has_version in a
  follow-up.

Things not yet fixed:

- DTLS code is not EVP_AEAD-aware. Those ciphers are disabled for now.

- On the client, DTLS_ANY_VERSION creates SSL_SESSIONs with the wrong
  ssl_version. The tests pass because we no longer enforce the match as of
  e37216f56009fbf48c3a1e733b7a546ca6dfc2af. (In fact, we've gone from the server
  ignoring ssl_version and client enforcing to the client mostly ignoring
  ssl_version and the server enforcing.)

- ssl3_send_client_hello's ssl_version check checks for equality against
  s->version rather than >.

Change-Id: I5a0dde221b2009413df9b9443882b9bf3b29519c
Reviewed-on: https://boringssl-review.googlesource.com/2403
Reviewed-by: Adam Langley <agl@google.com>
2014-12-02 19:27:54 +00:00
David Benjamin 65ea8ff84c Debug resumption connections with -debug too.
Change-Id: Ib33cceed561698310f369d63de602123af146a45
Reviewed-on: https://boringssl-review.googlesource.com/2402
Reviewed-by: Adam Langley <agl@google.com>
2014-12-02 19:27:33 +00:00
David Benjamin 95f9cfcde0 unifdef OPENSSL_NO_BIO.
Get that out of the way.

Change-Id: Ia61f47f1e23595a1d4876a85ae7518f11f4ab6a0
Reviewed-on: https://boringssl-review.googlesource.com/2401
Reviewed-by: Adam Langley <agl@google.com>
2014-12-02 19:27:19 +00:00
David Benjamin bafc58dfa4 Remove dead SSL BIO prototypes.
Those aren't implemented.

Change-Id: If4229f9cd2a8d333678a9cb35c4e857068794c49
Reviewed-on: https://boringssl-review.googlesource.com/2400
Reviewed-by: Adam Langley <agl@google.com>
2014-12-02 19:26:47 +00:00
David Benjamin 0f1e64bf7f Remove method swap in SSL_set_session.
This is a bit of cleanup that probably should have been done at the same time
as 30ddb434bf.

For now, version negotiation is implemented with a method swap. It also
performs this swap on SSL_set_session, but this was neutered in
30ddb434bf. Rather than hackishly neuter it,
remove it outright.  In addition, remove SSL_set_ssl_method. Now all method
swaps are internal: SSLv23_method switch to a version-specific method and
SSL_clear undoing it.

Note that this does change behavior: if an SSL* is created with one
version-specific method and we SSL_set_session to a session from a /different/
version, we would switch to the /other/ version-specific method. This is
extremely confusing, so it's unlikely anyone was actually expecting it.
Version-specific methods in general don't work well.

Change-Id: I72a5c1f321ca9aeb1b52ebe0317072950ba25092
Reviewed-on: https://boringssl-review.googlesource.com/2390
Reviewed-by: Adam Langley <agl@google.com>
2014-12-02 19:26:30 +00:00
David Benjamin 61f95277d4 Add tests for OCSP stapling and SCT lists.
We forgot to add those when we implemented the features. (Also relevant because
they will provide test coverage later for configuring features when using the
generic method tables rather than *_client_method.)

Change-Id: Ie08b27de893095e01a05a7084775676616459807
Reviewed-on: https://boringssl-review.googlesource.com/2410
Reviewed-by: Adam Langley <agl@google.com>
2014-12-02 19:26:01 +00:00
David Benjamin bb15e3ddb5 Remove method-switching codepath in SSL_clear.
Although the comment suggests this was added with an s->session check to
account for SSL_set_session switching methods (which we will remove in the next
commit) and to account for SSLv23_method switching methods (which we hope to
remove after a long tower of cleanup), the current codepath never runs and
can't work:

If it is called prior to handshaking or setting a session, no method switch has
happened so that codepath is dead. If it is called after setting a session, the
s->session check will keep it from running. If it is called after a handshake,
we will have established a session so that check will again keep it from
running. (Finally, if it is called during the handshake, the in_handshake check
will stop; that there is an SSL_clear call in the handshake state machine at
all is a bug that will be addressed once more things are disentangled. See
upstream's 979689aa5cfa100ccbc1f25064e9398be4b7b05c.)

Were that code to ever run, the SSL* would be in an inconsistent state. It
switches the method, but not the handshake_func. The handshake_func isn't
switched to NULL, so that will keep the SSL_connect and SSL_accept code from fixing it.

It seems the intent was that the caller would always call
SSL_set_{connect,accept}_state to fix this. But as of upstream's
b31b04d951e9b65bde29657e1ae057b76f0f0a73, this is not necessary and indeed
isn't called by a lot of consumer code.

Change-Id: I710652b1d565b77bc26f913c2066ce749a9025c9
Reviewed-on: https://boringssl-review.googlesource.com/2430
Reviewed-by: Adam Langley <agl@google.com>
2014-12-01 21:43:13 +00:00
David Benjamin 52d699f668 Make OCSP response and SCT list getter const-correct.
The data is owned by the SSL_SESSION, so the caller should not modify it. This
will require changes in Chromium, but they should be trivial.

Change-Id: I314718530c7d810f7c7b8852339b782b4c2dace1
Reviewed-on: https://boringssl-review.googlesource.com/2409
Reviewed-by: Adam Langley <agl@google.com>
2014-12-01 21:20:56 +00:00
David Benjamin 192f34b175 Fix bio_test.c build on Windows.
MSVC does not allow pointer arithmetic on void* pointers. Also
fix some style issues around whether * hugs the type or the
variable name.

Change-Id: I40cc1627830b37879fd70e2b688a42df62b6c62a
Reviewed-on: https://boringssl-review.googlesource.com/2452
Reviewed-by: Adam Langley <agl@google.com>
2014-12-01 19:06:59 +00:00
Håvard Molland 4e0a7e5a1d Cleanup of setting external buffer
Don't use |BIO_set_foo_buffer_size| when setting the
sizes of the buffers while making buffer pair. Since it
happens in pair.c we know the BIOs are BIO pairs and using
bio_ctrl here complicates setting external buffers. Also
zero out bio_bio_st during construction.

This fixes a problem that would happen if the default buffer
sizes were not set, since buf_externally_allocated was
not yet initialized.

Remove BIO_C_SET_BUFF_SIZE and BIO_CTRL_RESET which are
not used for bio pairs.

Change-Id: I365091d5f44f6f1c5522c325a771bdf03d8fe950
Reviewed-on: https://boringssl-review.googlesource.com/2370
Reviewed-by: Adam Langley <agl@google.com>
2014-11-24 17:46:00 +00:00
David Benjamin d1681e614f Remove SSL_set_session_secret_cb (EAP-FAST)
This is only used for EAP-FAST which we apparently don't need to support.
Remove it outright. We broke it in 9eaeef81fa by
failing to account for session misses.

If this changes and we need it later, we can resurrect it. Preferably
implemented differently: the current implementation is bolted badly onto the
handshake. Ideally use the supplied callbacks to fabricate an appropriate
SSL_SESSION and resume that with as much of the normal session ticket flow as
possible.

The one difference is that EAP-FAST seems to require the probing mechanism for
session tickets rather than the sane session ID echoing version.  We can
reimplement that by asking the record layer to probe ahead for one byte.

Change-Id: I38304953cc36b2020611556a91e8ac091691edac
Reviewed-on: https://boringssl-review.googlesource.com/2360
Reviewed-by: Adam Langley <agl@google.com>
2014-11-21 21:51:10 +00:00
David Benjamin fe8eb9a603 Add tests for session-ID-based resumption.
This implements session IDs in client and server in runner.go.

Change-Id: I26655f996b7b44c7eb56340ef6a415d3f2ac3503
Reviewed-on: https://boringssl-review.googlesource.com/2350
Reviewed-by: Adam Langley <agl@google.com>
2014-11-21 21:35:39 +00:00
David Benjamin ae3e487d51 Fix a couple more malloc test crashes.
The ex_data index may fail to be allocated. Also don't leave a dangling pointer
in handshake_dgst if EVP_DigestInit_ex fails and check a few more init function
failures.

Change-Id: I2e99a89b2171c9d73ccc925a2f35651af34ac5fb
Reviewed-on: https://boringssl-review.googlesource.com/2342
Reviewed-by: Adam Langley <agl@google.com>
2014-11-19 22:17:50 +00:00
Adam Langley 69a01608f3 Add malloc failure tests.
This commit fixes a number of crashes caused by malloc failures. They
were found using the -malloc-test=0 option to runner.go which runs tests
many times, causing a different allocation call to fail in each case.

(This test only works on Linux and only looks for crashes caused by
allocation failures, not memory leaks or other errors.)

This is not the complete set of crashes! More can be found by collecting
core dumps from running with -malloc-test=0.

Change-Id: Ia61d19f51e373bccb7bc604642c51e043a74bd83
Reviewed-on: https://boringssl-review.googlesource.com/2320
Reviewed-by: Adam Langley <agl@google.com>
2014-11-19 01:24:46 +00:00
Nico Weber deb5284138 Make build work on OS X with older cmake versions.
`uname -p` is still i386 on OS X for some reason, which causes cmake 2.8 to set
CMAKE_SYSTEM_PROCESSOR to i386, making the build think it's doing a 32-bit
build.  However, since the system is almost completely 64-bit these days, clang
defaults to producing 64-bit object files unless told otherwise. As a result,
the produced .o files are all 64-bit except for the .o files from assembly, and
then linking fails.

Fix this by forcing ARCH to 64-bit on OS X. This matches the default behavior
of cmake 3.0, where CMAKE_SYSTEM_PROCESSOR is x86_64.

Change-Id: I7a2abc4cef84dfbaf205852a9d7b647e83dd249f
Reviewed-on: https://boringssl-review.googlesource.com/2330
Reviewed-by: Adam Langley <agl@google.com>
Reviewed-by: Piotr Sikora <piotr@cloudflare.com>
2014-11-18 23:08:20 +00:00
David Benjamin 000800a306 Add tests for signature algorithm negotiation.
Change-Id: I5a263734560997b774014b5742877aa4b2940664
Reviewed-on: https://boringssl-review.googlesource.com/2289
Reviewed-by: Adam Langley <agl@google.com>
2014-11-18 22:30:03 +00:00
David Benjamin ec2f27dee1 Account for EVP_PKEY capabilities in selecting hash functions.
tls1_process_sigalgs now only determines the intersection between the peer
algorithms and those configured locally. That list is queried later to
determine the hash algorithm to use when signing CertificateVerify or
ServerKeyExchange.

This is needed to support client auth on Windows where smartcards or CAPI may
not support all hash functions.

As a bonus, this does away with more connection-global state. This avoids the
current situation where digests are chosen before keys are known (for
CertificateVerify) or for slots that don't exist.

Change-Id: Iec3619a103d691291d8ebe08ef77d574f2faf0e8
Reviewed-on: https://boringssl-review.googlesource.com/2280
Reviewed-by: Adam Langley <agl@google.com>
2014-11-18 22:22:33 +00:00
David Benjamin 033e5f47d1 Remove CERT_PKEY::valid_flags.
CERT_PKEY_SIGN isn't meaningful since, without strict mode, we always fall back
to SHA-1 anyway. So the digest is never NULL when CERT_PKEY_SIGN is computed.
The entire valid_flags is now back to it's pre-1.0.2 check of seeing if the
certificate and key are configured.

This finally removes the sensitivity between valid_flags and selecting the
digest, so we can defer choosing the digest all we like.

Change-Id: I9f9952498f512d7f0cc799497f7c5b52145a48af
Reviewed-on: https://boringssl-review.googlesource.com/2288
Reviewed-by: Adam Langley <agl@google.com>
2014-11-18 22:22:23 +00:00
David Benjamin f31e681acf Clean up ssl_set_cert_masks.
It doesn't depend on the cipher now that export ciphers are gone. It need only
be called once. Also remove the valid bit; nothing ever reads it. Its output is
also only used within a function, so make mask_k and mask_a local variables.

So all the configuration-based checks are in one place, change the input
parameter from CERT to SSL and move the PSK and ECDHE checks to the mask
computation. This avoids having to evaluate the temporary EC key for each
cipher.

The remaining uses are on the client which uses them differently (disabled
features rather than enabled ones). Those too may as well be local variables,
so leave a TODO.

Change-Id: Ibcb574341795d4016ea749f0290a793eed798874
Reviewed-on: https://boringssl-review.googlesource.com/2287
Reviewed-by: Adam Langley <agl@google.com>
2014-11-18 22:21:52 +00:00
Nico Weber 81257cb2e0 Add a codereview.settings file.
With this, `git cl upload` will do the right thing for boringssl.

BUG=none
Change-Id: Icc83144ef39bc71c795c411e608e0b8c009f3a04
Reviewed-on: https://boringssl-review.googlesource.com/2331
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2014-11-18 22:21:33 +00:00
David Benjamin 6a8d70c528 Trim tls1_check_chain and CERT_PKEY flags.
Many are now unused. Only two are currently considered in cipher selection:
CERT_PKEY_VALID and CERT_PKEY_SIGN. (As per previous commits, this is either
bizarre due to limited slots or redundant with ssl_early_callback_ctx. We can
probably prune this too.)

This also fixes a bug where DTLS 1.0 went through a TLS 1.2 codepath. As the
DTLS code is currently arranged, all version comparisons must be done via
macros like SSL_USE_SIGALGS. (Probably we should add functions to map from DTLS
to TLS versions and slowly move the library to using the TLS version as
in-memory representation.)

Change-Id: I89bcf5b7b9ea5cdecf54f4445156586377328fe0
Reviewed-on: https://boringssl-review.googlesource.com/2286
Reviewed-by: Adam Langley <agl@google.com>
2014-11-18 22:20:53 +00:00
David Benjamin 253b3e76dc Remove TLS strict mode.
It's new in OpenSSL 1.0.2 so it's never set by existing code. This removes gobs
and gobs of complexity from tls1_check_chain. It only checks the local
certificate, not the peer certificate. The uses appear to be:

- Sanity-check configuration. Not worth the complexity.

- Guide in selecting ciphers based on ClientHello parameters and which
  certificates in the CERT_PKEY are compatible. This isn't very useful one its
  own since the CERT_PKEY array only stores one slot per type (e.g. you cannot
  configure RSA/SHA-1 and RSA/SHA-256).

- For the (currently removed) SSL_check_chain to return more information based
  on ClientHello parameters and guide selecting a certificate. This is
  potentially useful but, as noted in the commit which removed it, redundant
  with ssl_early_callback_ctx.

This CL is largely mechanical removing of dead codepaths. The follow-up will
clean up the now unnecessary parts of this function.

Change-Id: I2ebfa17e4f73e59aa1ee9e4ae7f615af2c6cf590
Reviewed-on: https://boringssl-review.googlesource.com/2285
Reviewed-by: Adam Langley <agl@google.com>
2014-11-18 22:20:33 +00:00
David Benjamin 1ad868176d check_flags is always 0.
Get rid of now dead codepaths.

Change-Id: I3b5d49097cba70c5698a230cc6c1d79bdd0f0880
Reviewed-on: https://boringssl-review.googlesource.com/2284
Reviewed-by: Adam Langley <agl@google.com>
2014-11-18 22:20:10 +00:00
David Benjamin b398d16c1d Remove SSL_check_chain and unexport CERT_PKEY flags.
Both of these are newly-exported in OpenSSL 1.0.2, so they cannot be used by
current consumers.

This was added in upstream's 18d7158809c9722f4c6d2a8af7513577274f9b56 to
support custom selection of certificates. The intent seems to be that you
listen to cert_cb and use SSL_check_chain to lean on OpenSSL to process
signature algorithms list for you.

Unfortunately, the implementation is slightly suspect: it uses the same
function as the codepath which mutates and refers to the CERT_PKEY of the
matching type.  Some access was guarded by check_flags, but this is too
complex. Part of it is also because the matching digest is selected early and
we intend to connect this to EVP_PKEY_supports_digest so it is no longer a
property of just the key type.

Let's remove the hook for now, to unblock removing a lot of complexity. After
cleaning up this area, a function like this could be cleaner to support, but
we already have a version of this: select_certificate_cb and
ssl_early_callback_ctx.

Change-Id: I3add425b3996e5e32d4a88e14cc607b4fdaa5aec
Reviewed-on: https://boringssl-review.googlesource.com/2283
Reviewed-by: Adam Langley <agl@google.com>
2014-11-18 22:19:24 +00:00
David Benjamin 675227e0d2 Remove CERT_PKEY_EXPLICIT_SIGN flag.
This is maintained just to distinguish whether the digest was negotiated or we
simply fell back to assuming SHA-1 support. No code is sensitive to this flag
and it adds complexity because it is set at a different time, for now, from the
rest of valid_flags.

The flag is new in OpenSSL 1.0.2, so nothing external could be sensitive to it.

Change-Id: I9304e358d56f44d912d78beabf14316d456bf389
Reviewed-on: https://boringssl-review.googlesource.com/2282
Reviewed-by: Adam Langley <agl@google.com>
2014-11-18 22:19:06 +00:00
David Benjamin 248f350ed8 Remove SSL_get_peer_signature_nid and don't compute digests for peer_key.
This is new in OpenSSL 1.0.2 so it isn't used anywhere. Cuts down slightly on
connection-global state associated with signature algorithm processing.
Repurposing the digest field to mean both "the digest we choose to sign with
this key" and "the digest the last signature we saw happened to use" is
confusing.

Change-Id: Iec4d5078c33e271c8c7b0ab221c356ee8480b89d
Reviewed-on: https://boringssl-review.googlesource.com/2281
Reviewed-by: Adam Langley <agl@google.com>
2014-11-18 22:18:54 +00:00
David Benjamin c20febe177 Add EVP_PKEY_supports_digest.
This is intended for TLS client auth with Windows CAPI- and CNG-backed keys
which implement sign over sign_raw and do not support all hash functions. Only
plumbed through RSA for now.

Change-Id: Ica42e7fb026840f817a169da9372dda226f7d6fd
Reviewed-on: https://boringssl-review.googlesource.com/2250
Reviewed-by: Adam Langley <agl@google.com>
2014-11-18 22:18:36 +00:00
David Benjamin ca6c82643a Add DTLS-SRTP tests.
Just the negotiation portion as everything else is external. This feature is
used in WebRTC.

Change-Id: Iccc3983ea99e7d054b59010182f9a56a8099e116
Reviewed-on: https://boringssl-review.googlesource.com/2310
Reviewed-by: Adam Langley <agl@google.com>
2014-11-18 22:16:53 +00:00
Håvard Molland ce5be4bd5c Add zero copy read and write api for bio pairs.
Also add functionality for setting external buffers to give the
caller better control of the buffers. This is typical needed if OS
sockets can outlive the bio pair.

Change-Id: I500f0c522011ce76e9a9bce5d7b43c93d9d11457
2014-11-18 14:06:46 -08:00
David Benjamin 5e4f6e9247 Remove some remnants of SSLv2.
Change-Id: Id294821162c4c9ea6f2fce2a0be65bafcb616068
Reviewed-on: https://boringssl-review.googlesource.com/2311
Reviewed-by: Adam Langley <agl@google.com>
2014-11-17 20:27:13 +00:00
David Benjamin 3087f6e594 Fix garbage free on malloc failure in ec_wNAF_mul.
PR#3595

(Imported from upstream's e04d426bf98ebb22abf0f15b6f09d333a6e8b2ad.)

Change-Id: I01a9d9bef7e911b3fb1565f8a582f5d6cc7d5537
Reviewed-on: https://boringssl-review.googlesource.com/2290
Reviewed-by: Adam Langley <agl@google.com>
2014-11-14 18:47:41 +00:00
Alex Chernyakhovsky 4cd8c43e73 Remove support for processing fragmented alerts
Prior to this change, BoringSSL maintained a 2-byte buffer for alerts,
and would support reassembly of fragmented alerts.

NSS does not support fragmented alerts, nor would any reasonable
implementation produce them. Remove fragmented alert handling and
produce an error if a fragmented alert has ever been encountered.

Change-Id: I31530ac372e8a90b47cf89404630c1c207cfb048
Reviewed-on: https://boringssl-review.googlesource.com/2125
Reviewed-by: Adam Langley <agl@google.com>
2014-11-13 22:58:30 +00:00
David Benjamin bdf5e72f50 Don't resume sessions if the negotiated version doesn't match.
All of NSS, upstream OpenSSL, SChannel, and Secure Transport require, on the
client, that the ServerHello version match the session's version on resumption.
OpenSSL's current behavior is incompatible with all of these. Fall back to a
full handshake on the server instead of mismatch.

Add a comment on the client for why we are, as of
30ddb434bf, not currently enforcing the same in
the client.

Change-Id: I60aec972d81368c4ec30e2fd515dabd69401d175
Reviewed-on: https://boringssl-review.googlesource.com/2244
Reviewed-by: Adam Langley <agl@google.com>
2014-11-13 22:05:12 +00:00
David Benjamin 2f3ba910a2 Fix ec_test build on Windows.
No need to include unistd.h. (Though it probably should include string.h for
memcmp and strcmp.)

Change-Id: Ib09d2da4f7079c9d87338df75ec3560f4f203764
Reviewed-on: https://boringssl-review.googlesource.com/2260
Reviewed-by: Adam Langley <agl@google.com>
2014-11-12 19:39:55 +00:00
David Benjamin e18d821dfc runner: Refuse to resume sessions on mismatching versions.
Clients all consistently reject mismatches. If a different version was
negotiated, a server should ignore the resumption. This doesn't actually affect
current tests.  We really want to be making this change in BoringSSL (and then
upstream), but get the Go half into shape first.

Change-Id: Ieee7e141331d9e08573592e661889bd756dccfa9
Reviewed-on: https://boringssl-review.googlesource.com/2243
Reviewed-by: Adam Langley <agl@google.com>
2014-11-11 18:25:28 +00:00
David Benjamin d0297db108 Remove TODO about DTLS cookie lengths.
The limit increased from 32 to 255 between DTLS 1.0 and DTLS 1.2.

Change-Id: I329a59f9ba2bccc70282e2b47679c57b67e5ed43
Reviewed-on: https://boringssl-review.googlesource.com/2242
Reviewed-by: Adam Langley <agl@google.com>
2014-11-11 18:24:23 +00:00
David Benjamin ca6554b133 Add tests for client-initiated renegotiation.
These'll get removed once most of renego support is gone, but this is to prove
removing the warning alert from the previous commit still prevents legacy
renegotiations.

Change-Id: I7d9d95e1d4c5d23d3b6d170938a5499a65f2d5ea
Reviewed-on: https://boringssl-review.googlesource.com/2236
Reviewed-by: Adam Langley <agl@google.com>
2014-11-11 00:00:49 +00:00
David Benjamin 9114fae39e Add a test for RSA ServerKeyExchange.
Ensure that the client rejects it with UNEXPECTED_MESSAGE, not by attempting to
decode it.

Change-Id: Ifc5613cf1152e0f7dcbee73e05df1ef367dfbfd5
Reviewed-on: https://boringssl-review.googlesource.com/2232
Reviewed-by: Adam Langley <agl@google.com>
2014-11-11 00:00:39 +00:00
David Benjamin 688d8dfe48 Remove psk_identity_hint from SSL_SESSION.
There's not much point in retaining the identity hint in the SSL_SESSION. This
avoids the complexity around setting psk_identity hint on either the SSL or the
SSL_SESSION. Introduce a peer_psk_identity_hint for the client to store the one
received from the server.

This changes the semantics of SSL_get_psk_identity_hint; it now only returns
the value configured for the server. The client learns the hint through the
callback. This is compatible with the one use of this API in conscrypt (it
pulls the hint back out to pass to a callback).

Change-Id: I6d9131636b47f13ac5800b4451436a057021054a
Reviewed-on: https://boringssl-review.googlesource.com/2213
Reviewed-by: Adam Langley <agl@google.com>
2014-11-10 23:59:47 +00:00
David Benjamin e1b20a0136 Remove SSL3_FLAGS_POP_BUFFER.
This is an experimental flag that dates back to SSLeay 0.8.1b or earlier. It's
never set internally and never set in consumers.

Change-Id: I922583635c9f3d8d93f08f1707531ad22a26ae6a
Reviewed-on: https://boringssl-review.googlesource.com/2214
Reviewed-by: Adam Langley <agl@google.com>
2014-11-10 23:59:13 +00:00
David Benjamin 5e961c1ff1 Add DTLS replay tests.
At the record layer, DTLS maintains a window of seen sequence numbers to detect
replays. Add tests to cover that case. Test both repeated sequence numbers
within the window and sequence numbers past the window's left edge. Also test
receiving sequence numbers far past the window's right edge.

Change-Id: If6a7a24869db37fdd8fb3c4b3521b730e31f8f86
Reviewed-on: https://boringssl-review.googlesource.com/2221
Reviewed-by: Adam Langley <agl@google.com>
2014-11-10 23:58:56 +00:00
David Benjamin 0d82482e47 Fix ownership of error data in ERR_peek_*.
The error queue should only take ownership of the data if ERR_get_* is called,
not ERR_peek_*. Add a test for ERR_peek_error_line_data.

Change-Id: I976fc90fb54437dff723418ef3afd94f1c967922
Reviewed-on: https://boringssl-review.googlesource.com/2237
Reviewed-by: Adam Langley <agl@google.com>
2014-11-10 23:09:59 +00:00
David Benjamin f2f3cfedb7 Use BN_bn2bin_padded rather than doing math to figure out leading zeros.
Saves doing it ad-hoc all the time.

Change-Id: Ic1a1180f56eec37c19799649bb8f18237bd617f8
Reviewed-on: https://boringssl-review.googlesource.com/2241
Reviewed-by: Adam Langley <agl@google.com>
2014-11-10 23:04:52 +00:00
David Benjamin b145c8140b Compare r and s sizes to the order, not the degree.
r and s are scalars, not EC coordinates.

Change-Id: I46a20215d3c602559c18c74a1da9a91543ea73ca
Reviewed-on: https://boringssl-review.googlesource.com/2240
Reviewed-by: Adam Langley <agl@google.com>
2014-11-10 23:02:41 +00:00
David Benjamin 1f10d9c8e1 Remove redundant PSK length check.
If psk_len were 0, it would already have been an error earlier. The PSK cipher
suites don't lose the other_secret || psk construction if the PSK happens to be
empty.

Change-Id: I1917236720d0862658562bc8f014cb827ee9aed5
Reviewed-on: https://boringssl-review.googlesource.com/2233
Reviewed-by: Adam Langley <agl@google.com>
2014-11-10 23:02:11 +00:00
David Benjamin 1df112448b Fix memory leak in ssl3_send_client_key_exchange error handling.
Change-Id: I0f0d7a3d4cb6448582ae4945e732611bb9bf5d9f
Reviewed-on: https://boringssl-review.googlesource.com/2231
Reviewed-by: Adam Langley <agl@google.com>
2014-11-10 23:01:07 +00:00
David Benjamin 525a0fe315 Remove client-side support for ServerKeyExchange in the RSA key exchange.
Server-side support was removed in 77a942b7fe,
but client-side support was retained as it appeared NSS supported this.
However, this is not the case: ssl3_HandleServerKeyExchange only allows a
ServerKeyExchange message if hs.ws is in an appropriate state.
ssl3_AuthCertificate only sets it to allow ServerKeyExchange if it is a key
exchange that normally uses it or if is_limited is set. is_limited is only set
for the export cipher suites.

Thus we can safely remove this without waiting on gathering UMA data.

BUG=chromium:400587

Change-Id: I9aefb742dbb2d99c13340ab48017e1ceee04bc2f
Reviewed-on: https://boringssl-review.googlesource.com/2230
Reviewed-by: Adam Langley <agl@google.com>
2014-11-10 23:00:09 +00:00
David Benjamin b4188f0c9d Don't be lenient if the client attempts unsafe renego.
This was added in upstream's 82e610e2cfbbb5fd29c09785b6909a91e606f347. The
commit message cites draft-ietf-tls-renegotiation which was on
draft-ietf-tls-renegotiation-01 at the time. The text in question (6.2 Server
Considerations) is no longer in RFC 5746. The RFC now recommends terminating
the connection which is much simpler.

It also was wrong anyway as it checked s->ctx->options instead of s->options
for SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION.

Removing that block will result in the connection being terminated in
ssl_scan_clienthello_tlsext.

Change-Id: Ie222c78babd3654c5023ad07ac0d8e0adde68698
Reviewed-on: https://boringssl-review.googlesource.com/2235
Reviewed-by: Adam Langley <agl@google.com>
2014-11-10 22:46:17 +00:00
David Benjamin 6867f4854e Remove #if 0'd code documenting an old bug.
It was a bug anyway.

Change-Id: I59d680ce3615a4b24e72a9b6fa16939d83cc15ac
Reviewed-on: https://boringssl-review.googlesource.com/2234
Reviewed-by: Adam Langley <agl@google.com>
2014-11-10 22:45:17 +00:00
David Benjamin d8138e91d0 Keep retransmit window size architecture-independent.
Parameters like these should not change between 32-bit and 64-bit. 64 is also
the value recommended in RFC 6347, section 4.1.2.6. Document those fields while
I'm here.

Change-Id: I8481ee0765ff3d261a96a2e1a53b6ad6695b2d42
Reviewed-on: https://boringssl-review.googlesource.com/2222
Reviewed-by: Adam Langley <agl@google.com>
2014-11-10 22:44:56 +00:00
David Benjamin 60e7992764 Remove DTLSv1_listen.
This was added in http://rt.openssl.org/Ticket/Display.html?id=2033 to support
a mode where a DTLS socket would statelessly perform the ClientHello /
HelloVerifyRequest portion of the handshake, to be handed off to a socket
specific to this peer address.

This is not used by WebRTC or other current consumers. If we need to support
something like this, it would be cleaner to do the listen portion (cookieless
ClientHello + HelloVerifyRequest) externally and then spin up an SSL instance
on receipt of a cookied ClientHello. This would require a slightly more complex
BIO to replay the second ClientHello but would avoid peppering the DTLS
handshake state with a special short-circuiting mode.

Change-Id: I7a413932edfb62f8b9368912a9a0621d4155f1aa
Reviewed-on: https://boringssl-review.googlesource.com/2220
Reviewed-by: Adam Langley <agl@google.com>
2014-11-10 22:39:24 +00:00
David Benjamin b044020f84 Remove i2d_X509_PKEY and d2i_X509_PKEY.
One of them was never implemented upstream or downstream. The other no longer
works in BoringSSL. They're not used within BoringSSL (this still compiles),
even in X509_INFO, and do not appear to be used by consumers. If they were, we
would like to know via a compile failure.

This removes the last consumer within BoringSSL of the ASN.1 parsing macros.

Change-Id: Ifb72b1fcd0a4f7b3e6b081486f8638110872334b
Reviewed-on: https://boringssl-review.googlesource.com/2203
Reviewed-by: Adam Langley <agl@google.com>
2014-11-10 22:28:23 +00:00
Adam Langley 9ed9dae18e Update constant-time operations.
(Based on upstream's 42af669ff2754dfbe1dd55a0ab56664f82284dc4)

Change-Id: I4d3954fea7471e274c626483a0dfb9d7b3250b74
2014-11-10 13:48:30 -08:00
Adam Langley a0b74eb241 aesni-x86_64.pl: make ECB subroutine Windows ABI compliant (RT 3552).
(Imported from upstream's 3e3cc471c2682f5cb40523f3997f75974de1755e.)

Change-Id: I8b6468b104091a609140a035739c09a031de90b4
2014-11-10 13:45:33 -08:00
Adam Langley af6e45bde5 Simplify constant-time RSA padding check.
(Imported form upstream's 455b65dfab0de51c9f67b3c909311770f2b3f801 and
0d6a11a91f4de238ce533c40bd9507fe5d95f288)

Change-Id: Ia195c7fe753cfa3a7f8c91d2d7b2cd40a547be43
2014-11-10 13:45:33 -08:00
Adam Langley a952d96656 Add a few more constant-time utility functions.
Imported from upstream's 9bed73adaa6f834177f29e478d9a2247a6577c04.

Upstream's commit appears to have been based on BoringSSL's commits to
improve the constant-time behaviour of RSA padding checks and thus I've
not tried to import those bits of the change.

Change-Id: I0ea5775b0f1e18741bbbc9f792a6af0d3d2a4caf
2014-11-10 13:45:32 -08:00
Adam Langley 7530e3031d perlasm/x86_64-xlate.pl: handle inter-bank movd.
(Imported from upstream's f7835e1c20836f286f00d6bcc69f154493e01475)

Change-Id: I9ebf2b90a008ff88bfce0a55566f0d0977391c1e
2014-11-10 13:45:32 -08:00
Adam Langley fba236fa88 Omit version for v1 certificates.
When calling X509_set_version to set v1 certificate, that should mean
that the version number field is omitted.

(Imported from upstream's 8c0d19d8577c9a96b65622bfa92d0affd6bbb4ac)

Change-Id: If433fda7b6ccbd899f3379a38581c351cf4a82da
2014-11-10 13:45:32 -08:00
Adam Langley 920e69658e Extra return in check_issued.
(Imported from upstream's b8d687bb561384bb3d52027cbf637fa4852c4225)

Change-Id: I5155b8fa165fbb83a0ba6790571fec28e22cd45c
2014-11-10 13:45:32 -08:00
Adam Langley 0e7f89f96c Remove pkey_ctrl.
It only included ASN1_PKEY_CTRL_DEFAULT_MD_NID and that's unused in
BoringSSL.

Change-Id: Idfcbd0f26f6448ce307c53ddef334f2e63c85a64
2014-11-10 13:45:32 -08:00
Adam Langley 08d6fe2fdb Possibly-uninit variable in pem_lib.c.
Can't really happen, but the flow of control isn't obvious. Add an
initializer.

(Imported from upstream's fa2ae04c40510262d198131c758acd8aa5a9b4ce)

Change-Id: If393687bca9f505b825feffaf2a63895a0ea5b6a
2014-11-10 13:45:32 -08:00
Adam Langley e1cf3f1579 md5-x86_64.pl: work around warning.
(Imported from upstream's 30b7d5e1d83a2f5cb862361c180f7ba1f31a20a5.)

Change-Id: Icbcdb03bcaf8eddda1a7dfecc4f182ce6d93caeb
2014-11-10 13:45:32 -08:00
Adam Langley 3dfbcc1f25 x86[_64] assembly pack: add Silvermont performance data.
(Imported from upstream's 9dd6240201fdd9a9a0ce2aa66df04c174d08cf99)

Change-Id: Ie0f6f876e06ac28c717ec949565f6b0126166b30
2014-11-10 13:45:32 -08:00
Adam Langley b15d8132c7 Constant-time utilities.
Pull constant-time methods out to a separate header, add tests.

(Imported from upstream's 9a9b0c0401cae443f115ff19921d347b20aa396b and
27739e92659d38cdefa21e51b7f52b81a7ac3388)

Change-Id: Id570f5c531aca791112929e6258989f43c8a78d7
2014-11-10 13:45:32 -08:00
Adam Langley 655038e7db ASN1_STRING_to_UTF8 missing initializer.
(Imported from upstream's b85d461cdf92b1d76d903c245ec01fd7398179d8)

Change-Id: I85f620a5a924c3fe73aa394b39ab8ab343c4c7eb
2014-11-10 13:45:32 -08:00
Adam Langley 9398f168f9 Explicitly check for empty ASN.1 strings in d2i_ECPrivateKey.
The old code implicitly relies on the ASN.1 code returning a \0-prefixed
buffer when the buffer length is 0. Change this to verify explicitly
that the ASN.1 string has positive length.

(Imported from upstream's 7f7c05ca638c3cc6d261961fae439cd91e3c1d27)

Change-Id: Icc6c44b874bdcb02374016a36d209830d6162a8a
2014-11-10 13:45:32 -08:00
Adam Langley 9f5a314d35 Automatically generate a missing EC public key.
When d2i_ECPrivateKey reads a private key with a missing (optional)
public key, generate one automatically from the group and private key.

(Imported from upstream's 2083f7c465d07867dd9867b8742bb71c03d1f203)

Change-Id: I9e5090de87cf846ab92e4be5b6bf64e6091d02e4
2014-11-10 13:45:31 -08:00
David Benjamin 1a8b549098 Fix memory leak in calling SSL_clear.
State hanging off the SSL gets freed in two places.

Change-Id: I41a8d2a7cab35f0098396006e1f6380038ec471a
Reviewed-on: https://boringssl-review.googlesource.com/2212
Reviewed-by: Adam Langley <agl@google.com>
2014-11-06 02:03:05 +00:00
David Benjamin 9da9035b50 Add digest_test with tests for all existing EVP_MDs.
Remove the existing md5_test and sha1_test. They now are all covered by
digest_test. For good measure, test the one-shot functions too.

Change-Id: I8e144cc563fb8817144e26cbd2e10c15642464ba
Reviewed-on: https://boringssl-review.googlesource.com/2211
Reviewed-by: Adam Langley <agl@google.com>
2014-11-06 01:49:03 +00:00
David Benjamin 23586e1e0e Test insertion of duplicates in pqueue_test.
Also add a few other assertions.

Change-Id: Iae0c65802f4d05c7585e2790be5295f478e1f614
Reviewed-on: https://boringssl-review.googlesource.com/2210
Reviewed-by: Adam Langley <agl@google.com>
2014-11-06 01:46:57 +00:00
David Benjamin a85093f5bb Fix error handling in X509_PURPOSE_add and X509_TRUST_add.
Two leaks can happen: if idx is -1, the newly allocated entry may not be freed.
Also, for X509_PURPOSE_add, if only one BUF_strdup succeeds, it will leak.

Restructure both so that the allocations happen ahead of time and are properly
cleaned up. This avoids leaving an existing entry in a half-broken state.

Found (sort of) by scan-build; because of all the indirections and DYNAMIC
flags, it doesn't actually realize the leak's been fixed.

Change-Id: I5521889bd14e007b3f62b6a4906d7c346698b48c
Reviewed-on: https://boringssl-review.googlesource.com/2209
Reviewed-by: Adam Langley <agl@google.com>
2014-11-06 01:44:43 +00:00
David Benjamin ab2815eaff Fix leak in X509V3_EXT_add on error.
If it fails to be added to the list, the input should be freed. Found (sort of)
by scan-build; because of all the indirections and DYNAMIC flags, it doesn't
actually realize the leak's been fixed.

Change-Id: Idca10964e1ffb2ace1cea7f88d94693205d70d5b
Reviewed-on: https://boringssl-review.googlesource.com/2208
Reviewed-by: Adam Langley <agl@google.com>
2014-11-06 01:40:58 +00:00
David Benjamin 4aa86f1cdf Don't leak in err_set_error_data if error queue is empty.
Caught by clang scan-build.

Change-Id: I16496bfc469e809348199057adfb24c33c426ccb
Reviewed-on: https://boringssl-review.googlesource.com/2207
Reviewed-by: Adam Langley <agl@google.com>
2014-11-06 01:35:26 +00:00
David Benjamin e2793a7189 Remove redundant s->s3 check.
s->s3 is never NULL if an ssl3_* function is called, and we'll crash later
anyway. (This also makes scan-build stop believing it can be NULL.)

Change-Id: Ibf8433bd4d945f9bf5416d72946102a9e50d2787
Reviewed-on: https://boringssl-review.googlesource.com/2206
Reviewed-by: Adam Langley <agl@google.com>
2014-11-06 01:34:52 +00:00
David Benjamin 9ecafa5c78 Shush some dead assignments.
Appease clang scan-build a bit. I'm not sure it's actually worth silencing all
of them because some of them look like preserving invariants between local
variables, but some are clearly pointless or can be restructured slightly.

Change-Id: I0bc81e2589bb402ff3ef0182d7a8921e31b85052
Reviewed-on: https://boringssl-review.googlesource.com/2205
Reviewed-by: Adam Langley <agl@google.com>
2014-11-06 01:34:33 +00:00
David Benjamin f2b32a2de2 Switch ssl3_send_channel_id to BN_bn2bin_padded.
Check the return value while we're here. This avoids some arithmetic and
appease scan-build's dead assignment flagger.

Change-Id: If3615076e091eb44b9e3e9d50cd64f80e645337e
Reviewed-on: https://boringssl-review.googlesource.com/2204
Reviewed-by: Adam Langley <agl@google.com>
2014-11-06 01:32:27 +00:00
David Benjamin 626fb8b75c Fix leaks in and de-macro X509_PKEY_new.
Caught by clang scan-build.

Change-Id: I075ae0423ec72493f21608ab5704e2984ca3e86c
Reviewed-on: https://boringssl-review.googlesource.com/2202
Reviewed-by: Adam Langley <agl@google.com>
2014-11-06 01:30:59 +00:00
David Benjamin 74072ac84c Fix a2i_ASN1_* leak on failure.
Caught by clang scan-build.

Change-Id: I1097848052026361e24fd1202cc0c831c3f83e49
Reviewed-on: https://boringssl-review.googlesource.com/2201
Reviewed-by: Adam Langley <agl@google.com>
2014-11-06 01:29:59 +00:00
David Benjamin 3f383908e2 Properly clean up on ssl_cert_dup failure.
Caught by scan-build.

Change-Id: I7c09b176d6a9e5d4fcd6e4fba184ac0679983cff
Reviewed-on: https://boringssl-review.googlesource.com/2200
Reviewed-by: Adam Langley <agl@google.com>
2014-11-06 01:28:30 +00:00
Adam Langley 25cb99c149 crypto/bn/asm/rsaz-*.pl: allow spaces in Perl path name.
(Imported from upstream's ef908777218bd4a362dbe9cebb8e18fa8ab384cf.)

Change-Id: Id9b288d230cc9d8ab308690a18e687e2132e3293
Reviewed-on: https://boringssl-review.googlesource.com/2168
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2014-11-05 21:26:15 +00:00
Adam Langley 404e6e64d0 Small tweak to ec_GFp_simple_points_make_affine.
(Imported from upstream's 267e6f3cc0ef78dea4e5cf93907a71556a45f008)

Change-Id: I99cfd0196b9625449c50494562c44f57f09fed17
Reviewed-on: https://boringssl-review.googlesource.com/2167
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2014-11-05 21:26:04 +00:00
189 changed files with 29043 additions and 29466 deletions
+9 -2
View File
@@ -3,8 +3,8 @@ cmake_minimum_required (VERSION 2.8.8)
project (BoringSSL)
if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -ggdb -std=c89")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -ggdb -std=c++0x")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wshadow -Werror -ggdb -std=c89")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wshadow -Werror -ggdb -std=c++0x")
elseif(MSVC)
# Disable warnings for implicit integer narrowing.
set(CMAKE_C_FLAGS "/wd4267")
@@ -36,6 +36,13 @@ else()
message(FATAL_ERROR "Unknown processor:" ${CMAKE_SYSTEM_PROCESSOR})
endif()
if (${ARCH} STREQUAL "x86" AND APPLE)
# With CMake 2.8.x, ${CMAKE_SYSTEM_PROCESSOR} evalutes to i386 on OS X,
# but clang defaults to 64-bit builds on OS X unless otherwise told.
# Set ARCH to x86_64 so clang and CMake agree. This is fixed in CMake 3.
set(ARCH "x86_64")
endif()
add_subdirectory(crypto)
add_subdirectory(ssl)
add_subdirectory(ssl/test)
+4
View File
@@ -0,0 +1,4 @@
# This file is used by gcl to get repository specific information.
GERRIT_HOST: True
GERRIT_PORT: True
CODE_REVIEW_SERVER: https://boringssl-review.googlesource.com
+10
View File
@@ -105,6 +105,7 @@ add_subdirectory(hmac)
# Level 3
add_subdirectory(evp)
add_subdirectory(hkdf)
add_subdirectory(pem)
add_subdirectory(x509)
add_subdirectory(x509v3)
@@ -160,11 +161,20 @@ add_library(
$<TARGET_OBJECTS:ecdsa>
$<TARGET_OBJECTS:hmac>
$<TARGET_OBJECTS:evp>
$<TARGET_OBJECTS:hkdf>
$<TARGET_OBJECTS:pem>
$<TARGET_OBJECTS:x509>
$<TARGET_OBJECTS:x509v3>
$<TARGET_OBJECTS:pkcs8>
)
add_executable(
constant_time_test
constant_time_test.c
)
target_link_libraries(constant_time_test crypto)
perlasm(cpu-x86_64-asm.${ASM_EXT} cpu-x86_64-asm.pl)
perlasm(cpu-x86-asm.${ASM_EXT} cpu-x86-asm.pl)
+27 -25
View File
@@ -584,6 +584,16 @@ $code.=<<___;
.type aesni_ecb_encrypt,\@function,5
.align 16
aesni_ecb_encrypt:
___
$code.=<<___ if ($win64);
lea -0x58(%rsp),%rsp
movaps %xmm6,(%rsp)
movaps %xmm7,0x10(%rsp)
movaps %xmm8,0x20(%rsp)
movaps %xmm9,0x30(%rsp)
.Lecb_enc_body:
___
$code.=<<___;
and \$-16,$len
jz .Lecb_ret
@@ -862,6 +872,16 @@ $code.=<<___;
movups $inout5,0x50($out)
.Lecb_ret:
___
$code.=<<___ if ($win64);
movaps (%rsp),%xmm6
movaps 0x10(%rsp),%xmm7
movaps 0x20(%rsp),%xmm8
movaps 0x30(%rsp),%xmm9
lea 0x58(%rsp),%rsp
.Lecb_enc_ret:
___
$code.=<<___;
ret
.size aesni_ecb_encrypt,.-aesni_ecb_encrypt
___
@@ -3225,28 +3245,9 @@ $code.=<<___;
.extern __imp_RtlVirtualUnwind
___
$code.=<<___ if ($PREFIX eq "aesni");
.type ecb_se_handler,\@abi-omnipotent
.type ecb_ccm64_se_handler,\@abi-omnipotent
.align 16
ecb_se_handler:
push %rsi
push %rdi
push %rbx
push %rbp
push %r12
push %r13
push %r14
push %r15
pushfq
sub \$64,%rsp
mov 152($context),%rax # pull context->Rsp
jmp .Lcommon_seh_tail
.size ecb_se_handler,.-ecb_se_handler
.type ccm64_se_handler,\@abi-omnipotent
.align 16
ccm64_se_handler:
ecb_ccm64_se_handler:
push %rsi
push %rdi
push %rbx
@@ -3283,7 +3284,7 @@ ccm64_se_handler:
lea 0x58(%rax),%rax # adjust stack pointer
jmp .Lcommon_seh_tail
.size ccm64_se_handler,.-ccm64_se_handler
.size ecb_ccm64_se_handler,.-ecb_ccm64_se_handler
.type ctr_xts_se_handler,\@abi-omnipotent
.align 16
@@ -3457,14 +3458,15 @@ ___
$code.=<<___ if ($PREFIX eq "aesni");
.LSEH_info_ecb:
.byte 9,0,0,0
.rva ecb_se_handler
.rva ecb_ccm64_se_handler
.rva .Lecb_enc_body,.Lecb_enc_ret # HandlerData[]
.LSEH_info_ccm64_enc:
.byte 9,0,0,0
.rva ccm64_se_handler
.rva ecb_ccm64_se_handler
.rva .Lccm64_enc_body,.Lccm64_enc_ret # HandlerData[]
.LSEH_info_ccm64_dec:
.byte 9,0,0,0
.rva ccm64_se_handler
.rva ecb_ccm64_se_handler
.rva .Lccm64_dec_body,.Lccm64_dec_ret # HandlerData[]
.LSEH_info_ctr32:
.byte 9,0,0,0
+2
View File
@@ -40,6 +40,7 @@
# Core 2 9.30 8.69 +7%
# Nehalem(**) 7.63 6.88 +11%
# Atom 17.1 16.4 +4%
# Silvermont - 12.9
#
# (*) Comparison is not completely fair, because "this" is ECB,
# i.e. no extra processing such as counter values calculation
@@ -78,6 +79,7 @@
# Core 2 9.98
# Nehalem 7.80
# Atom 17.9
# Silvermont 14.0
#
# November 2011.
#
+1
View File
@@ -30,6 +30,7 @@
# Core 2(**) 28.1/41.4/18.3 21.9/25.2(***)
# Nehalem 27.9/40.4/18.1 10.2/11.9
# Atom 70.7/92.1/60.1 61.1/75.4(***)
# Silvermont 45.4/62.9/24.1 49.2/61.1(***)
#
# (*) "Hyper-threading" in the context refers rather to cache shared
# among multiple cores, than to specifically Intel HTT. As vast
+1
View File
@@ -30,6 +30,7 @@
# Core 2(**) 29.6/41.1/14.3 21.9/25.2(***)
# 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(***)
#
# (*) "Hyper-threading" in the context refers rather to cache shared
# among multiple cores, than to specifically Intel HTT. As vast
+1 -1
View File
@@ -111,7 +111,7 @@ int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value)
}
/* Returns 0 if they are equal, != 0 otherwise. */
int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b)
int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
{
int result = -1;
+2 -1
View File
@@ -159,7 +159,6 @@ int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
if (sp == NULL)
{
OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE);
if (s != NULL) OPENSSL_free(s);
goto err;
}
s=sp;
@@ -200,6 +199,8 @@ err:
err_sl:
OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_ENUMERATED, ASN1_R_SHORT_LINE);
}
if (s != NULL)
OPENSSL_free(s);
return(ret);
}
+2 -1
View File
@@ -163,7 +163,6 @@ int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
if (sp == NULL)
{
OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
if (s != NULL) OPENSSL_free(s);
goto err;
}
s=sp;
@@ -204,6 +203,8 @@ err:
err_sl:
OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_INTEGER, ASN1_R_SHORT_LINE);
}
if (s != NULL)
OPENSSL_free(s);
return(ret);
}
+2 -1
View File
@@ -157,7 +157,6 @@ int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
if (sp == NULL)
{
OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_STRING, ERR_R_MALLOC_FAILURE);
if (s != NULL) OPENSSL_free(s);
goto err;
}
s=sp;
@@ -198,6 +197,8 @@ err:
err_sl:
OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_STRING, ASN1_R_SHORT_LINE);
}
if (s != NULL)
OPENSSL_free(s);
return(ret);
}
+2 -3
View File
@@ -599,14 +599,13 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
{
int flags, aclass;
int ret;
const unsigned char *p, *q;
const unsigned char *p;
if (!val)
return 0;
flags = tt->flags;
aclass = flags & ASN1_TFLG_TAG_CLASS;
p = *in;
q = p;
if (flags & ASN1_TFLG_SK_MASK)
{
@@ -663,7 +662,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
while(len > 0)
{
ASN1_VALUE *skfield;
q = p;
const unsigned char *q = p;
/* See if EOC found */
if (asn1_check_eoc(&p, len))
{
+7 -1
View File
@@ -126,7 +126,13 @@ static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
int utype, char *free_cont, const ASN1_ITEM *it)
{
BIGNUM *bn;
if(!*pval) bn_new(pval, it);
if(!*pval)
{
if (!bn_new(pval, it))
{
return 0;
}
}
bn = (BIGNUM *)*pval;
if(!BN_bin2bn(cont, len, bn)) {
bn_free(pval, it);
+4
View File
@@ -22,6 +22,10 @@ const ERR_STRING_DATA BIO_error_string_data[] = {
{ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_new, 0), "BIO_new"},
{ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_new_file, 0), "BIO_new_file"},
{ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_new_mem_buf, 0), "BIO_new_mem_buf"},
{ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_zero_copy_get_read_buf, 0), "BIO_zero_copy_get_read_buf"},
{ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_zero_copy_get_read_buf_done, 0), "BIO_zero_copy_get_read_buf_done"},
{ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_zero_copy_get_write_buf, 0), "BIO_zero_copy_get_write_buf"},
{ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_zero_copy_get_write_buf_done, 0), "BIO_zero_copy_get_write_buf_done"},
{ERR_PACK(ERR_LIB_BIO, BIO_F_bio_ctrl, 0), "bio_ctrl"},
{ERR_PACK(ERR_LIB_BIO, BIO_F_bio_io, 0), "bio_io"},
{ERR_PACK(ERR_LIB_BIO, BIO_F_bio_ip_and_port_to_socket_and_addr, 0), "bio_ip_and_port_to_socket_and_addr"},
+154
View File
@@ -35,6 +35,7 @@
#include <openssl/crypto.h>
#include <openssl/err.h>
#define MIN(a, b) ((a < b) ? a : b)
#if !defined(OPENSSL_WINDOWS)
static int closesocket(int sock) {
@@ -119,6 +120,155 @@ static int test_socket_connect(void) {
return 1;
}
/* bio_read_zero_copy_wrapper is a wrapper around the zero-copy APIs to make
* testing easier. */
static size_t bio_read_zero_copy_wrapper(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 = 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;
}
/* bio_write_zero_copy_wrapper is a wrapper around the zero-copy APIs to make
* testing easier. */
static size_t bio_write_zero_copy_wrapper(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 = 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 int test_zero_copy_bio_pairs(void) {
/* Test read and write, especially triggering the ring buffer wrap-around.*/
BIO* bio1;
BIO* bio2;
size_t i, j;
uint8_t bio1_application_send_buffer[1024];
uint8_t bio2_application_recv_buffer[1024];
size_t total_read = 0;
size_t total_write = 0;
uint8_t* write_buf;
size_t write_buf_offset;
size_t available_bytes;
size_t bytes_left;
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 (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 (i = 0; i < sizeof(kLengths) / sizeof(kLengths[0]); i++) {
for (j = 0; j < sizeof(kPartialLengths) / sizeof(kPartialLengths[0]); j++) {
total_write = 0;
total_read = 0;
BIO_new_bio_pair(&bio1, kBufferSize, &bio2, kBufferSize);
total_write += bio_write_zero_copy_wrapper(
bio1, bio1_application_send_buffer, kLengths[i]);
/* This tests interleaved read/write calls. Do a read between zero copy
* write calls. */
if (!BIO_zero_copy_get_write_buf(bio1, &write_buf, &write_buf_offset,
&available_bytes)) {
return 0;
}
/* 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 = 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 += bio_write_zero_copy_wrapper(
bio1, bio1_application_send_buffer + total_write,
kPartialLengths[j] - interleaved_write_len);
/* Drain the rest. */
bytes_left = BIO_pending(bio2);
total_read += bio_read_zero_copy_wrapper(
bio2, bio2_application_recv_buffer + total_read, bytes_left);
BIO_free(bio1);
BIO_free(bio2);
if (total_read != total_write) {
fprintf(stderr, "Lengths not equal in round (%u, %u)\n", (unsigned)i,
(unsigned)j);
return 0;
}
if (total_read > kLengths[i] + kPartialLengths[j]) {
fprintf(stderr, "Bad lengths in round (%u, %u)\n", (unsigned)i,
(unsigned)j);
return 0;
}
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 0;
}
}
}
return 1;
}
static int test_printf(void) {
/* Test a short output, a very long one, and various sizes around
* 256 (the size of the buffer) to ensure edge cases are correct. */
@@ -201,6 +351,10 @@ int main(void) {
return 1;
}
if (!test_zero_copy_bio_pairs()) {
return 1;
}
printf("PASS\n");
return 0;
}
+4 -3
View File
@@ -81,9 +81,10 @@ static char to_char(uint8_t b) {
return b;
}
/* hexdump adds |len| bytes of |data| to the current hex dump described by
/* hexdump_write adds |len| bytes of |data| to the current hex dump described by
* |ctx|. */
static int hexdump(struct hexdump_ctx *ctx, const uint8_t *data, size_t len) {
static int hexdump_write(struct hexdump_ctx *ctx, const uint8_t *data,
size_t len) {
size_t i;
char buf[10];
unsigned l;
@@ -182,7 +183,7 @@ int BIO_hexdump(BIO *bio, const uint8_t *data, size_t len, unsigned indent) {
ctx.bio = bio;
ctx.indent = indent;
if (!hexdump(&ctx, data, len) || !finish(&ctx)) {
if (!hexdump_write(&ctx, data, len) || !finish(&ctx)) {
return 0;
}
+343 -72
View File
@@ -70,7 +70,13 @@ struct bio_bio_st {
size_t len; /* valid iff buf != NULL; 0 if peer == NULL */
size_t offset; /* valid iff buf != NULL; 0 if len == 0 */
size_t size;
char *buf; /* "size" elements (if != NULL) */
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
@@ -85,11 +91,9 @@ static int bio_new(BIO *bio) {
if (b == NULL) {
return 0;
}
memset(b, 0, sizeof(struct bio_bio_st));
b->peer = NULL;
b->size = 17 * 1024; /* enough for one TLS record (just a default) */
b->buf = NULL;
bio->ptr = b;
return 1;
}
@@ -140,7 +144,7 @@ static int bio_free(BIO *bio) {
bio_destroy_pair(bio);
}
if (b->buf != NULL) {
if (b->buf != NULL && !b->buf_externally_allocated) {
OPENSSL_free(b->buf);
}
@@ -149,6 +153,268 @@ static int bio_free(BIO *bio) {
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_zero_copy_get_read_buf, BIO_R_UNINITIALIZED);
return 0;
}
b = bio->ptr;
if (!b || !b->peer) {
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf,
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_zero_copy_get_read_buf,
BIO_R_UNSUPPORTED_METHOD);
return 0;
}
if (peer_b->zero_copy_read_lock) {
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf, 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_zero_copy_get_read_buf_done,
BIO_R_UNINITIALIZED);
return 0;
}
b = bio->ptr;
if (!b || !b->peer) {
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done,
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_zero_copy_get_read_buf_done,
BIO_R_UNSUPPORTED_METHOD);
return 0;
}
if (!peer_b->zero_copy_read_lock) {
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done,
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_zero_copy_get_read_buf_done,
BIO_R_INVALID_ARGUMENT);
return 0;
}
peer_b->len -= bytes_read;
assert(peer_b->len >= 0);
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_zero_copy_get_write_buf, BIO_R_UNINITIALIZED);
return 0;
}
b = bio->ptr;
if (!b || !b->buf || !b->peer) {
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf,
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_zero_copy_get_write_buf,
BIO_R_UNSUPPORTED_METHOD);
return 0;
}
assert(b->buf != NULL);
if (b->zero_copy_write_lock) {
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf, BIO_R_INVALID_ARGUMENT);
return 0;
}
b->request = 0;
if (b->closed) {
/* Bio is already closed. */
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf, 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_zero_copy_get_write_buf_done,
BIO_R_UNINITIALIZED);
return 0;
}
b = bio->ptr;
if (!b || !b->buf || !b->peer) {
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done,
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_zero_copy_get_write_buf_done,
BIO_R_UNSUPPORTED_METHOD);
return 0;
}
b->request = 0;
if (b->closed) {
/* BIO is already closed. */
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done, BIO_R_BROKEN_PIPE);
return 0;
}
if (!b->zero_copy_write_lock) {
OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done,
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_zero_copy_get_write_buf_done,
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;
@@ -169,7 +435,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) {
if (buf == NULL || size == 0 || peer_b->zero_copy_read_lock) {
return 0;
}
@@ -214,7 +480,10 @@ static int bio_read(BIO *bio, char *buf, int size_) {
memcpy(buf, peer_b->buf + peer_b->offset, chunk);
peer_b->len -= chunk;
if (peer_b->len) {
/* 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) {
peer_b->offset += chunk;
assert(peer_b->offset <= peer_b->size);
if (peer_b->offset == peer_b->size) {
@@ -248,6 +517,10 @@ 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 */
@@ -304,7 +577,9 @@ static int bio_write(BIO *bio, const char *buf, int num_) {
return num;
}
static int bio_make_pair(BIO *bio1, BIO *bio2) {
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) {
struct bio_bio_st *b1, *b2;
assert(bio1 != NULL);
@@ -318,21 +593,42 @@ 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) {
b1->buf = OPENSSL_malloc(b1->size);
if (b1->buf == NULL) {
OPENSSL_PUT_ERROR(BIO, bio_make_pair, ERR_R_MALLOC_FAILURE);
return 0;
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, bio_make_pair, ERR_R_MALLOC_FAILURE);
return 0;
}
} else {
b1->buf = ext_writebuf1;
b1->buf_externally_allocated = 1;
}
b1->len = 0;
b1->offset = 0;
}
if (b2->buf == NULL) {
b2->buf = OPENSSL_malloc(b2->size);
if (b2->buf == NULL) {
OPENSSL_PUT_ERROR(BIO, bio_make_pair, ERR_R_MALLOC_FAILURE);
return 0;
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, bio_make_pair, ERR_R_MALLOC_FAILURE);
return 0;
}
} else {
b2->buf = ext_writebuf2;
b2->buf_externally_allocated = 1;
}
b2->len = 0;
b2->offset = 0;
@@ -341,9 +637,13 @@ 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;
@@ -360,27 +660,6 @@ static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) {
switch (cmd) {
/* specific CTRL codes */
case BIO_C_SET_BUFF_SIZE:
if (b->peer) {
OPENSSL_PUT_ERROR(BIO, bio_ctrl, BIO_R_IN_USE);
ret = 0;
} else if (num == 0) {
OPENSSL_PUT_ERROR(BIO, bio_ctrl, BIO_R_INVALID_ARGUMENT);
ret = 0;
} else {
size_t new_size = num;
if (b->size != new_size) {
if (b->buf) {
OPENSSL_free(b->buf);
b->buf = NULL;
}
b->size = new_size;
}
ret = 1;
}
break;
case BIO_C_GET_WRITE_BUF_SIZE:
ret = (long)b->size;
break;
@@ -419,14 +698,6 @@ static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) {
/* standard CTRL codes follow */
case BIO_CTRL_RESET:
if (b->buf != NULL) {
b->len = 0;
b->offset = 0;
}
ret = 0;
break;
case BIO_CTRL_GET_CLOSE:
ret = bio->shutdown;
break;
@@ -478,35 +749,43 @@ static int bio_puts(BIO *bio, const char *str) {
return bio_write(bio, str, strlen(str));
}
int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1, BIO **bio2_p,
size_t writebuf2) {
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 */
};
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;
long r;
int ret = 0;
bio1 = BIO_new(BIO_s_bio());
/* 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());
bio2 = BIO_new(bio_s_bio());
if (bio2 == NULL) {
goto err;
}
if (writebuf1) {
r = BIO_set_write_buffer_size(bio1, writebuf1);
if (!r) {
goto err;
}
}
if (writebuf2) {
r = BIO_set_write_buffer_size(bio2, writebuf2);
if (!r) {
goto err;
}
}
if (!bio_make_pair(bio1, bio2)) {
if (!bio_make_pair(bio1, bio2, writebuf1_len, ext_writebuf1, writebuf2_len,
ext_writebuf2)) {
goto err;
}
ret = 1;
@@ -528,14 +807,6 @@ err:
return ret;
}
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 */
};
const BIO_METHOD *BIO_s_bio(void) { return &methods_biop; }
size_t BIO_ctrl_get_read_request(BIO *bio) {
return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
}
+1 -1
View File
@@ -99,7 +99,7 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([3-9])\.([0-
$addx = ($ver>=3.03);
}
open OUT,"| $^X $xlate $flavour $output";
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT = *OUT;
if ($avx>1) {{{
+1 -1
View File
@@ -95,7 +95,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
open OUT,"| $^X $xlate $flavour $output";
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT=*OUT;
if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
+27 -65
View File
@@ -292,80 +292,45 @@ BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) {
/* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0)
*/
#if 0
/* original macros are kept for reference purposes */
#define mul_add_c(a, b, c0, c1, c2) \
{ \
BN_ULONG ta = (a), tb = (b); \
t1 = ta * tb; \
t2 = BN_UMULT_HIGH(ta, tb); \
c0 += t1; \
t2 += (c0 < t1) ? 1 : 0; \
c1 += t2; \
c2 += (c1 < t2) ? 1 : 0; \
}
#define mul_add_c2(a, b, c0, c1, c2) \
{ \
BN_ULONG ta = (a), tb = (b), t0; \
t1 = BN_UMULT_HIGH(ta, tb); \
t0 = ta * tb; \
t2 = t1 + t1; \
c2 += (t2 < t1) ? 1 : 0; \
t1 = t0 + t0; \
t2 += (t1 < t0) ? 1 : 0; \
c0 += t1; \
t2 += (c0 < t1) ? 1 : 0; \
c1 += t2; \
c2 += (c1 < t2) ? 1 : 0; \
}
#else
#define mul_add_c(a, b, c0, c1, c2) \
do { \
/* Keep in mind that carrying into high part of multiplication result can not
* overflow, because it cannot be all-ones. */
#define mul_add_c(a, b, c0, c1, c2) \
do { \
BN_ULONG t1, t2; \
asm("mulq %3" : "=a"(t1), "=d"(t2) : "a"(a), "m"(b) : "cc"); \
asm("addq %2,%0; adcq %3,%1" \
: "+r"(c0), "+d"(t2) \
: "a"(t1), "g"(0) \
: "cc"); \
asm("addq %2,%0; adcq %3,%1" \
: "+r"(c1), "+r"(c2) \
: "d"(t2), "g"(0) \
: "cc"); \
asm("addq %3,%0; adcq %4,%1; adcq %5,%2" \
: "+r"(c0), "+r"(c1), "+r"(c2) \
: "r"(t1), "r"(t2), "g"(0) \
: "cc"); \
} while (0)
#define sqr_add_c(a, i, c0, c1, c2) \
do { \
#define sqr_add_c(a, i, c0, c1, c2) \
do { \
BN_ULONG t1, t2; \
asm("mulq %2" : "=a"(t1), "=d"(t2) : "a"(a[i]) : "cc"); \
asm("addq %2,%0; adcq %3,%1" \
: "+r"(c0), "+d"(t2) \
: "a"(t1), "g"(0) \
: "cc"); \
asm("addq %2,%0; adcq %3,%1" \
: "+r"(c1), "+r"(c2) \
: "d"(t2), "g"(0) \
: "cc"); \
asm("addq %3,%0; adcq %4,%1; adcq %5,%2" \
: "+r"(c0), "+r"(c1), "+r"(c2) \
: "r"(t1), "r"(t2), "g"(0) \
: "cc"); \
} while (0)
#define mul_add_c2(a, b, c0, c1, c2) \
do { \
#define mul_add_c2(a, b, c0, c1, c2) \
do { \
BN_ULONG t1, t2; \
asm("mulq %3" : "=a"(t1), "=d"(t2) : "a"(a), "m"(b) : "cc"); \
asm("addq %0,%0; adcq %2,%1" : "+d"(t2), "+r"(c2) : "g"(0) : "cc"); \
asm("addq %0,%0; adcq %2,%1" : "+a"(t1), "+d"(t2) : "g"(0) : "cc"); \
asm("addq %2,%0; adcq %3,%1" \
: "+r"(c0), "+d"(t2) \
: "a"(t1), "g"(0) \
: "cc"); \
asm("addq %2,%0; adcq %3,%1" \
: "+r"(c1), "+r"(c2) \
: "d"(t2), "g"(0) \
: "cc"); \
asm("addq %3,%0; adcq %4,%1; adcq %5,%2" \
: "+r"(c0), "+r"(c1), "+r"(c2) \
: "r"(t1), "r"(t2), "g"(0) \
: "cc"); \
asm("addq %3,%0; adcq %4,%1; adcq %5,%2" \
: "+r"(c0), "+r"(c1), "+r"(c2) \
: "r"(t1), "r"(t2), "g"(0) \
: "cc"); \
} while (0)
#endif
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
BN_ULONG t1, t2;
BN_ULONG c1, c2, c3;
c1 = 0;
@@ -468,7 +433,6 @@ void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
}
void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
BN_ULONG t1, t2;
BN_ULONG c1, c2, c3;
c1 = 0;
@@ -507,7 +471,6 @@ void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
}
void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) {
BN_ULONG t1, t2;
BN_ULONG c1, c2, c3;
c1 = 0;
@@ -582,7 +545,6 @@ void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) {
}
void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) {
BN_ULONG t1, t2;
BN_ULONG c1, c2, c3;
c1 = 0;
+79 -21
View File
@@ -653,40 +653,98 @@ int test_mul(BIO *bp) {
}
int test_sqr(BIO *bp, BN_CTX *ctx) {
BIGNUM a, c, d, e;
int i;
BIGNUM *a, *c, *d, *e;
int i, ret = 0;
BN_init(&a);
BN_init(&c);
BN_init(&d);
BN_init(&e);
a = BN_new();
c = BN_new();
d = BN_new();
e = BN_new();
if (a == NULL || c == NULL || d == NULL || e == NULL) {
goto err;
}
for (i = 0; i < num0; i++) {
BN_rand(&a, 40 + i * 10, 0, 0);
a.neg = rand_neg();
BN_sqr(&c, &a, ctx);
BN_rand(a, 40 + i * 10, 0, 0);
a->neg = rand_neg();
BN_sqr(c, a, ctx);
if (bp != NULL) {
if (!results) {
BN_print(bp, &a);
BN_print(bp, a);
BIO_puts(bp, " * ");
BN_print(bp, &a);
BN_print(bp, a);
BIO_puts(bp, " - ");
}
BN_print(bp, &c);
BN_print(bp, c);
BIO_puts(bp, "\n");
}
BN_div(&d, &e, &c, &a, ctx);
BN_sub(&d, &d, &a);
if (!BN_is_zero(&d) || !BN_is_zero(&e)) {
BN_div(d, e, c, a, ctx);
BN_sub(d, d, a);
if (!BN_is_zero(d) || !BN_is_zero(e)) {
fprintf(stderr, "Square test failed!\n");
return 0;
goto err;
}
}
BN_free(&a);
BN_free(&c);
BN_free(&d);
BN_free(&e);
return (1);
/* Regression test for a BN_sqr overflow bug. */
BN_hex2bn(&a,
"80000000000000008000000000000001FFFFFFFFFFFFFFFE0000000000000000");
BN_sqr(c, a, ctx);
if (bp != NULL) {
if (!results) {
BN_print(bp, a);
BIO_puts(bp, " * ");
BN_print(bp, a);
BIO_puts(bp, " - ");
}
BN_print(bp, c);
BIO_puts(bp, "\n");
}
BN_mul(d, a, a, ctx);
if (BN_cmp(c, d)) {
fprintf(stderr,
"Square test failed: BN_sqr and BN_mul produce "
"different results!\n");
goto err;
}
/* Regression test for a BN_sqr overflow bug. */
BN_hex2bn(&a,
"80000000000000000000000080000001FFFFFFFE000000000000000000000000");
BN_sqr(c, a, ctx);
if (bp != NULL) {
if (!results) {
BN_print(bp, a);
BIO_puts(bp, " * ");
BN_print(bp, a);
BIO_puts(bp, " - ");
}
BN_print(bp, c);
BIO_puts(bp, "\n");
}
BN_mul(d, a, a, ctx);
if (BN_cmp(c, d)) {
fprintf(stderr,
"Square test failed: BN_sqr and BN_mul produce "
"different results!\n");
goto err;
}
ret = 1;
err:
if (a != NULL) {
BN_free(a);
}
if (c != NULL) {
BN_free(c);
}
if (d != NULL) {
BN_free(d);
}
if (e != NULL) {
BN_free(e);
}
return ret;
}
+8 -9
View File
@@ -416,7 +416,7 @@ err:
static int mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx) {
int i, j, bits, ret = 0, wstart, wend, window, wvalue;
int i, j, bits, ret = 0, wstart, window;
int start = 1;
BIGNUM *aa;
/* Table of variables obtained from 'ctx' */
@@ -485,15 +485,16 @@ static int mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
start = 1; /* This is used to avoid multiplication etc
* when there is only the value '1' in the
* buffer. */
wvalue = 0; /* The 'value' of the window */
wstart = bits - 1; /* The top bit of the window */
wend = 0; /* The bottom bit of the window */
if (!BN_one(r)) {
goto err;
}
for (;;) {
int wvalue; /* The 'value' of the window */
int wend; /* The bottom bit of the window */
if (BN_is_bit_set(p, wstart) == 0) {
if (!start) {
if (!BN_mod_mul_reciprocal(r, r, r, &recp, ctx)) {
@@ -542,7 +543,6 @@ static int mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
/* move the 'window' down further */
wstart -= wend + 1;
wvalue = 0;
start = 0;
if (wstart < 0) {
break;
@@ -601,7 +601,7 @@ int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) {
int i, j, bits, ret = 0, wstart, wend, window, wvalue;
int i, j, bits, ret = 0, wstart, window;
int start = 1;
BIGNUM *d, *r;
const BIGNUM *aa;
@@ -680,9 +680,7 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
start = 1; /* This is used to avoid multiplication etc
* when there is only the value '1' in the
* buffer. */
wvalue = 0; /* The 'value' of the window */
wstart = bits - 1; /* The top bit of the window */
wend = 0; /* The bottom bit of the window */
j = m->top; /* borrow j */
if (m->d[j - 1] & (((BN_ULONG)1) << (BN_BITS2 - 1))) {
@@ -701,6 +699,9 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
}
for (;;) {
int wvalue; /* The 'value' of the window */
int wend; /* The bottom bit of the window */
if (BN_is_bit_set(p, wstart) == 0) {
if (!start) {
if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
@@ -716,7 +717,6 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
/* We now have wstart on a 'set' bit, we now need to work out how bit a
* window to do. To do this we need to scan forward until the last set bit
* before the end of the window */
j = wstart;
wvalue = 1;
wend = 0;
for (i = 1; i < window; i++) {
@@ -748,7 +748,6 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
/* move the 'window' down further */
wstart -= wend + 1;
wvalue = 0;
start = 0;
if (wstart < 0) {
break;
+155 -154
View File
@@ -659,175 +659,194 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
/* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */
#ifdef BN_LLONG
#define mul_add_c(a, b, c0, c1, c2) \
t = (BN_ULLONG)a * b; \
t1 = (BN_ULONG)Lw(t); \
t2 = (BN_ULONG)Hw(t); \
c0 = (c0 + t1) & BN_MASK2; \
if ((c0) < t1) \
t2++; \
c1 = (c1 + t2) & BN_MASK2; \
if ((c1) < t2) \
c2++;
#define mul_add_c2(a, b, c0, c1, c2) \
t = (BN_ULLONG)a * b; \
tt = (t + t) & BN_MASK; \
if (tt < t) \
c2++; \
t1 = (BN_ULONG)Lw(tt); \
t2 = (BN_ULONG)Hw(tt); \
c0 = (c0 + t1) & BN_MASK2; \
if ((c0 < t1) && (((++t2) & BN_MASK2) == 0)) \
c2++; \
c1 = (c1 + t2) & BN_MASK2; \
if ((c1) < t2) \
c2++;
/* Keep in mind that additions to multiplication result can not overflow,
* because its high half cannot be all-ones. */
#define mul_add_c(a, b, c0, c1, c2) \
do { \
BN_ULONG hi; \
BN_ULLONG t = (BN_ULLONG)(a) * (b); \
t += c0; /* no carry */ \
c0 = (BN_ULONG)Lw(t); \
hi = (BN_ULONG)Hw(t); \
c1 = (c1 + hi) & BN_MASK2; \
if (c1 < hi) \
c2++; \
} while (0)
#define sqr_add_c(a, i, c0, c1, c2) \
t = (BN_ULLONG)a[i] * a[i]; \
t1 = (BN_ULONG)Lw(t); \
t2 = (BN_ULONG)Hw(t); \
c0 = (c0 + t1) & BN_MASK2; \
if ((c0) < t1) \
t2++; \
c1 = (c1 + t2) & BN_MASK2; \
if ((c1) < t2) \
c2++;
#define mul_add_c2(a, b, c0, c1, c2) \
do { \
BN_ULONG hi; \
BN_ULLONG t = (BN_ULLONG)(a) * (b); \
BN_ULLONG tt = t + c0; /* no carry */ \
c0 = (BN_ULONG)Lw(tt); \
hi = (BN_ULONG)Hw(tt); \
c1 = (c1 + hi) & BN_MASK2; \
if (c1 < hi) \
c2++; \
t += c0; /* no carry */ \
c0 = (BN_ULONG)Lw(t); \
hi = (BN_ULONG)Hw(t); \
c1 = (c1 + hi) & BN_MASK2; \
if (c1 < hi) \
c2++; \
} while (0)
#define sqr_add_c(a, i, c0, c1, c2) \
do { \
BN_ULONG hi; \
BN_ULLONG t = (BN_ULLONG)a[i] * a[i]; \
t += c0; /* no carry */ \
c0 = (BN_ULONG)Lw(t); \
hi = (BN_ULONG)Hw(t); \
c1 = (c1 + hi) & BN_MASK2; \
if (c1 < hi) \
c2++; \
} while (0)
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
#elif defined(BN_UMULT_LOHI)
/* Keep in mind that additions to hi can not overflow, because the high word of
* a multiplication result cannot be all-ones. */
#define mul_add_c(a, b, c0, c1, c2) \
{ \
do { \
BN_ULONG ta = (a), tb = (b); \
BN_UMULT_LOHI(t1, t2, ta, tb); \
c0 += t1; \
t2 += (c0 < t1) ? 1 : 0; \
c1 += t2; \
c2 += (c1 < t2) ? 1 : 0; \
}
BN_ULONG lo, hi; \
BN_UMULT_LOHI(lo, hi, ta, tb); \
c0 += lo; \
hi += (c0 < lo) ? 1 : 0; \
c1 += hi; \
c2 += (c1 < hi) ? 1 : 0; \
} while (0)
#define mul_add_c2(a, b, c0, c1, c2) \
{ \
BN_ULONG ta = (a), tb = (b), t0; \
BN_UMULT_LOHI(t0, t1, ta, tb); \
t2 = t1 + t1; \
c2 += (t2 < t1) ? 1 : 0; \
t1 = t0 + t0; \
t2 += (t1 < t0) ? 1 : 0; \
c0 += t1; \
t2 += (c0 < t1) ? 1 : 0; \
c1 += t2; \
c2 += (c1 < t2) ? 1 : 0; \
}
do { \
BN_ULONG ta = (a), tb = (b); \
BN_ULONG lo, hi, tt; \
BN_UMULT_LOHI(lo, hi, ta, tb); \
c0 += lo; \
tt = hi + ((c0 < lo) ? 1 : 0); \
c1 += tt; \
c2 += (c1 < tt) ? 1 : 0; \
c0 += lo; \
hi += (c0 < lo) ? 1 : 0; \
c1 += hi; \
c2 += (c1 < hi) ? 1 : 0; \
} while (0)
#define sqr_add_c(a, i, c0, c1, c2) \
{ \
do { \
BN_ULONG ta = (a)[i]; \
BN_UMULT_LOHI(t1, t2, ta, ta); \
c0 += t1; \
t2 += (c0 < t1) ? 1 : 0; \
c1 += t2; \
c2 += (c1 < t2) ? 1 : 0; \
}
BN_ULONG lo, hi; \
BN_UMULT_LOHI(lo, hi, ta, ta); \
c0 += lo; \
hi += (c0 < lo) ? 1 : 0; \
c1 += hi; \
c2 += (c1 < hi) ? 1 : 0; \
} while (0)
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
#elif defined(BN_UMULT_HIGH)
#define mul_add_c(a, b, c0, c1, c2) \
{ \
BN_ULONG ta = (a), tb = (b); \
t1 = ta * tb; \
t2 = BN_UMULT_HIGH(ta, tb); \
c0 += t1; \
t2 += (c0 < t1) ? 1 : 0; \
c1 += t2; \
c2 += (c1 < t2) ? 1 : 0; \
}
/* Keep in mind that additions to hi can not overflow, because
* the high word of a multiplication result cannot be all-ones. */
#define mul_add_c(a, b, c0, c1, c2) \
do { \
BN_ULONG ta = (a), tb = (b); \
BN_ULONG lo = ta * tb; \
BN_ULONG hi = BN_UMULT_HIGH(ta, tb); \
c0 += lo; \
hi += (c0 < lo) ? 1 : 0; \
c1 += hi; \
c2 += (c1 < hi) ? 1 : 0; \
} while (0)
#define mul_add_c2(a, b, c0, c1, c2) \
{ \
BN_ULONG ta = (a), tb = (b), t0; \
t1 = BN_UMULT_HIGH(ta, tb); \
t0 = ta * tb; \
t2 = t1 + t1; \
c2 += (t2 < t1) ? 1 : 0; \
t1 = t0 + t0; \
t2 += (t1 < t0) ? 1 : 0; \
c0 += t1; \
t2 += (c0 < t1) ? 1 : 0; \
c1 += t2; \
c2 += (c1 < t2) ? 1 : 0; \
}
#define mul_add_c2(a, b, c0, c1, c2) \
do { \
BN_ULONG ta = (a), tb = (b), tt; \
BN_ULONG lo = ta * tb; \
BN_ULONG hi = BN_UMULT_HIGH(ta, tb); \
c0 += lo; \
tt = hi + ((c0 < lo) ? 1 : 0); \
c1 += tt; \
c2 += (c1 < tt) ? 1 : 0; \
c0 += lo; \
hi += (c0 < lo) ? 1 : 0; \
c1 += hi; \
c2 += (c1 < hi) ? 1 : 0; \
} while (0)
#define sqr_add_c(a, i, c0, c1, c2) \
{ \
BN_ULONG ta = (a)[i]; \
t1 = ta * ta; \
t2 = BN_UMULT_HIGH(ta, ta); \
c0 += t1; \
t2 += (c0 < t1) ? 1 : 0; \
c1 += t2; \
c2 += (c1 < t2) ? 1 : 0; \
}
#define sqr_add_c(a, i, c0, c1, c2) \
do { \
BN_ULONG ta = (a)[i]; \
BN_ULONG lo = ta * ta; \
BN_ULONG hi = BN_UMULT_HIGH(ta, ta); \
c0 += lo; \
hi += (c0 < lo) ? 1 : 0; \
c1 += hi; \
c2 += (c1 < hi) ? 1 : 0; \
} while (0)
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
#else /* !BN_LLONG */
#define mul_add_c(a, b, c0, c1, c2) \
t1 = LBITS(a); \
t2 = HBITS(a); \
bl = LBITS(b); \
bh = HBITS(b); \
mul64(t1, t2, bl, bh); \
c0 = (c0 + t1) & BN_MASK2; \
if ((c0) < t1) \
t2++; \
c1 = (c1 + t2) & BN_MASK2; \
if ((c1) < t2) \
c2++;
#define mul_add_c2(a, b, c0, c1, c2) \
t1 = LBITS(a); \
t2 = HBITS(a); \
bl = LBITS(b); \
bh = HBITS(b); \
mul64(t1, t2, bl, bh); \
if (t2 & BN_TBIT) \
c2++; \
t2 = (t2 + t2) & BN_MASK2; \
if (t1 & BN_TBIT) \
t2++; \
t1 = (t1 + t1) & BN_MASK2; \
c0 = (c0 + t1) & BN_MASK2; \
if ((c0 < t1) && (((++t2) & BN_MASK2) == 0)) \
c2++; \
c1 = (c1 + t2) & BN_MASK2; \
if ((c1) < t2) \
c2++;
/* Keep in mind that additions to hi can not overflow, because
* the high word of a multiplication result cannot be all-ones. */
#define mul_add_c(a, b, c0, c1, c2) \
do { \
BN_ULONG lo = LBITS(a), hi = HBITS(a); \
BN_ULONG bl = LBITS(b), bh = HBITS(b); \
mul64(lo, hi, bl, bh); \
c0 = (c0 + lo) & BN_MASK2; \
if (c0 < lo) \
hi++; \
c1 = (c1 + hi) & BN_MASK2; \
if (c1 < hi) \
c2++; \
} while (0)
#define mul_add_c2(a, b, c0, c1, c2) \
do { \
BN_ULONG tt; \
BN_ULONG lo = LBITS(a), hi = HBITS(a); \
BN_ULONG bl = LBITS(b), bh = HBITS(b); \
mul64(lo, hi, bl, bh); \
tt = hi; \
c0 = (c0 + lo) & BN_MASK2; \
if (c0 < lo) \
tt++; \
c1 = (c1 + tt) & BN_MASK2; \
if (c1 < tt) \
c2++; \
c0 = (c0 + lo) & BN_MASK2; \
if (c0 < lo) \
hi++; \
c1 = (c1 + hi) & BN_MASK2; \
if (c1 < hi) \
c2++; \
} while (0)
#define sqr_add_c(a, i, c0, c1, c2) \
sqr64(t1, t2, (a)[i]); \
c0 = (c0 + t1) & BN_MASK2; \
if ((c0) < t1) \
t2++; \
c1 = (c1 + t2) & BN_MASK2; \
if ((c1) < t2) \
c2++;
do { \
BN_ULONG lo, hi; \
sqr64(lo, hi, (a)[i]); \
c0 = (c0 + lo) & BN_MASK2; \
if (c0 < lo) \
hi++; \
c1 = (c1 + hi) & BN_MASK2; \
if (c1 < hi) \
c2++; \
} while (0)
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
#endif /* !BN_LLONG */
void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
#if defined(BN_LLONG)
BN_ULLONG t;
#elif !defined(BN_UMULT_LOHI) && !defined(BN_UMULT_HIGH)
BN_ULONG bl, bh;
#endif
BN_ULONG t1, t2;
BN_ULONG c1, c2, c3;
c1 = 0;
@@ -930,12 +949,6 @@ void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
}
void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
#if defined(BN_LLONG)
BN_ULLONG t;
#elif !defined(BN_UMULT_LOHI) && !defined(BN_UMULT_HIGH)
BN_ULONG bl, bh;
#endif
BN_ULONG t1, t2;
BN_ULONG c1, c2, c3;
c1 = 0;
@@ -974,12 +987,6 @@ void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
}
void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) {
#if defined(BN_LLONG)
BN_ULLONG t, tt;
#elif !defined(BN_UMULT_LOHI) && !defined(BN_UMULT_HIGH)
BN_ULONG bl, bh;
#endif
BN_ULONG t1, t2;
BN_ULONG c1, c2, c3;
c1 = 0;
@@ -1054,12 +1061,6 @@ void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) {
}
void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) {
#if defined(BN_LLONG)
BN_ULLONG t, tt;
#elif !defined(BN_UMULT_LOHI) && !defined(BN_UMULT_HIGH)
BN_ULONG bl, bh;
#endif
BN_ULONG t1, t2;
BN_ULONG c1, c2, c3;
c1 = 0;
+9 -9
View File
@@ -127,6 +127,11 @@
#include <inttypes.h>
#if defined(OPENSSL_X86_64) && defined(_MSC_VER) && _MSC_VER >= 1400
#include <intrin.h>
#pragma intrinsic(__umulh, _umul128)
#endif
#if defined(__cplusplus)
extern "C" {
#endif
@@ -239,7 +244,7 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
}
#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64)
# if defined(__GNUC__) && __GNUC__>=2
# if defined(__GNUC__) && __GNUC__ >= 2
# define BN_UMULT_HIGH(a,b) ({ \
register BN_ULONG ret,discard; \
__asm__ ("mulq %3" \
@@ -252,14 +257,9 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
: "=a"(low),"=d"(high) \
: "a"(a),"g"(b) \
: "cc");
# endif
# if defined(_MSC_VER) && _MSC_VER>=1400
unsigned __int64 __umulh (unsigned __int64 a,unsigned __int64 b);
unsigned __int64 _umul128 (unsigned __int64 a,unsigned __int64 b,
unsigned __int64 *h);
# pragma intrinsic(__umulh,_umul128)
# define BN_UMULT_HIGH(a,b) __umulh((a),(b))
# define BN_UMULT_LOHI(low,high,a,b) ((low)=_umul128((a),(b),&(high)))
# elif defined(_MSC_VER) && _MSC_VER >= 1400
# define BN_UMULT_HIGH(a, b) __umulh((a), (b))
# define BN_UMULT_LOHI(low, high, a, b) ((low) = _umul128((a), (b), &(high)))
# endif
#elif !defined(OPENSSL_NO_ASM) && defined(OPENSSL_AARCH64)
# if defined(__GNUC__) && __GNUC__>=2
+4 -3
View File
@@ -136,9 +136,10 @@ int BN_rand(BIGNUM *rnd, int bits, int top, int bottom) {
goto err;
}
/* make a random number and set the top and bottom bits */
if (RAND_pseudo_bytes(buf, bytes) <= 0)
/* Make a random number and set the top and bottom bits. */
if (!RAND_bytes(buf, bytes)) {
goto err;
}
if (top != -1) {
if (top) {
@@ -286,7 +287,7 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, const BIGNUM *priv,
for (attempt = 0;; attempt++) {
for (done = 0; done < num_k_bytes;) {
if (RAND_pseudo_bytes(random_bytes, sizeof(random_bytes)) != 1) {
if (!RAND_bytes(random_bytes, sizeof(random_bytes))) {
goto err;
}
SHA512_Init(&sha);
+7 -5
View File
@@ -122,15 +122,17 @@ static int cbs_convert_ber(CBS *in, CBB *out, char squash_header,
* implicit and the tags within are fragments of a primitive type that
* need to be concatenated. */
if (context_specific && (tag & CBS_ASN1_CONSTRUCTED)) {
CBS in_copy, contents;
unsigned tag;
size_t header_len;
CBS in_copy, inner_contents;
unsigned inner_tag;
size_t inner_header_len;
CBS_init(&in_copy, CBS_data(in), CBS_len(in));
if (!CBS_get_any_asn1_element(&in_copy, &contents, &tag, &header_len)) {
if (!CBS_get_any_asn1_element(&in_copy, &inner_contents, &inner_tag,
&inner_header_len)) {
return 0;
}
if (CBS_len(&contents) > header_len && is_primitive_type(tag)) {
if (CBS_len(&inner_contents) > inner_header_len &&
is_primitive_type(inner_tag)) {
squash_child_headers = 1;
}
}
+3 -4
View File
@@ -448,8 +448,7 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) {
if (arg) {
memcpy(gctx->iv, ptr, arg);
}
if (c->encrypt &&
RAND_pseudo_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0) {
if (c->encrypt && !RAND_bytes(gctx->iv + arg, gctx->ivlen - arg)) {
return 0;
}
gctx->iv_gen = 1;
@@ -1103,7 +1102,7 @@ static int aead_aes_key_wrap_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
/* The code below only handles a 32-bit |t| thus 6*|n| must be less than
* 2^32, where |n| is |in_len| / 8. So in_len < 4/3 * 2^32 and we
* conservatively cap it to 2^32-16 to stop 32-bit platforms complaining that
* a comparision is always true. */
* a comparison is always true. */
if (in_len > 0xfffffff0) {
OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_seal, CIPHER_R_TOO_LARGE);
return 0;
@@ -1198,7 +1197,7 @@ static int aead_aes_key_wrap_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
/* The code below only handles a 32-bit |t| thus 6*|n| must be less than
* 2^32, where |n| is |in_len| / 8. So in_len < 4/3 * 2^32 and we
* conservatively cap it to 2^32-8 to stop 32-bit platforms complaining that
* a comparision is always true. */
* a comparison is always true. */
if (in_len > 0xfffffff8) {
OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_open, CIPHER_R_TOO_LARGE);
return 0;
-1
View File
@@ -279,7 +279,6 @@ static void RC2_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
l2c(xor0, iv);
l2c(xor1, iv);
}
tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
tin[0] = tin[1] = 0;
}
+1 -1
View File
@@ -59,6 +59,7 @@
#include <assert.h>
#include <openssl/cipher.h>
#include <openssl/cpu.h>
#include <openssl/err.h>
#include <openssl/md5.h>
#include <openssl/mem.h>
@@ -176,7 +177,6 @@ static int aead_rc4_md5_tls_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
MD5_CTX md;
#if defined(STITCHED_CALL)
size_t rc4_off, md5_off, blocks;
extern unsigned int OPENSSL_ia32cap_P[];
#else
const size_t rc4_off = 0;
const size_t md5_off = 0;
+307
View File
@@ -0,0 +1,307 @@
/*
* Utilities for constant-time cryptography.
*
* Author: Emilia Kasper (emilia@openssl.org)
* Based on previous work by Bodo Moeller, Emilia Kasper, Adam Langley
* (Google).
* ====================================================================
* Copyright (c) 2014 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 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 "internal.h"
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
static const unsigned int CONSTTIME_TRUE = (unsigned)(~0);
static const unsigned int CONSTTIME_FALSE = 0;
static const uint8_t CONSTTIME_TRUE_8 = 0xff;
static const uint8_t CONSTTIME_FALSE_8 = 0;
static int test_binary_op(unsigned int (*op)(unsigned int a, unsigned int b),
const char* op_name, unsigned int a, unsigned int b,
int is_true) {
unsigned c = op(a, b);
if (is_true && c != CONSTTIME_TRUE) {
fprintf(stderr,
"Test failed for %s(%du, %du): expected %du (TRUE), got %du\n",
op_name, a, b, CONSTTIME_TRUE, c);
return 1;
} else if (!is_true && c != CONSTTIME_FALSE) {
fprintf(stderr,
"Test failed for %s(%du, %du): expected %du (FALSE), got %du\n",
op_name, a, b, CONSTTIME_FALSE, c);
return 1;
}
return 0;
}
static int test_binary_op_8(uint8_t (*op)(unsigned int a, unsigned int b),
const char* op_name, unsigned int a, unsigned int b,
int is_true) {
uint8_t c = op(a, b);
if (is_true && c != CONSTTIME_TRUE_8) {
fprintf(stderr,
"Test failed for %s(%du, %du): expected %u (TRUE), got %u\n",
op_name, a, b, CONSTTIME_TRUE_8, c);
return 1;
} else if (!is_true && c != CONSTTIME_FALSE_8) {
fprintf(stderr,
"Test failed for %s(%du, %du): expected %u (FALSE), got %u\n",
op_name, a, b, CONSTTIME_FALSE_8, c);
return 1;
}
return 0;
}
static int test_is_zero(unsigned int a) {
unsigned int c = constant_time_is_zero(a);
if (a == 0 && c != CONSTTIME_TRUE) {
fprintf(stderr,
"Test failed for constant_time_is_zero(%du): expected %du (TRUE), "
"got %du\n",
a, CONSTTIME_TRUE, c);
return 1;
} else if (a != 0 && c != CONSTTIME_FALSE) {
fprintf(stderr,
"Test failed for constant_time_is_zero(%du): expected %du (FALSE), "
"got %du\n",
a, CONSTTIME_FALSE, c);
return 1;
}
return 0;
}
static int test_is_zero_8(unsigned int a) {
uint8_t c = constant_time_is_zero_8(a);
if (a == 0 && c != CONSTTIME_TRUE_8) {
fprintf(stderr,
"Test failed for constant_time_is_zero(%du): expected %u (TRUE), "
"got %u\n",
a, CONSTTIME_TRUE_8, c);
return 1;
} else if (a != 0 && c != CONSTTIME_FALSE) {
fprintf(stderr,
"Test failed for constant_time_is_zero(%du): expected %u (FALSE), "
"got %u\n",
a, CONSTTIME_FALSE_8, c);
return 1;
}
return 0;
}
static int test_select(unsigned int a, unsigned int b) {
unsigned int selected = constant_time_select(CONSTTIME_TRUE, a, b);
if (selected != a) {
fprintf(stderr,
"Test failed for constant_time_select(%du, %du,"
"%du): expected %du(first value), got %du\n",
CONSTTIME_TRUE, a, b, a, selected);
return 1;
}
selected = constant_time_select(CONSTTIME_FALSE, a, b);
if (selected != b) {
fprintf(stderr,
"Test failed for constant_time_select(%du, %du,"
"%du): expected %du(second value), got %du\n",
CONSTTIME_FALSE, a, b, b, selected);
return 1;
}
return 0;
}
static int test_select_8(uint8_t a, uint8_t b) {
uint8_t selected = constant_time_select_8(CONSTTIME_TRUE_8, a, b);
if (selected != a) {
fprintf(stderr,
"Test failed for constant_time_select(%u, %u,"
"%u): expected %u(first value), got %u\n",
CONSTTIME_TRUE, a, b, a, selected);
return 1;
}
selected = constant_time_select_8(CONSTTIME_FALSE_8, a, b);
if (selected != b) {
fprintf(stderr,
"Test failed for constant_time_select(%u, %u,"
"%u): expected %u(second value), got %u\n",
CONSTTIME_FALSE, a, b, b, selected);
return 1;
}
return 0;
}
static int test_select_int(int a, int b) {
int selected = constant_time_select_int(CONSTTIME_TRUE, a, b);
if (selected != a) {
fprintf(stderr,
"Test failed for constant_time_select(%du, %d,"
"%d): expected %d(first value), got %d\n",
CONSTTIME_TRUE, a, b, a, selected);
return 1;
}
selected = constant_time_select_int(CONSTTIME_FALSE, a, b);
if (selected != b) {
fprintf(stderr,
"Test failed for constant_time_select(%du, %d,"
"%d): expected %d(second value), got %d\n",
CONSTTIME_FALSE, a, b, b, selected);
return 1;
}
return 0;
}
static int test_eq_int(int a, int b) {
unsigned int equal = constant_time_eq_int(a, b);
if (a == b && equal != CONSTTIME_TRUE) {
fprintf(stderr,
"Test failed for constant_time_eq_int(%d, %d): expected %du(TRUE), "
"got %du\n",
a, b, CONSTTIME_TRUE, equal);
return 1;
} else if (a != b && equal != CONSTTIME_FALSE) {
fprintf(stderr,
"Test failed for constant_time_eq_int(%d, %d): expected "
"%du(FALSE), got %du\n",
a, b, CONSTTIME_FALSE, equal);
return 1;
}
return 0;
}
static int test_eq_int_8(int a, int b) {
uint8_t equal = constant_time_eq_int_8(a, b);
if (a == b && equal != CONSTTIME_TRUE_8) {
fprintf(stderr,
"Test failed for constant_time_eq_int_8(%d, %d): expected "
"%u(TRUE), got %u\n",
a, b, CONSTTIME_TRUE_8, equal);
return 1;
} else if (a != b && equal != CONSTTIME_FALSE_8) {
fprintf(stderr,
"Test failed for constant_time_eq_int_8(%d, %d): expected "
"%u(FALSE), got %u\n",
a, b, CONSTTIME_FALSE_8, equal);
return 1;
}
return 0;
}
static unsigned int test_values[] = {0, 1, 1024, 12345, 32000, UINT_MAX / 2 - 1,
UINT_MAX / 2, UINT_MAX / 2 + 1,
UINT_MAX - 1, UINT_MAX};
static uint8_t test_values_8[] = {0, 1, 2, 20, 32, 127, 128, 129, 255};
static int signed_test_values[] = {
0, 1, -1, 1024, -1024, 12345, -12345,
32000, -32000, INT_MAX, INT_MIN, INT_MAX - 1, INT_MIN + 1};
int main(int argc, char* argv[]) {
unsigned int a, b, i, j;
int c, d;
uint8_t e, f;
int num_failed = 0, num_all = 0;
fprintf(stdout, "Testing constant time operations...\n");
for (i = 0; i < sizeof(test_values) / sizeof(int); ++i) {
a = test_values[i];
num_failed += test_is_zero(a);
num_failed += test_is_zero_8(a);
num_all += 2;
for (j = 0; j < sizeof(test_values) / sizeof(int); ++j) {
b = test_values[j];
num_failed +=
test_binary_op(&constant_time_lt, "constant_time_lt", a, b, a < b);
num_failed += test_binary_op_8(&constant_time_lt_8, "constant_time_lt_8",
a, b, a < b);
num_failed +=
test_binary_op(&constant_time_lt, "constant_time_lt_8", b, a, b < a);
num_failed += test_binary_op_8(&constant_time_lt_8, "constant_time_lt_8",
b, a, b < a);
num_failed +=
test_binary_op(&constant_time_ge, "constant_time_ge", a, b, a >= b);
num_failed += test_binary_op_8(&constant_time_ge_8, "constant_time_ge_8",
a, b, a >= b);
num_failed +=
test_binary_op(&constant_time_ge, "constant_time_ge", b, a, b >= a);
num_failed += test_binary_op_8(&constant_time_ge_8, "constant_time_ge_8",
b, a, b >= a);
num_failed +=
test_binary_op(&constant_time_eq, "constant_time_eq", a, b, a == b);
num_failed += test_binary_op_8(&constant_time_eq_8, "constant_time_eq_8",
a, b, a == b);
num_failed +=
test_binary_op(&constant_time_eq, "constant_time_eq", b, a, b == a);
num_failed += test_binary_op_8(&constant_time_eq_8, "constant_time_eq_8",
b, a, b == a);
num_failed += test_select(a, b);
num_all += 13;
}
}
for (i = 0; i < sizeof(signed_test_values) / sizeof(int); ++i) {
c = signed_test_values[i];
for (j = 0; j < sizeof(signed_test_values) / sizeof(int); ++j) {
d = signed_test_values[j];
num_failed += test_select_int(c, d);
num_failed += test_eq_int(c, d);
num_failed += test_eq_int_8(c, d);
num_all += 3;
}
}
for (i = 0; i < sizeof(test_values_8); ++i) {
e = test_values_8[i];
for (j = 0; j < sizeof(test_values_8); ++j) {
f = test_values_8[j];
num_failed += test_select_8(e, f);
num_all += 1;
}
}
if (!num_failed) {
fprintf(stdout, "ok (ran %d tests)\n", num_all);
fprintf(stdout, "PASS\n");
return EXIT_SUCCESS;
} else {
fprintf(stdout, "%d of %d tests failed!\n", num_failed, num_all);
return EXIT_FAILURE;
}
}
+8
View File
@@ -9,3 +9,11 @@ add_library(
digests.c
digest_error.c
)
add_executable(
digest_test
digest_test.c
)
target_link_libraries(digest_test crypto)
+244
View File
@@ -0,0 +1,244 @@
/* Copyright (c) 2014, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/md4.h>
#include <openssl/md5.h>
#include <openssl/sha.h>
typedef struct {
/* md_func is the digest to test. */
const EVP_MD *(*md_func)(void);
/* one_shot_func is the convenience one-shot version of the
* digest. */
uint8_t *(*one_shot_func)(const uint8_t *, size_t, uint8_t *);
/* input is a NUL-terminated string to hash. */
const char *input;
/* repeat is the number of times to repeat input. */
size_t repeat;
/* expected_hex is the expected digest in hexadecimal. */
const char *expected_hex;
} TEST_VECTOR;
static const TEST_VECTOR kTestVectors[] = {
/* MD4 tests, from RFC 1320. (crypto/md4 does not provide a
* one-shot MD4 function.) */
{ &EVP_md4, NULL, "", 1, "31d6cfe0d16ae931b73c59d7e0c089c0" },
{ &EVP_md4, NULL, "a", 1, "bde52cb31de33e46245e05fbdbd6fb24" },
{ &EVP_md4, NULL, "abc", 1, "a448017aaf21d8525fc10ae87aa6729d" },
{ &EVP_md4, NULL, "message digest", 1,
"d9130a8164549fe818874806e1c7014b" },
{ &EVP_md4, NULL, "abcdefghijklmnopqrstuvwxyz", 1,
"d79e1c308aa5bbcdeea8ed63df412da9" },
{ &EVP_md4, NULL,
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 1,
"043f8582f241db351ce627e153e7f0e4" },
{ &EVP_md4, NULL, "1234567890", 8, "e33b4ddc9c38f2199c3e7b164fcc0536" },
/* MD5 tests, from RFC 1321. */
{ &EVP_md5, &MD5, "", 1, "d41d8cd98f00b204e9800998ecf8427e" },
{ &EVP_md5, &MD5, "a", 1, "0cc175b9c0f1b6a831c399e269772661" },
{ &EVP_md5, &MD5, "abc", 1, "900150983cd24fb0d6963f7d28e17f72" },
{ &EVP_md5, &MD5, "message digest", 1, "f96b697d7cb7938d525a2f31aaf161d0" },
{ &EVP_md5, &MD5, "abcdefghijklmnopqrstuvwxyz", 1,
"c3fcd3d76192e4007dfb496cca67e13b" },
{ &EVP_md5, &MD5,
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 1,
"d174ab98d277d9f5a5611c2c9f419d9f" },
{ &EVP_md5, &MD5, "1234567890", 8, "57edf4a22be3c955ac49da2e2107b67a" },
/* SHA-1 tests, from RFC 3174. */
{ &EVP_sha1, &SHA1, "abc", 1, "a9993e364706816aba3e25717850c26c9cd0d89d" },
{ &EVP_sha1, &SHA1,
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
"84983e441c3bd26ebaae4aa1f95129e5e54670f1" },
{ &EVP_sha1, &SHA1, "a", 1000000,
"34aa973cd4c4daa4f61eeb2bdbad27316534016f" },
{ &EVP_sha1, &SHA1,
"0123456701234567012345670123456701234567012345670123456701234567", 10,
"dea356a2cddd90c7a7ecedc5ebb563934f460452" },
/* SHA-224 tests, from RFC 3874. */
{ &EVP_sha224, &SHA224, "abc", 1,
"23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7" },
{ &EVP_sha224, &SHA224,
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
"75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525" },
{ &EVP_sha224, &SHA224,
"a", 1000000,
"20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67" },
/* SHA-256 tests, from NIST. */
{ &EVP_sha256, &SHA256, "abc", 1,
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" },
{ &EVP_sha256, &SHA256,
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
"248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1" },
/* SHA-384 tests, from NIST. */
{ &EVP_sha384, &SHA384, "abc", 1,
"cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed"
"8086072ba1e7cc2358baeca134c825a7" },
{ &EVP_sha384, &SHA384,
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 1,
"09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712"
"fcc7c71a557e2db966c3e9fa91746039" },
/* SHA-512 tests, from NIST. */
{ &EVP_sha512, &SHA512, "abc", 1,
"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"
"2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" },
{ &EVP_sha512, &SHA512,
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 1,
"8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018"
"501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909" },
/* MD5-SHA1 tests. */
{ &EVP_md5_sha1, NULL, "abc", 1,
"900150983cd24fb0d6963f7d28e17f72a9993e364706816aba3e25717850c26c9cd0d89d" },
};
static int compare_digest(const TEST_VECTOR *test,
const uint8_t *digest,
size_t digest_len) {
static const char kHexTable[] = "0123456789abcdef";
size_t i;
char digest_hex[2*EVP_MAX_MD_SIZE + 1];
for (i = 0; i < digest_len; i++) {
digest_hex[2*i] = kHexTable[digest[i] >> 4];
digest_hex[2*i + 1] = kHexTable[digest[i] & 0xf];
}
digest_hex[2*digest_len] = '\0';
if (strcmp(digest_hex, test->expected_hex) != 0) {
fprintf(stderr, "%s(\"%s\" * %d) = %s; want %s\n",
EVP_MD_name(test->md_func()), test->input, (int)test->repeat,
digest_hex, test->expected_hex);
return 0;
}
return 1;
}
static int test_digest(const TEST_VECTOR *test) {
int ret = 0;
EVP_MD_CTX ctx;
size_t i;
uint8_t digest[EVP_MAX_MD_SIZE];
unsigned digest_len;
EVP_MD_CTX_init(&ctx);
/* Test the input provided. */
if (!EVP_DigestInit_ex(&ctx, test->md_func(), NULL)) {
fprintf(stderr, "EVP_DigestInit_ex failed\n");
goto done;
}
for (i = 0; i < test->repeat; i++) {
if (!EVP_DigestUpdate(&ctx, test->input, strlen(test->input))) {
fprintf(stderr, "EVP_DigestUpdate failed\n");
goto done;
}
}
if (!EVP_DigestFinal_ex(&ctx, digest, &digest_len)) {
fprintf(stderr, "EVP_DigestFinal_ex failed\n");
goto done;
}
if (!compare_digest(test, digest, digest_len)) {
goto done;
}
/* Test the input one character at a time. */
if (!EVP_DigestInit_ex(&ctx, test->md_func(), NULL)) {
fprintf(stderr, "EVP_DigestInit_ex failed\n");
goto done;
}
if (!EVP_DigestUpdate(&ctx, NULL, 0)) {
fprintf(stderr, "EVP_DigestUpdate failed\n");
goto done;
}
for (i = 0; i < test->repeat; i++) {
const char *p;
for (p = test->input; *p; p++) {
if (!EVP_DigestUpdate(&ctx, p, 1)) {
fprintf(stderr, "EVP_DigestUpdate failed\n");
goto done;
}
}
}
if (!EVP_DigestFinal_ex(&ctx, digest, &digest_len)) {
fprintf(stderr, "EVP_DigestFinal_ex failed\n");
goto done;
}
if (digest_len != EVP_MD_size(test->md_func())) {
fprintf(stderr, "EVP_MD_size output incorrect\n");
goto done;
}
if (!compare_digest(test, digest, digest_len)) {
goto done;
}
/* Test the one-shot function. */
if (test->one_shot_func && test->repeat == 1) {
uint8_t *out = test->one_shot_func((const uint8_t *)test->input,
strlen(test->input), digest);
if (out != digest) {
fprintf(stderr, "one_shot_func gave incorrect return\n");
goto done;
}
if (!compare_digest(test, digest, EVP_MD_size(test->md_func()))) {
goto done;
}
/* Test the deprecated static buffer variant, until it's removed. */
out = test->one_shot_func((const uint8_t *)test->input, strlen(test->input),
NULL);
if (!compare_digest(test, out, EVP_MD_size(test->md_func()))) {
goto done;
}
}
ret = 1;
done:
EVP_MD_CTX_cleanup(&ctx);
return ret;
}
int main(void) {
size_t i;
CRYPTO_library_init();
ERR_load_crypto_strings();
for (i = 0; i < sizeof(kTestVectors) / sizeof(kTestVectors[0]); i++) {
if (!test_digest(&kTestVectors[i])) {
fprintf(stderr, "Test %d failed\n", (int)i);
return 1;
}
}
printf("PASS\n");
return 0;
}
+41 -1
View File
@@ -193,9 +193,48 @@ static const EVP_MD sha512_md = {
const EVP_MD *EVP_sha512(void) { return &sha512_md; }
typedef struct {
MD5_CTX md5;
SHA_CTX sha1;
} MD5_SHA1_CTX;
static int md5_sha1_init(EVP_MD_CTX *md_ctx) {
MD5_SHA1_CTX *ctx = md_ctx->md_data;
return MD5_Init(&ctx->md5) && SHA1_Init(&ctx->sha1);
}
static int md5_sha1_update(EVP_MD_CTX *md_ctx, const void *data, size_t count) {
MD5_SHA1_CTX *ctx = md_ctx->md_data;
return MD5_Update(&ctx->md5, data, count) && SHA1_Update(&ctx->sha1, data, count);
}
static int md5_sha1_final(EVP_MD_CTX *md_ctx, unsigned char *out) {
MD5_SHA1_CTX *ctx = md_ctx->md_data;
if (!MD5_Final(out, &ctx->md5) ||
!SHA1_Final(out + MD5_DIGEST_LENGTH, &ctx->sha1)) {
return 0;
}
return 1;
}
static const EVP_MD md5_sha1_md = {
NID_md5_sha1,
MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH,
0 /* flags */,
md5_sha1_init,
md5_sha1_update,
md5_sha1_final,
64 /* block size */,
sizeof(MD5_SHA1_CTX),
};
const EVP_MD *EVP_md5_sha1(void) { return &md5_sha1_md; }
struct nid_to_digest {
int nid;
const EVP_MD *(*md_func)();
const EVP_MD* (*md_func)(void);
};
static const struct nid_to_digest nid_to_digest_mapping[] = {
@@ -205,6 +244,7 @@ static const struct nid_to_digest nid_to_digest_mapping[] = {
{ NID_sha256, EVP_sha256 },
{ NID_sha384, EVP_sha384 },
{ NID_sha512, EVP_sha512 },
{ NID_md5_sha1, EVP_md5_sha1 },
{ NID_dsaWithSHA, EVP_sha1 },
{ NID_dsaWithSHA1, EVP_sha1 },
{ NID_ecdsa_with_SHA1, EVP_sha1 },
+12 -1
View File
@@ -243,13 +243,21 @@ int DSA_verify(int type, const uint8_t *digest, size_t digest_len,
const uint8_t *sig, size_t sig_len, const DSA *dsa) {
DSA_SIG *s = NULL;
int ret = -1, valid;
uint8_t *der = NULL;
s = DSA_SIG_new();
if (s == NULL) {
goto err;
}
if (d2i_DSA_SIG(&s, &sig, sig_len) == NULL) {
const uint8_t *sigp = sig;
if (d2i_DSA_SIG(&s, &sigp, sig_len) == NULL || sigp != sig + sig_len) {
goto err;
}
/* Ensure that the signature uses DER and doesn't have trailing garbage. */
int der_len = i2d_DSA_SIG(s, &der);
if (der_len < 0 || (size_t)der_len != sig_len || memcmp(sig, der, sig_len)) {
goto err;
}
@@ -260,6 +268,9 @@ int DSA_verify(int type, const uint8_t *digest, size_t digest_len,
ret = valid;
err:
if (der != NULL) {
OPENSSL_free(der);
}
if (s) {
DSA_SIG_free(s);
}
+91 -65
View File
@@ -482,30 +482,35 @@ static int paramgen(DSA *ret, unsigned bits, const uint8_t *seed_in,
qsize = qbits / 8;
if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH &&
qsize != SHA256_DIGEST_LENGTH)
qsize != SHA256_DIGEST_LENGTH) {
/* invalid q size */
return 0;
}
if (bits < 512)
if (bits < 512) {
bits = 512;
}
bits = (bits + 63) / 64 * 64;
/* NB: seed_len == 0 is special case: copy generated seed to
* seed_in if it is not NULL. */
if (seed_len && (seed_len < (size_t)qsize))
if (seed_len && (seed_len < (size_t)qsize)) {
seed_in = NULL; /* seed buffer too small -- ignore */
if (seed_len > (size_t)qsize)
}
if (seed_len > (size_t)qsize) {
seed_len = qsize; /* App. 2.2 of FIPS PUB 186 allows larger SEED,
* but our internal buffers are restricted to 160 bits*/
if (seed_in != NULL)
}
if (seed_in != NULL) {
memcpy(seed, seed_in, seed_len);
}
if ((ctx = BN_CTX_new()) == NULL)
goto err;
if ((mont = BN_MONT_CTX_new()) == NULL)
ctx = BN_CTX_new();
mont = BN_MONT_CTX_new();
if (ctx == NULL || mont == NULL) {
goto err;
}
BN_CTX_start(ctx);
r0 = BN_CTX_get(ctx);
@@ -517,20 +522,24 @@ static int paramgen(DSA *ret, unsigned bits, const uint8_t *seed_in,
p = BN_CTX_get(ctx);
test = BN_CTX_get(ctx);
if (!BN_lshift(test, BN_value_one(), bits - 1))
if (!BN_lshift(test, BN_value_one(), bits - 1)) {
goto err;
}
for (;;) {
for (;;) /* find q */
{
/* Find q. */
for (;;) {
int seed_is_random;
/* step 1 */
if (!BN_GENCB_call(cb, 0, m++))
if (!BN_GENCB_call(cb, 0, m++)) {
goto err;
}
if (!seed_len) {
RAND_pseudo_bytes(seed, qsize);
if (!RAND_bytes(seed, qsize)) {
goto err;
}
seed_is_random = 1;
} else {
seed_is_random = 0;
@@ -541,39 +550,43 @@ static int paramgen(DSA *ret, unsigned bits, const uint8_t *seed_in,
/* precompute "SEED + 1" for step 7: */
for (i = qsize - 1; i < qsize; i--) {
buf[i]++;
if (buf[i] != 0)
if (buf[i] != 0) {
break;
}
}
/* step 2 */
if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL))
if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL) ||
!EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL)) {
goto err;
if (!EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL))
goto err;
for (i = 0; i < qsize; i++)
}
for (i = 0; i < qsize; i++) {
md[i] ^= buf2[i];
}
/* step 3 */
md[0] |= 0x80;
md[qsize - 1] |= 0x01;
if (!BN_bin2bn(md, qsize, q))
if (!BN_bin2bn(md, qsize, q)) {
goto err;
}
/* step 4 */
r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx, seed_is_random, cb);
if (r > 0)
if (r > 0) {
break;
if (r != 0)
}
if (r != 0) {
goto err;
}
/* do a callback call */
/* step 5 */
}
if (!BN_GENCB_call(cb, 2, 0))
goto err;
if (!BN_GENCB_call(cb, 3, 0))
if (!BN_GENCB_call(cb, 2, 0) || !BN_GENCB_call(cb, 3, 0)) {
goto err;
}
/* step 6 */
counter = 0;
@@ -582,8 +595,9 @@ static int paramgen(DSA *ret, unsigned bits, const uint8_t *seed_in,
n = (bits - 1) / 160;
for (;;) {
if ((counter != 0) && !BN_GENCB_call(cb, 0, counter))
if ((counter != 0) && !BN_GENCB_call(cb, 0, counter)) {
goto err;
}
/* step 7 */
BN_zero(W);
@@ -592,48 +606,48 @@ static int paramgen(DSA *ret, unsigned bits, const uint8_t *seed_in,
/* obtain "SEED + offset + k" by incrementing: */
for (i = qsize - 1; i < qsize; i--) {
buf[i]++;
if (buf[i] != 0)
if (buf[i] != 0) {
break;
}
}
if (!EVP_Digest(buf, qsize, md, NULL, evpmd, NULL))
if (!EVP_Digest(buf, qsize, md, NULL, evpmd, NULL)) {
goto err;
}
/* step 8 */
if (!BN_bin2bn(md, qsize, r0))
goto err;
if (!BN_lshift(r0, r0, (qsize << 3) * k))
goto err;
if (!BN_add(W, W, r0))
if (!BN_bin2bn(md, qsize, r0) ||
!BN_lshift(r0, r0, (qsize << 3) * k) ||
!BN_add(W, W, r0)) {
goto err;
}
}
/* more of step 8 */
if (!BN_mask_bits(W, bits - 1))
goto err;
if (!BN_copy(X, W))
goto err;
if (!BN_add(X, X, test))
if (!BN_mask_bits(W, bits - 1) ||
!BN_copy(X, W) ||
!BN_add(X, X, test)) {
goto err;
}
/* step 9 */
if (!BN_lshift1(r0, q))
goto err;
if (!BN_mod(c, X, r0, ctx))
goto err;
if (!BN_sub(r0, c, BN_value_one()))
goto err;
if (!BN_sub(p, X, r0))
if (!BN_lshift1(r0, q) ||
!BN_mod(c, X, r0, ctx) ||
!BN_sub(r0, c, BN_value_one()) ||
!BN_sub(p, X, r0)) {
goto err;
}
/* step 10 */
if (BN_cmp(p, test) >= 0) {
/* step 11 */
r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb);
if (r > 0)
if (r > 0) {
goto end; /* found it */
if (r != 0)
}
if (r != 0) {
goto err;
}
}
/* step 13 */
@@ -641,50 +655,59 @@ static int paramgen(DSA *ret, unsigned bits, const uint8_t *seed_in,
/* "offset = offset + n + 1" */
/* step 14 */
if (counter >= 4096)
if (counter >= 4096) {
break;
}
}
}
end:
if (!BN_GENCB_call(cb, 2, 1))
if (!BN_GENCB_call(cb, 2, 1)) {
goto err;
}
/* We now need to generate g */
/* Set r0=(p-1)/q */
if (!BN_sub(test, p, BN_value_one()))
goto err;
if (!BN_div(r0, NULL, test, q, ctx))
if (!BN_sub(test, p, BN_value_one()) ||
!BN_div(r0, NULL, test, q, ctx)) {
goto err;
}
if (!BN_set_word(test, h))
goto err;
if (!BN_MONT_CTX_set(mont, p, ctx))
if (!BN_set_word(test, h) ||
!BN_MONT_CTX_set(mont, p, ctx)) {
goto err;
}
for (;;) {
/* g=test^r0%p */
if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont))
if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont)) {
goto err;
if (!BN_is_one(g))
}
if (!BN_is_one(g)) {
break;
if (!BN_add(test, test, BN_value_one()))
}
if (!BN_add(test, test, BN_value_one())) {
goto err;
}
h++;
}
if (!BN_GENCB_call(cb, 3, 1))
if (!BN_GENCB_call(cb, 3, 1)) {
goto err;
}
ok = 1;
err:
if (ok) {
if (ret->p)
if (ret->p) {
BN_free(ret->p);
if (ret->q)
}
if (ret->q) {
BN_free(ret->q);
if (ret->g)
}
if (ret->g) {
BN_free(ret->g);
}
ret->p = BN_dup(p);
ret->q = BN_dup(q);
ret->g = BN_dup(g);
@@ -692,10 +715,12 @@ err:
ok = 0;
goto err;
}
if (counter_ret != NULL)
if (counter_ret != NULL) {
*counter_ret = counter;
if (h_ret != NULL)
}
if (h_ret != NULL) {
*h_ret = h;
}
}
if (ctx) {
@@ -703,8 +728,9 @@ err:
BN_CTX_free(ctx);
}
if (mont != NULL)
if (mont != NULL) {
BN_MONT_CTX_free(mont);
}
return ok;
}
+7
View File
@@ -21,4 +21,11 @@ add_executable(
example_mul.c
)
add_executable(
ec_test
ec_test.c
)
target_link_libraries(example_mul crypto)
target_link_libraries(ec_test crypto)
-7
View File
@@ -247,7 +247,6 @@ EC_GROUP *ec_group_new(const EC_METHOD *meth) {
ret->meth = meth;
BN_init(&ret->order);
BN_init(&ret->cofactor);
ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED;
if (!meth->group_init(ret)) {
OPENSSL_free(ret);
@@ -457,7 +456,6 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) {
}
dest->curve_name = src->curve_name;
dest->asn1_form = src->asn1_form;
return dest->meth->group_copy(dest, src);
}
@@ -540,11 +538,6 @@ int EC_GROUP_get_degree(const EC_GROUP *group) {
return group->meth->group_get_degree(group);
}
void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
point_conversion_form_t form) {
group->asn1_form = form;
}
int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) {
if (group->meth->mul == 0) {
/* use default */
+27 -11
View File
@@ -341,28 +341,41 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const uint8_t **in, long len) {
goto err;
}
/* TODO(fork): loading the public key is silly. Why not calculate it? */
if (ret->pub_key) {
EC_POINT_free(ret->pub_key);
}
ret->pub_key = EC_POINT_new(ret->group);
if (ret->pub_key == NULL) {
OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB);
goto err;
}
if (priv_key->publicKey) {
const uint8_t *pub_oct;
size_t pub_oct_len;
int pub_oct_len;
if (ret->pub_key) {
EC_POINT_free(ret->pub_key);
}
ret->pub_key = EC_POINT_new(ret->group);
if (ret->pub_key == NULL) {
OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB);
goto err;
}
pub_oct = M_ASN1_STRING_data(priv_key->publicKey);
pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey);
/* save the point conversion form */
/* The first byte (the point conversion form) must be present. */
if (pub_oct_len <= 0) {
OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, EC_R_BUFFER_TOO_SMALL);
goto err;
}
/* Save the point conversion form. */
ret->conv_form = (point_conversion_form_t)(pub_oct[0] & ~0x01);
if (!EC_POINT_oct2point(ret->group, ret->pub_key, pub_oct, pub_oct_len,
NULL)) {
OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB);
goto err;
}
} else {
if (!EC_POINT_mul(ret->group, ret->pub_key, ret->priv_key, NULL, NULL,
NULL)) {
OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB);
goto err;
}
/* Remember the original private-key-only encoding. */
ret->enc_flag |= EC_PKEY_NO_PUBKEY;
}
ok = 1;
@@ -373,6 +386,9 @@ err:
EC_KEY_free(ret);
}
ret = NULL;
if (a) {
*a = ret;
}
}
if (priv_key) {
-3
View File
@@ -295,9 +295,6 @@ point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key) {
void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform) {
key->conv_form = cform;
if (key->group != NULL) {
EC_GROUP_set_point_conversion_form(key->group, cform);
}
}
int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx) {
+124
View File
@@ -0,0 +1,124 @@
/* Copyright (c) 2014, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <stdio.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/crypto.h>
#include <openssl/ec_key.h>
#include <openssl/err.h>
#include "internal.h"
static const uint8_t kECKeyWithoutPublic[] = {
0x30, 0x31, 0x02, 0x01, 0x01, 0x04, 0x20, 0xc6, 0xc1, 0xaa, 0xda, 0x15, 0xb0,
0x76, 0x61, 0xf8, 0x14, 0x2c, 0x6c, 0xaf, 0x0f, 0xdb, 0x24, 0x1a, 0xff, 0x2e,
0xfe, 0x46, 0xc0, 0x93, 0x8b, 0x74, 0xf2, 0xbc, 0xc5, 0x30, 0x52, 0xb0, 0x77,
0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07,
};
int test_d2i_ECPrivateKey(void) {
int len, ret = 0;
uint8_t *out = NULL, *outp;
const uint8_t *inp;
EC_KEY *key = NULL;
BIGNUM *x = NULL, *y = NULL;
const EC_POINT *public;
char *x_hex = NULL, *y_hex = NULL;
inp = kECKeyWithoutPublic;
key = d2i_ECPrivateKey(NULL, &inp, sizeof(kECKeyWithoutPublic));
if (key == NULL || inp != kECKeyWithoutPublic + sizeof(kECKeyWithoutPublic)) {
fprintf(stderr, "Failed to parse private key.\n");
BIO_print_errors_fp(stderr);
goto out;
}
len = i2d_ECPrivateKey(key, NULL);
out = malloc(len);
outp = out;
if (len != i2d_ECPrivateKey(key, &outp)) {
fprintf(stderr, "Failed to serialize private key.\n");
BIO_print_errors_fp(stderr);
goto out;
}
if (0 != memcmp(out, kECKeyWithoutPublic, len)) {
fprintf(stderr, "Serialisation of key doesn't match original.\n");
goto out;
}
public = EC_KEY_get0_public_key(key);
if (public == NULL) {
fprintf(stderr, "Public key missing.\n");
goto out;
}
x = BN_new();
y = BN_new();
if (x == NULL || y == NULL) {
goto out;
}
if (!EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(key), public, x, y,
NULL)) {
fprintf(stderr, "Failed to get public key in affine coordinates.\n");
goto out;
}
x_hex = BN_bn2hex(x);
y_hex = BN_bn2hex(y);
if (0 != strcmp(x_hex, "c81561ecf2e54edefe6617db1c7a34a70744ddb261f269b83dacfcd2ade5a681") ||
0 != strcmp(y_hex, "e0e2afa3f9b6abe4c698ef6495f1be49a3196c5056acb3763fe4507eec596e88")) {
fprintf(stderr, "Incorrect public key: %s %s\n", x_hex, y_hex);
goto out;
}
ret = 1;
out:
if (key != NULL) {
EC_KEY_free(key);
}
if (out != NULL) {
free(out);
}
if (x != NULL) {
BN_free(x);
}
if (y != NULL) {
BN_free(y);
}
if (x_hex != NULL) {
OPENSSL_free(x_hex);
}
if (y_hex != NULL) {
OPENSSL_free(y_hex);
}
return ret;
}
int main(void) {
CRYPTO_library_init();
ERR_load_crypto_strings();
if (!test_d2i_ECPrivateKey()) {
fprintf(stderr, "failed\n");
return 1;
}
printf("PASS\n");
return 0;
}
-1
View File
@@ -199,7 +199,6 @@ struct ec_group_st {
BIGNUM order, cofactor;
int curve_name; /* optional NID for named curve */
point_conversion_form_t asn1_form;
struct ec_pre_comp_st *pre_comp;
+26 -45
View File
@@ -81,11 +81,10 @@ static size_t ec_GFp_simple_point2oct(const EC_GROUP *group,
BN_CTX *new_ctx = NULL;
int used_ctx = 0;
BIGNUM *x, *y;
size_t field_len, i, skip;
size_t field_len, i;
if ((form != POINT_CONVERSION_COMPRESSED) &&
(form != POINT_CONVERSION_UNCOMPRESSED) &&
(form != POINT_CONVERSION_HYBRID)) {
(form != POINT_CONVERSION_UNCOMPRESSED)) {
OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point2oct, EC_R_INVALID_FORM);
goto err;
}
@@ -117,58 +116,43 @@ static size_t ec_GFp_simple_point2oct(const EC_GROUP *group,
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
if (ctx == NULL) {
return 0;
}
}
BN_CTX_start(ctx);
used_ctx = 1;
x = BN_CTX_get(ctx);
y = BN_CTX_get(ctx);
if (y == NULL)
if (y == NULL) {
goto err;
}
if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx))
if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) {
goto err;
}
if ((form == POINT_CONVERSION_COMPRESSED ||
form == POINT_CONVERSION_HYBRID) &&
BN_is_odd(y))
if ((form == POINT_CONVERSION_COMPRESSED) &&
BN_is_odd(y)) {
buf[0] = form + 1;
else
} else {
buf[0] = form;
}
i = 1;
skip = field_len - BN_num_bytes(x);
if (skip > field_len) {
OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point2oct, ERR_R_INTERNAL_ERROR);
goto err;
}
while (skip > 0) {
buf[i++] = 0;
skip--;
}
skip = BN_bn2bin(x, buf + i);
i += skip;
if (i != 1 + field_len) {
if (!BN_bn2bin_padded(buf + i, field_len, x)) {
OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point2oct, ERR_R_INTERNAL_ERROR);
goto err;
}
i += field_len;
if (form == POINT_CONVERSION_UNCOMPRESSED ||
form == POINT_CONVERSION_HYBRID) {
skip = field_len - BN_num_bytes(y);
if (skip > field_len) {
if (form == POINT_CONVERSION_UNCOMPRESSED) {
if (!BN_bn2bin_padded(buf + i, field_len, y)) {
OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point2oct, ERR_R_INTERNAL_ERROR);
goto err;
}
while (skip > 0) {
buf[i++] = 0;
skip--;
}
skip = BN_bn2bin(y, buf + i);
i += skip;
i += field_len;
}
if (i != ret) {
@@ -177,17 +161,21 @@ static size_t ec_GFp_simple_point2oct(const EC_GROUP *group,
}
}
if (used_ctx)
if (used_ctx) {
BN_CTX_end(ctx);
if (new_ctx != NULL)
}
if (new_ctx != NULL) {
BN_CTX_free(new_ctx);
}
return ret;
err:
if (used_ctx)
if (used_ctx) {
BN_CTX_end(ctx);
if (new_ctx != NULL)
}
if (new_ctx != NULL) {
BN_CTX_free(new_ctx);
}
return 0;
}
@@ -210,8 +198,7 @@ static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
y_bit = form & 1;
form = form & ~1U;
if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED) &&
(form != POINT_CONVERSION_UNCOMPRESSED) &&
(form != POINT_CONVERSION_HYBRID)) {
(form != POINT_CONVERSION_UNCOMPRESSED)) {
OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING);
return 0;
}
@@ -267,12 +254,6 @@ static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING);
goto err;
}
if (form == POINT_CONVERSION_HYBRID) {
if (y_bit != BN_is_odd(y)) {
OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING);
goto err;
}
}
if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
goto err;
+3 -2
View File
@@ -1338,9 +1338,10 @@ err:
}
if (prod_Z != NULL) {
for (i = 0; i < num; i++) {
if (prod_Z[i] != NULL) {
BN_clear_free(prod_Z[i]);
if (prod_Z[i] == NULL) {
break;
}
BN_clear_free(prod_Z[i]);
}
OPENSSL_free(prod_Z);
}
+7 -4
View File
@@ -389,13 +389,16 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
sizeof wNAF[0]); /* includes space for pivot */
val_sub = OPENSSL_malloc(totalnum * sizeof val_sub[0]);
/* Ensure wNAF is initialised in case we end up going to err. */
if (wNAF) {
wNAF[0] = NULL; /* preliminary pivot */
}
if (!wsize || !wNAF_len || !wNAF || !val_sub) {
OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, ERR_R_MALLOC_FAILURE);
goto err;
}
wNAF[0] = NULL; /* preliminary pivot */
/* num_val will be the total number of temporarily precomputed points */
num_val = 0;
@@ -443,8 +446,8 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
* as the wNAF belonging to the generator,
* so wNAF splitting will not buy us anything. */
numblocks = 1;
totalnum = num + 1; /* don't use wNAF splitting */
numblocks = 1; /* don't use wNAF splitting */
totalnum = num + numblocks;
wNAF[num] = tmp_wNAF;
wNAF[num + 1] = NULL;
wNAF_len[num] = tmp_len;
+3 -9
View File
@@ -81,7 +81,7 @@ int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
const BIGNUM *priv;
const EC_GROUP *group;
int ret = -1;
size_t buflen, len;
size_t buflen;
uint8_t *buf = NULL;
if ((ctx = BN_CTX_new()) == NULL) {
@@ -116,20 +116,14 @@ int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
}
buflen = (EC_GROUP_get_degree(group) + 7) / 8;
len = BN_num_bytes(x);
if (len > buflen) {
OPENSSL_PUT_ERROR(ECDH, ECDH_compute_key, ERR_R_INTERNAL_ERROR);
goto err;
}
buf = OPENSSL_malloc(buflen);
if (buf == NULL) {
OPENSSL_PUT_ERROR(ECDH, ECDH_compute_key, ERR_R_MALLOC_FAILURE);
goto err;
}
memset(buf, 0, buflen - len);
if (len != (size_t)BN_bn2bin(x, buf + buflen - len)) {
OPENSSL_PUT_ERROR(ECDH, ECDH_compute_key, ERR_R_BN_LIB);
if (!BN_bn2bin_padded(buf, buflen, x)) {
OPENSSL_PUT_ERROR(ECDH, ECDH_compute_key, ERR_R_INTERNAL_ERROR);
goto err;
}
+14 -1
View File
@@ -74,18 +74,31 @@ int ECDSA_verify(int type, const uint8_t *digest, size_t digest_len,
const uint8_t *sig, size_t sig_len, EC_KEY *eckey) {
ECDSA_SIG *s;
int ret = 0;
uint8_t *der = NULL;
if (eckey->ecdsa_meth && eckey->ecdsa_meth->verify) {
return eckey->ecdsa_meth->verify(digest, digest_len, sig, sig_len, eckey);
}
s = ECDSA_SIG_new();
if (s == NULL || d2i_ECDSA_SIG(&s, &sig, sig_len) == NULL) {
const uint8_t *sigp = sig;
if (s == NULL || d2i_ECDSA_SIG(&s, &sigp, sig_len) == NULL ||
sigp != sig + sig_len) {
goto err;
}
/* Ensure that the signature uses DER and doesn't have trailing garbage. */
const int der_len = i2d_ECDSA_SIG(s, &der);
if (der_len < 0 || (size_t) der_len != sig_len || memcmp(sig, der, sig_len)) {
goto err;
}
ret = ECDSA_do_verify(digest, digest_len, s, eckey);
err:
if (der != NULL) {
OPENSSL_free(der);
}
if (s != NULL) {
ECDSA_SIG_free(s);
}
+31 -14
View File
@@ -66,21 +66,27 @@ int test_builtin(BIO *out) {
size_t n = 0;
EC_KEY *eckey = NULL, *wrong_eckey = NULL;
EC_GROUP *group;
BIGNUM *order = NULL;
ECDSA_SIG *ecdsa_sig = NULL;
unsigned char digest[20], wrong_digest[20];
unsigned char *signature = NULL;
const unsigned char *sig_ptr;
unsigned char *sig_ptr2;
unsigned char *raw_buf = NULL;
unsigned int sig_len, degree, r_len, s_len, bn_len, buf_len;
unsigned int sig_len, r_len, s_len, bn_len, buf_len;
int nid, ret = 0;
/* fill digest values with some random data */
if (!RAND_pseudo_bytes(digest, 20) || !RAND_pseudo_bytes(wrong_digest, 20)) {
if (!RAND_bytes(digest, 20) || !RAND_bytes(wrong_digest, 20)) {
BIO_printf(out, "ERROR: unable to get random data\n");
goto builtin_err;
}
order = BN_new();
if (order == NULL) {
goto builtin_err;
}
/* create and verify a ecdsa signature with every availble curve
* (with ) */
BIO_printf(out,
@@ -108,8 +114,10 @@ int test_builtin(BIO *out) {
goto builtin_err;
}
EC_GROUP_free(group);
degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey));
if (degree < 160) {
if (!EC_GROUP_get_order(EC_KEY_get0_group(eckey), order, NULL)) {
goto builtin_err;
}
if (BN_num_bits(order) < 160) {
/* Too small to test. */
EC_KEY_free(eckey);
eckey = NULL;
@@ -203,20 +211,21 @@ int test_builtin(BIO *out) {
/* Store the two BIGNUMs in raw_buf. */
r_len = BN_num_bytes(ecdsa_sig->r);
s_len = BN_num_bytes(ecdsa_sig->s);
bn_len = (degree + 7) / 8;
bn_len = BN_num_bytes(order);
if (r_len > bn_len || s_len > bn_len) {
BIO_printf(out, " failed\n");
goto builtin_err;
}
buf_len = 2 * bn_len;
raw_buf = OPENSSL_malloc(buf_len);
raw_buf = OPENSSL_malloc(2 * bn_len);
if (raw_buf == NULL) {
goto builtin_err;
}
/* Pad the bignums with leading zeroes. */
memset(raw_buf, 0, buf_len);
BN_bn2bin(ecdsa_sig->r, raw_buf + bn_len - r_len);
BN_bn2bin(ecdsa_sig->s, raw_buf + buf_len - s_len);
if (!BN_bn2bin_padded(raw_buf, bn_len, ecdsa_sig->r) ||
!BN_bn2bin_padded(raw_buf + bn_len, bn_len, ecdsa_sig->s)) {
goto builtin_err;
}
/* Modify a single byte in the buffer. */
offset = raw_buf[10] % buf_len;
@@ -268,16 +277,24 @@ int test_builtin(BIO *out) {
ret = 1;
builtin_err:
if (eckey)
if (eckey) {
EC_KEY_free(eckey);
if (wrong_eckey)
}
if (order) {
BN_free(order);
}
if (wrong_eckey) {
EC_KEY_free(wrong_eckey);
if (ecdsa_sig)
}
if (ecdsa_sig) {
ECDSA_SIG_free(ecdsa_sig);
if (signature)
}
if (signature) {
OPENSSL_free(signature);
if (raw_buf)
}
if (raw_buf) {
OPENSSL_free(raw_buf);
}
return ret;
}
+35 -10
View File
@@ -175,12 +175,12 @@ static uint32_t get_error_values(int inc, int top, const char **file, int *line,
uint32_t ret;
state = err_get_state();
if (state->bottom == state->top) {
if (state == NULL || state->bottom == state->top) {
return 0;
}
if (top) {
assert(!inc);
/* last error */
i = state->top;
} else {
@@ -211,14 +211,21 @@ static uint32_t get_error_values(int inc, int top, const char **file, int *line,
if (flags != NULL) {
*flags = error->flags & ERR_FLAG_PUBLIC_MASK;
}
if (error->flags & ERR_FLAG_MALLOCED) {
if (state->to_free) {
OPENSSL_free(state->to_free);
/* If this error is being removed, take ownership of data from
* the error. The semantics are such that the caller doesn't
* take ownership either. Instead the error system takes
* ownership and retains it until the next call that affects the
* error queue. */
if (inc) {
if (error->flags & ERR_FLAG_MALLOCED) {
if (state->to_free) {
OPENSSL_free(state->to_free);
}
state->to_free = error->data;
}
state->to_free = error->data;
error->data = NULL;
error->flags = 0;
}
error->data = NULL;
error->flags = 0;
}
}
@@ -274,6 +281,10 @@ void ERR_clear_error(void) {
ERR_STATE *const state = err_get_state();
unsigned i;
if (state == NULL) {
return;
}
for (i = 0; i < ERR_NUM_ERRORS; i++) {
err_clear(&state->errors[i]);
}
@@ -473,7 +484,10 @@ static void err_set_error_data(char *data, int flags) {
ERR_STATE *const state = err_get_state();
struct err_error_st *error;
if (state->top == state->bottom) {
if (state == NULL || state->top == state->bottom) {
if (flags & ERR_FLAG_MALLOCED) {
OPENSSL_free(data);
}
return;
}
@@ -489,6 +503,10 @@ void ERR_put_error(int library, int func, int reason, const char *file,
ERR_STATE *const state = err_get_state();
struct err_error_st *error;
if (state == NULL) {
return;
}
if (library == ERR_LIB_SYS && reason == 0) {
#if defined(WIN32)
reason = GetLastError();
@@ -589,7 +607,7 @@ void ERR_add_error_dataf(const char *format, ...) {
int ERR_set_mark(void) {
ERR_STATE *const state = err_get_state();
if (state->bottom == state->top) {
if (state == NULL || state->bottom == state->top) {
return 0;
}
state->errors[state->top].flags |= ERR_FLAG_MARK;
@@ -600,6 +618,10 @@ int ERR_pop_to_mark(void) {
ERR_STATE *const state = err_get_state();
struct err_error_st *error;
if (state == NULL) {
return 0;
}
while (state->bottom != state->top) {
error = &state->errors[state->top];
@@ -656,6 +678,7 @@ static const char *const kLibraryNames[ERR_NUM_LIBS] = {
"Digest functions", /* ERR_LIB_DIGEST */
"Cipher functions", /* ERR_LIB_CIPHER */
"User defined functions", /* ERR_LIB_USER */
"HKDF functions", /* ERR_LIB_HKDF */
};
#define NUM_SYS_ERRNOS 127
@@ -700,6 +723,7 @@ extern const ERR_STRING_DATA ECDSA_error_string_data[];
extern const ERR_STRING_DATA EC_error_string_data[];
extern const ERR_STRING_DATA ENGINE_error_string_data[];
extern const ERR_STRING_DATA EVP_error_string_data[];
extern const ERR_STRING_DATA HKDF_error_string_data[];
extern const ERR_STRING_DATA OBJ_error_string_data[];
extern const ERR_STRING_DATA PEM_error_string_data[];
extern const ERR_STRING_DATA PKCS8_error_string_data[];
@@ -754,6 +778,7 @@ static void err_load_strings(void) {
ERR_load_strings(EC_error_string_data);
ERR_load_strings(ENGINE_error_string_data);
ERR_load_strings(EVP_error_string_data);
ERR_load_strings(HKDF_error_string_data);
ERR_load_strings(OBJ_error_string_data);
ERR_load_strings(PEM_error_string_data);
ERR_load_strings(PKCS8_error_string_data);
+5
View File
@@ -231,6 +231,11 @@ static ERR_STATE *err_get_state(void) {
CRYPTO_r_lock(CRYPTO_LOCK_ERR);
}
if (state_hash == NULL) {
CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
return NULL;
}
state = lh_ERR_STATE_retrieve(state_hash, &pattern);
CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
if (state != NULL) {
+20 -5
View File
@@ -23,11 +23,15 @@ static int test_overflow(void) {
unsigned i;
for (i = 0; i < ERR_NUM_ERRORS*2; i++) {
ERR_put_error(1, 2, 3, "test", 1);
ERR_put_error(1, 2, i+1, "test", 1);
}
for (i = 0; i < ERR_NUM_ERRORS - 1; i++) {
if (ERR_get_error() == 0) {
uint32_t err = ERR_get_error();
/* Errors are returned in order they were pushed, with the least recent ones
* removed, up to |ERR_NUM_ERRORS - 1| errors. So the errors returned are
* |ERR_NUM_ERRORS + 2| through |ERR_NUM_ERRORS * 2|, inclusive. */
if (err == 0 || ERR_GET_REASON(err) != i + ERR_NUM_ERRORS + 2) {
fprintf(stderr, "ERR_get_error failed at %u\n", i);
return 0;
}
@@ -42,9 +46,9 @@ static int test_overflow(void) {
}
static int test_put_error(void) {
uint32_t packed_error;
int line, flags;
const char *file, *data;
uint32_t peeked_packed_error, packed_error;
int peeked_line, line, peeked_flags, flags;
const char *peeked_file, *file, *peeked_data, *data;
if (ERR_get_error() != 0) {
fprintf(stderr, "ERR_get_error returned value before an error was added.\n");
@@ -54,7 +58,18 @@ static int test_put_error(void) {
ERR_put_error(1, 2, 3, "test", 4);
ERR_add_error_data(1, "testing");
peeked_packed_error = ERR_peek_error_line_data(&peeked_file, &peeked_line,
&peeked_data, &peeked_flags);
packed_error = ERR_get_error_line_data(&file, &line, &data, &flags);
if (peeked_packed_error != packed_error ||
peeked_file != file ||
peeked_data != data ||
peeked_flags != flags) {
fprintf(stderr, "Bad peeked error data returned.\n");
return 0;
}
if (strcmp(file, "test") != 0 ||
line != 4 ||
(flags & ERR_FLAG_STRING) == 0 ||
+7
View File
@@ -124,6 +124,13 @@ int EVP_PKEY_is_opaque(const EVP_PKEY *pkey) {
return 0;
}
int EVP_PKEY_supports_digest(const EVP_PKEY *pkey, const EVP_MD *md) {
if (pkey->ameth && pkey->ameth->pkey_supports_digest) {
return pkey->ameth->pkey_supports_digest(pkey, md);
}
return 1;
}
int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) {
if (a->type != b->type) {
return -1;
+16 -1
View File
@@ -124,7 +124,10 @@ static EVP_PKEY_CTX *evp_pkey_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) {
if (pmeth->init) {
if (pmeth->init(ret) <= 0) {
EVP_PKEY_CTX_free(ret);
if (pkey) {
EVP_PKEY_free(ret->pkey);
}
OPENSSL_free(ret);
return NULL;
}
}
@@ -176,17 +179,25 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx) {
if (pctx->pkey) {
rctx->pkey = EVP_PKEY_dup(pctx->pkey);
if (rctx->pkey == NULL) {
goto err;
}
}
if (pctx->peerkey) {
rctx->peerkey = EVP_PKEY_dup(pctx->peerkey);
if (rctx->peerkey == NULL) {
goto err;
}
}
if (pctx->pmeth->copy(rctx, pctx) > 0) {
return rctx;
}
err:
EVP_PKEY_CTX_free(rctx);
OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_dup, ERR_LIB_EVP);
return NULL;
}
@@ -485,6 +496,10 @@ int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) {
if (!*ppkey) {
*ppkey = EVP_PKEY_new();
if (!*ppkey) {
OPENSSL_PUT_ERROR(EVP, EVP_PKEY_keygen, ERR_LIB_EVP);
return 0;
}
}
if (!ctx->pmeth->keygen(ctx, *ppkey)) {
+1
View File
@@ -20,6 +20,7 @@ const ERR_STRING_DATA EVP_error_string_data[] = {
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DigestSignAlgorithm, 0), "EVP_DigestSignAlgorithm"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DigestVerifyInitFromAlgorithm, 0), "EVP_DigestVerifyInitFromAlgorithm"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_ctrl, 0), "EVP_PKEY_CTX_ctrl"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_dup, 0), "EVP_PKEY_CTX_dup"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_copy_parameters, 0), "EVP_PKEY_copy_parameters"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_decrypt, 0), "EVP_PKEY_decrypt"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_decrypt_init, 0), "EVP_PKEY_decrypt_init"},
+53
View File
@@ -229,6 +229,20 @@ static const uint8_t kExampleECKeyDER[] = {
0xc1,
};
/* kExampleBadECKeyDER is a sample EC private key encoded as an ECPrivateKey
* structure. The private key is equal to the order and will fail to import */
static const uint8_t kExampleBadECKeyDER[] = {
0x30, 0x66, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48,
0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03,
0x01, 0x07, 0x04, 0x4C, 0x30, 0x4A, 0x02, 0x01, 0x01, 0x04, 0x20, 0xFF,
0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, 0xF3,
0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51, 0xA1, 0x23, 0x03, 0x21, 0x00,
0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51
};
static EVP_PKEY *load_example_rsa_key(void) {
EVP_PKEY *ret = NULL;
const uint8_t *derp = kExampleRSAKeyDER;
@@ -539,6 +553,40 @@ done:
return ret;
}
/* Tests loading a bad key in PKCS8 format */
static int test_EVP_PKCS82PKEY(void) {
int ret = 0;
const uint8_t *derp = kExampleBadECKeyDER;
PKCS8_PRIV_KEY_INFO *p8inf = NULL;
EVP_PKEY *pkey = NULL;
p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &derp, sizeof(kExampleBadECKeyDER));
if (!p8inf || derp != kExampleBadECKeyDER + sizeof(kExampleBadECKeyDER)) {
fprintf(stderr, "Failed to parse key\n");
goto done;
}
pkey = EVP_PKCS82PKEY(p8inf);
if (pkey) {
fprintf(stderr, "Imported invalid EC key\n");
goto done;
}
ret = 1;
done:
if (p8inf != NULL) {
PKCS8_PRIV_KEY_INFO_free(p8inf);
}
if (pkey != NULL) {
EVP_PKEY_free(pkey);
}
return ret;
}
int main(void) {
CRYPTO_library_init();
ERR_load_crypto_strings();
@@ -581,6 +629,11 @@ int main(void) {
return 1;
}
if (!test_EVP_PKCS82PKEY()) {
fprintf(stderr, "test_EVP_PKCS82PKEY failed\n");
return 1;
}
printf("PASS\n");
return 0;
}
+6 -1
View File
@@ -106,6 +106,12 @@ struct evp_pkey_asn1_method_st {
* custom implementations which do not expose key material and parameters.*/
int (*pkey_opaque)(const EVP_PKEY *pk);
/* pkey_supports_digest returns one if |pkey| supports digests of
* type |md|. This is intended for use with EVP_PKEYs backing custom
* implementations which can't sign all digests. If null, it is
* assumed that all digests are supported. */
int (*pkey_supports_digest)(const EVP_PKEY *pkey, const EVP_MD *md);
int (*pkey_size)(const EVP_PKEY *pk);
int (*pkey_bits)(const EVP_PKEY *pk);
@@ -121,7 +127,6 @@ struct evp_pkey_asn1_method_st {
void (*pkey_free)(EVP_PKEY *pkey);
int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2);
/* Legacy functions for old PEM */
+1 -12
View File
@@ -538,17 +538,6 @@ static int old_ec_priv_encode(const EVP_PKEY *pkey, uint8_t **pder) {
return i2d_ECPrivateKey(pkey->pkey.ec, pder);
}
static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) {
switch (op) {
case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
*(int *)arg2 = NID_sha1;
return 2;
default:
return -2;
}
}
const EVP_PKEY_ASN1_METHOD ec_asn1_meth = {
EVP_PKEY_EC,
EVP_PKEY_EC,
@@ -566,6 +555,7 @@ const EVP_PKEY_ASN1_METHOD ec_asn1_meth = {
eckey_priv_print,
eckey_opaque,
0 /* pkey_supports_digest */,
int_ec_size,
ec_bits,
@@ -579,7 +569,6 @@ const EVP_PKEY_ASN1_METHOD ec_asn1_meth = {
0,
int_ec_free,
ec_pkey_ctrl,
old_ec_priv_decode,
old_ec_priv_encode
};
+4
View File
@@ -109,6 +109,10 @@ static int pkey_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) {
static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx) {
HMAC_PKEY_CTX *hctx = ctx->data;
if (hctx == NULL) {
return;
}
HMAC_CTX_cleanup(&hctx->ctx);
if (hctx->ktmp.data) {
if (hctx->ktmp.length) {
+2 -13
View File
@@ -75,26 +75,15 @@ static void hmac_key_free(EVP_PKEY *pkey) {
}
}
static int hmac_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) {
switch (op) {
case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
*(int *)arg2 = NID_sha1;
return 1;
default:
return -2;
}
}
const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = {
EVP_PKEY_HMAC, EVP_PKEY_HMAC, 0 /* flags */,
"HMAC", "OpenSSL HMAC method", 0 /* pub_decode */,
0 /* pub_encode */, 0 /* pub_cmp */, 0 /* pub_print */,
0 /*priv_decode */, 0 /* priv_encode */, 0 /* priv_print */,
0 /* pkey_opaque */,
0 /* pkey_opaque */, 0 /* pkey_supports_digest */,
hmac_size, 0 /* pkey_bits */, 0 /* param_decode */,
0 /* param_encode*/, 0 /* param_missing*/, 0 /* param_copy*/,
0 /* param_cmp*/, 0 /* param_print*/, 0 /* sig_print*/,
hmac_key_free, hmac_pkey_ctrl, 0 /* old_priv_decode */,
hmac_key_free, 0 /* old_priv_decode */,
0 /* old_priv_encode */
};
+5 -19
View File
@@ -153,6 +153,10 @@ static int rsa_opaque(const EVP_PKEY *pkey) {
return RSA_is_opaque(pkey->pkey.rsa);
}
static int rsa_supports_digest(const EVP_PKEY *pkey, const EVP_MD *md) {
return RSA_supports_digest(pkey->pkey.rsa, md);
}
static int int_rsa_size(const EVP_PKEY *pkey) {
return RSA_size(pkey->pkey.rsa);
}
@@ -409,24 +413,6 @@ static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
return 1;
}
static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) {
X509_ALGOR *alg = NULL;
switch (op) {
case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
*(int *)arg2 = NID_sha1;
return 1;
default:
return -2;
}
if (alg) {
X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0);
}
return 1;
}
static int old_rsa_priv_decode(EVP_PKEY *pkey, const unsigned char **pder,
int derlen) {
RSA *rsa = d2i_RSAPrivateKey(NULL, pder, derlen);
@@ -701,6 +687,7 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meth = {
rsa_priv_print,
rsa_opaque,
rsa_supports_digest,
int_rsa_size,
rsa_bits,
@@ -709,7 +696,6 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meth = {
rsa_sig_print,
int_rsa_free,
rsa_pkey_ctrl,
old_rsa_priv_decode,
old_rsa_priv_encode,
+9 -3
View File
@@ -151,7 +151,7 @@ static uint32_t class_hash(const EX_CLASS_ITEM *a) {
return a->class_value;
}
/* class_cmp is a comparision function for an LHASH of |EX_CLASS_ITEM|
/* class_cmp is a comparison function for an LHASH of |EX_CLASS_ITEM|
* structures. */
static int class_cmp(const EX_CLASS_ITEM *a, const EX_CLASS_ITEM *b) {
return a->class_value - b->class_value;
@@ -193,8 +193,10 @@ static LHASH_OF(EX_CLASS_ITEM) *get_classes(void) {
static void cleanup(void) {
LHASH_OF(EX_CLASS_ITEM) *classes = get_classes();
lh_EX_CLASS_ITEM_doall(classes, class_free);
lh_EX_CLASS_ITEM_free(classes);
if (classes != NULL) {
lh_EX_CLASS_ITEM_doall(classes, class_free);
lh_EX_CLASS_ITEM_free(classes);
}
global_classes = NULL;
}
@@ -204,6 +206,10 @@ static EX_CLASS_ITEM *get_class(int class_value) {
EX_CLASS_ITEM template, *class_item;
int ok = 0;
if (classes == NULL) {
return NULL;
}
CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
template.class_value = class_value;
class_item = lh_EX_CLASS_ITEM_retrieve(classes, &template);
+18
View File
@@ -0,0 +1,18 @@
include_directories(. .. ../../include)
add_library(
hkdf
OBJECT
hkdf.c
hkdf_error.c
)
add_executable(
hkdf_test
hkdf_test.c
)
target_link_libraries(hkdf_test crypto)
+88
View File
@@ -0,0 +1,88 @@
/* Copyright (c) 2014, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <openssl/hkdf.h>
#include <assert.h>
#include <openssl/err.h>
#include <openssl/hmac.h>
int HKDF(uint8_t *out_key, size_t out_len,
const EVP_MD *digest,
const uint8_t *secret, size_t secret_len,
const uint8_t *salt, size_t salt_len,
const uint8_t *info, size_t info_len) {
/* https://tools.ietf.org/html/rfc5869#section-2.2 */
const size_t digest_len = EVP_MD_size(digest);
uint8_t prk[EVP_MAX_MD_SIZE], previous[EVP_MAX_MD_SIZE];
size_t n, done = 0;
unsigned i, prk_len;
int ret = 0;
HMAC_CTX hmac;
/* If salt is not given, HashLength zeros are used. However, HMAC does that
* internally already so we can ignore it.*/
/* Expand key material to desired length. */
n = (out_len + digest_len - 1) / digest_len;
if (out_len + digest_len < out_len || n > 255) {
OPENSSL_PUT_ERROR(HKDF, HKDF, HKDF_R_OUTPUT_TOO_LARGE);
return 0;
}
HMAC_CTX_init(&hmac);
/* Extract input keying material into pseudorandom key |prk|. */
if (HMAC(digest, salt, salt_len, secret, secret_len, prk, &prk_len) == NULL) {
goto out;
}
assert(prk_len == digest_len);
if (!HMAC_Init_ex(&hmac, prk, prk_len, digest, NULL)) {
goto out;
}
for (i = 0; i < n; i++) {
uint8_t ctr = i + 1;
size_t todo;
if (i != 0 && (!HMAC_Init_ex(&hmac, NULL, 0, NULL, NULL) ||
!HMAC_Update(&hmac, previous, digest_len))) {
goto out;
}
if (!HMAC_Update(&hmac, info, info_len) ||
!HMAC_Update(&hmac, &ctr, 1) ||
!HMAC_Final(&hmac, previous, NULL)) {
goto out;
}
todo = digest_len;
if (done + todo > out_len) {
todo = out_len - done;
}
memcpy(out_key + done, previous, todo);
done += todo;
}
ret = 1;
out:
HMAC_CTX_cleanup(&hmac);
if (ret != 1) {
OPENSSL_PUT_ERROR(HKDF, HKDF, ERR_R_HMAC_LIB);
}
return ret;
}
+23
View File
@@ -0,0 +1,23 @@
/* Copyright (c) 2014, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <openssl/err.h>
#include <openssl/hkdf.h>
const ERR_STRING_DATA HKDF_error_string_data[] = {
{ERR_PACK(ERR_LIB_HKDF, HKDF_F_HKDF, 0), "HKDF"},
{ERR_PACK(ERR_LIB_HKDF, 0, HKDF_R_OUTPUT_TOO_LARGE), "OUTPUT_TOO_LARGE"},
{0, NULL},
};
+239
View File
@@ -0,0 +1,239 @@
/* Copyright (c) 2014, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <stdio.h>
#include <openssl/bio.h>
#include <openssl/crypto.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/hkdf.h>
typedef struct {
const EVP_MD *(*md_func)(void);
const uint8_t ikm[80];
const size_t ikm_len;
const uint8_t salt[80];
const size_t salt_len;
const uint8_t info[80];
const size_t info_len;
const size_t out_len;
const uint8_t out[82];
} hkdf_test_vector_t;
/* These test vectors are from RFC 5869. */
static const hkdf_test_vector_t kTests[] = {
{
EVP_sha256,
{
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
}, 22,
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
0x0c,
}, 13,
{
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
}, 10,
42, {
0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, 0x90, 0x43, 0x4f, 0x64,
0xd0, 0x36, 0x2f, 0x2a, 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c,
0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf, 0x34, 0x00, 0x72, 0x08,
0xd5, 0xb8, 0x87, 0x18, 0x58, 0x65
}
},
{
EVP_sha256,
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f
}, 80,
{
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf
}, 80,
{
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb,
0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3,
0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
}, 80,
82, {
0xb1, 0x1e, 0x39, 0x8d, 0xc8, 0x03, 0x27, 0xa1, 0xc8, 0xe7, 0xf7, 0x8c,
0x59, 0x6a, 0x49, 0x34, 0x4f, 0x01, 0x2e, 0xda, 0x2d, 0x4e, 0xfa, 0xd8,
0xa0, 0x50, 0xcc, 0x4c, 0x19, 0xaf, 0xa9, 0x7c, 0x59, 0x04, 0x5a, 0x99,
0xca, 0xc7, 0x82, 0x72, 0x71, 0xcb, 0x41, 0xc6, 0x5e, 0x59, 0x0e, 0x09,
0xda, 0x32, 0x75, 0x60, 0x0c, 0x2f, 0x09, 0xb8, 0x36, 0x77, 0x93, 0xa9,
0xac, 0xa3, 0xdb, 0x71, 0xcc, 0x30, 0xc5, 0x81, 0x79, 0xec, 0x3e, 0x87,
0xc1, 0x4c, 0x01, 0xd5, 0xc1, 0xf3, 0x43, 0x4f, 0x1d, 0x87
}
},
{
EVP_sha256,
{
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
}, 22,
{
0,
}, 0,
{
0,
}, 0,
42, {
0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f, 0x71, 0x5f, 0x80, 0x2a,
0x06, 0x3c, 0x5a, 0x31, 0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1, 0x87, 0x9e,
0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d, 0x9d, 0x20, 0x13, 0x95,
0xfa, 0xa4, 0xb6, 0x1a, 0x96, 0xc8
}
},
{
EVP_sha1,
{
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
}, 11,
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
0x0c,
}, 13,
{
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
}, 10,
42, {
0x08, 0x5a, 0x01, 0xea, 0x1b, 0x10, 0xf3, 0x69, 0x33, 0x06, 0x8b, 0x56,
0xef, 0xa5, 0xad, 0x81, 0xa4, 0xf1, 0x4b, 0x82, 0x2f, 0x5b, 0x09, 0x15,
0x68, 0xa9, 0xcd, 0xd4, 0xf1, 0x55, 0xfd, 0xa2, 0xc2, 0x2e, 0x42, 0x24,
0x78, 0xd3, 0x05, 0xf3, 0xf8, 0x96
}
},
{
EVP_sha1,
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f
}, 80,
{
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf
}, 80,
{
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb,
0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3,
0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
}, 80,
82, {
0x0b, 0xd7, 0x70, 0xa7, 0x4d, 0x11, 0x60, 0xf7, 0xc9, 0xf1, 0x2c, 0xd5,
0x91, 0x2a, 0x06, 0xeb, 0xff, 0x6a, 0xdc, 0xae, 0x89, 0x9d, 0x92, 0x19,
0x1f, 0xe4, 0x30, 0x56, 0x73, 0xba, 0x2f, 0xfe, 0x8f, 0xa3, 0xf1, 0xa4,
0xe5, 0xad, 0x79, 0xf3, 0xf3, 0x34, 0xb3, 0xb2, 0x02, 0xb2, 0x17, 0x3c,
0x48, 0x6e, 0xa3, 0x7c, 0xe3, 0xd3, 0x97, 0xed, 0x03, 0x4c, 0x7f, 0x9d,
0xfe, 0xb1, 0x5c, 0x5e, 0x92, 0x73, 0x36, 0xd0, 0x44, 0x1f, 0x4c, 0x43,
0x00, 0xe2, 0xcf, 0xf0, 0xd0, 0x90, 0x0b, 0x52, 0xd3, 0xb4
}
},
{
EVP_sha1,
{
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
}, 22,
{
0,
}, 0,
{
0,
}, 0,
42, {
0x0a, 0xc1, 0xaf, 0x70, 0x02, 0xb3, 0xd7, 0x61, 0xd1, 0xe5, 0x52, 0x98,
0xda, 0x9d, 0x05, 0x06, 0xb9, 0xae, 0x52, 0x05, 0x72, 0x20, 0xa3, 0x06,
0xe0, 0x7b, 0x6b, 0x87, 0xe8, 0xdf, 0x21, 0xd0, 0xea, 0x00, 0x03, 0x3d,
0xe0, 0x39, 0x84, 0xd3, 0x49, 0x18
}
},
{
EVP_sha1,
{
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
}, 22,
{
0,
}, 0,
{
0,
}, 0,
42, {
0x2c, 0x91, 0x11, 0x72, 0x04, 0xd7, 0x45, 0xf3, 0x50, 0x0d, 0x63, 0x6a,
0x62, 0xf6, 0x4f, 0x0a, 0xb3, 0xba, 0xe5, 0x48, 0xaa, 0x53, 0xd4, 0x23,
0xb0, 0xd1, 0xf2, 0x7e, 0xbb, 0xa6, 0xf5, 0xe5, 0x67, 0x3a, 0x08, 0x1d,
0x70, 0xcc, 0xe7, 0xac, 0xfc, 0x48
}
},
};
int main(void) {
uint8_t buf[82];
size_t i;
CRYPTO_library_init();
ERR_load_crypto_strings();
for (i = 0; i < sizeof(kTests) / sizeof(kTests[0]); i++) {
const hkdf_test_vector_t *test = &kTests[i];
if (!HKDF(buf, test->out_len, test->md_func(), test->ikm, test->ikm_len,
test->salt, test->salt_len, test->info, test->info_len)) {
fprintf(stderr, "Call to HKDF failed\n");
BIO_print_errors_fp(stderr);
return 1;
}
if (memcmp(buf, test->out, test->out_len) != 0) {
fprintf(stderr, "%u: Resulting key material does not match test vector\n",
(unsigned)i);
return 1;
}
}
printf("PASS\n");
ERR_free_strings();
return 0;
}
+7
View File
@@ -74,6 +74,13 @@ uint8_t *HMAC(const EVP_MD *evp_md, const void *key, size_t key_len,
out = static_out_buffer;
}
/* If key_len is 0, the value of key doesn't matter. However, if we pass
* key == NULL into HMAC_Init, it interprets it to mean "use the previous
* value" instead of using a key of length 0. */
if (key == NULL && key_len == 0) {
key = static_out_buffer;
}
HMAC_CTX_init(&ctx);
if (!HMAC_Init(&ctx, key, key_len, evp_md) ||
!HMAC_Update(&ctx, data, data_len) ||
+14
View File
@@ -145,6 +145,20 @@ int main(int argc, char *argv[]) {
}
}
/* Test that HMAC() functions corretly when called with key=NULL */
const struct test_st *test = &kTests[0];
if (NULL == HMAC(EVP_md5(), NULL, test->key_len, test->data,
test->data_len, out, &out_len)) {
printf("HMAC failed.\n");
err++;
}
p = to_hex(out, out_len);
if (strcmp(p, test->hex_digest) != 0) {
printf("got %s instead of %s\n", p, test->hex_digest);
err++;
}
if (err) {
return 1;
}
+147 -2
View File
@@ -132,7 +132,7 @@ struct st_CRYPTO_EX_DATA_IMPL {
};
#if defined(OPENSSL_WINDOWS)
#if defined(_MSC_VER)
#define OPENSSL_U64(x) x##UI64
#else
@@ -142,13 +142,158 @@ struct st_CRYPTO_EX_DATA_IMPL {
#define OPENSSL_U64(x) x##ULL
#endif
#endif /* OPENSSL_WINDOWS */
#endif /* defined(_MSC_VER) */
#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
/* OPENSSL_cpuid_setup initializes OPENSSL_ia32cap_P. */
void OPENSSL_cpuid_setup(void);
#endif
#if !defined(inline)
#define inline __inline
#endif
/* Constant-time utility functions.
*
* The following methods return a bitmask of all ones (0xff...f) for true and 0
* for false. This is useful for choosing a value based on the result of a
* conditional in constant time. For example,
*
* if (a < b) {
* c = a;
* } else {
* c = b;
* }
*
* can be written as
*
* unsigned int lt = constant_time_lt(a, b);
* c = constant_time_select(lt, a, b); */
/* constant_time_msb returns the given value with the MSB copied to all the
* other bits. */
static inline unsigned int constant_time_msb(unsigned int a) {
return (unsigned int)((int)(a) >> (sizeof(int) * 8 - 1));
}
/* constant_time_lt returns 0xff..f if a < b and 0 otherwise. */
static inline unsigned int constant_time_lt(unsigned int a, unsigned int b) {
/* Consider the two cases of the problem:
* msb(a) == msb(b): a < b iff the MSB of a - b is set.
* msb(a) != msb(b): a < b iff the MSB of b is set.
*
* If msb(a) == msb(b) then the following evaluates as:
* msb(a^((a^b)|((a-b)^a))) ==
* msb(a^((a-b) ^ a)) == (because msb(a^b) == 0)
* msb(a^a^(a-b)) == (rearranging)
* msb(a-b) (because x. x^x == 0)
*
* Else, if msb(a) != msb(b) then the following evaluates as:
* msb(a^((a^b)|((a-b)^a))) ==
* msb(a^(𝟙 | ((a-b)^a))) == (because msb(a^b) == 1 and 𝟙
* represents a value s.t. msb(𝟙) = 1)
* msb(a^𝟙) == (because ORing with 1 results in 1)
* msb(b)
*
*
* Here is an SMT-LIB verification of this formula:
*
* (define-fun lt ((a (_ BitVec 32)) (b (_ BitVec 32))) (_ BitVec 32)
* (bvxor a (bvor (bvxor a b) (bvxor (bvsub a b) a)))
* )
*
* (declare-fun a () (_ BitVec 32))
* (declare-fun b () (_ BitVec 32))
*
* (assert (not (= (= #x00000001 (bvlshr (lt a b) #x0000001f)) (bvult a b))))
* (check-sat)
* (get-model)
*/
return constant_time_msb(a^((a^b)|((a-b)^a)));
}
/* constant_time_lt_8 acts like |constant_time_lt| but returns an 8-bit mask. */
static inline uint8_t constant_time_lt_8(unsigned int a, unsigned int b) {
return (uint8_t)(constant_time_lt(a, b));
}
/* constant_time_gt returns 0xff..f if a >= b and 0 otherwise. */
static inline unsigned int constant_time_ge(unsigned int a, unsigned int b) {
return ~constant_time_lt(a, b);
}
/* constant_time_ge_8 acts like |constant_time_ge| but returns an 8-bit mask. */
static inline uint8_t constant_time_ge_8(unsigned int a, unsigned int b) {
return (uint8_t)(constant_time_ge(a, b));
}
/* constant_time_is_zero returns 0xff..f if a == 0 and 0 otherwise. */
static inline unsigned int constant_time_is_zero(unsigned int a) {
/* Here is an SMT-LIB verification of this formula:
*
* (define-fun is_zero ((a (_ BitVec 32))) (_ BitVec 32)
* (bvand (bvnot a) (bvsub a #x00000001))
* )
*
* (declare-fun a () (_ BitVec 32))
*
* (assert (not (= (= #x00000001 (bvlshr (is_zero a) #x0000001f)) (= a #x00000000))))
* (check-sat)
* (get-model)
*/
return constant_time_msb(~a & (a - 1));
}
/* constant_time_is_zero_8 acts like constant_time_is_zero but returns an 8-bit
* mask. */
static inline uint8_t constant_time_is_zero_8(unsigned int a) {
return (uint8_t)(constant_time_is_zero(a));
}
/* constant_time_eq returns 0xff..f if a == b and 0 otherwise. */
static inline unsigned int constant_time_eq(unsigned int a, unsigned int b) {
return constant_time_is_zero(a ^ b);
}
/* constant_time_eq_8 acts like |constant_time_eq| but returns an 8-bit mask. */
static inline uint8_t constant_time_eq_8(unsigned int a, unsigned int b) {
return (uint8_t)(constant_time_eq(a, b));
}
/* constant_time_eq_int acts like |constant_time_eq| but works on int values. */
static inline unsigned int constant_time_eq_int(int a, int b) {
return constant_time_eq((unsigned)(a), (unsigned)(b));
}
/* constant_time_eq_int_8 acts like |constant_time_eq_int| but returns an 8-bit
* mask. */
static inline uint8_t constant_time_eq_int_8(int a, int b) {
return constant_time_eq_8((unsigned)(a), (unsigned)(b));
}
/* constant_time_select returns (mask & a) | (~mask & b). When |mask| is all 1s
* or all 0s (as returned by the methods above), the select methods return
* either |a| (if |mask| is nonzero) or |b| (if |mask| is zero). */
static inline unsigned int constant_time_select(unsigned int mask,
unsigned int a, unsigned int b) {
return (mask & a) | (~mask & b);
}
/* constant_time_select_8 acts like |constant_time_select| but operates on
* 8-bit values. */
static inline uint8_t constant_time_select_8(uint8_t mask, uint8_t a,
uint8_t b) {
return (uint8_t)(constant_time_select(mask, a, b));
}
/* constant_time_select_int acts like |constant_time_select| but operates on
* ints. */
static inline int constant_time_select_int(unsigned int mask, int a, int b) {
return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b)));
}
#if defined(__cplusplus)
} /* extern C */
#endif
-8
View File
@@ -28,11 +28,3 @@ add_library(
perlasm(md5-x86_64.${ASM_EXT} asm/md5-x86_64.pl)
perlasm(md5-586.${ASM_EXT} asm/md5-586.pl)
add_executable(
md5_test
md5_test.c
)
target_link_libraries(md5_test crypto)
+1 -1
View File
@@ -108,6 +108,7 @@ sub round4_step
EOF
}
no warnings qw(uninitialized);
my $flavour = shift;
my $output = shift || "";
if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
@@ -119,7 +120,6 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate;
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
no warnings qw(uninitialized);
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT=*OUT;
-103
View File
@@ -1,103 +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 <stdio.h>
#include <openssl/crypto.h>
#include <openssl/digest.h>
#include <openssl/md5.h>
static const char *const test[] = {
"", "a", "abc", "message digest", "abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
"12345678901234567890123456789012345678901234567890123456789012345678901234"
"567890",
NULL, };
static const char *const expected[] = {
"d41d8cd98f00b204e9800998ecf8427e", "0cc175b9c0f1b6a831c399e269772661",
"900150983cd24fb0d6963f7d28e17f72", "f96b697d7cb7938d525a2f31aaf161d0",
"c3fcd3d76192e4007dfb496cca67e13b", "d174ab98d277d9f5a5611c2c9f419d9f",
"57edf4a22be3c955ac49da2e2107b67a", };
int main(int argc, char **argv) {
size_t i, j;
uint8_t md[MD5_DIGEST_LENGTH];
char md_hex[sizeof(md) * 2 + 1];
int ok = 1;
CRYPTO_library_init();
for (i = 0; test[i] != NULL; i++) {
EVP_Digest(test[i], strlen(test[i]), md, NULL, EVP_md5(), NULL);
for (j = 0; j < sizeof(md); j++) {
sprintf(&md_hex[j * 2], "%02x", md[j]);
}
md_hex[MD5_DIGEST_LENGTH * 2] = 0;
if (strcmp(md_hex, expected[i]) != 0) {
fprintf(stderr, "#%u: got %s, wanted %s\n", (unsigned)i, md_hex,
expected[i]);
ok = 0;
}
}
if (ok) {
printf("PASS\n");
}
return ok ? 0 : 1;
}
+1
View File
@@ -64,6 +64,7 @@
# Ivy Bridge 1.80(+7%)
# Haswell 0.55(+93%) (if system doesn't support AVX)
# Bulldozer 1.49(+27%)
# Silvermont 2.88(+13%)
# March 2013
#
+37
View File
@@ -0,0 +1,37 @@
OID information is generated via a series of perl scripts. In order, the full
list of commands to run are:
perl objects.pl objects.txt obj_mac.num ../../include/openssl/obj_mac.h
perl obj_dat.pl ../../include/openssl/obj_mac.h obj_dat.h
perl obj_xref.pl obj_mac.num obj_xref.txt > obj_xref.h
objects.txt contains the list of all built-in OIDs. It is processed by
objects.pl to output obj_mac.num and obj_mac.h. obj_mac.num is the list of NID
values for each OID. This is an input/output parameter so NID values are stable
across regenerations. obj_mac.h is the header which defines macros for all the
built-in OIDs in C.
obj_mac.h is read by obj_dat.pl to generate obj_dat.h. obj_dat.h contains the
ASN1_OBJECTs corresponding to built-in OIDs themselves along with lookup tables
for search by short name, OID, etc.
obj_mac.num and obj_xref.txt are read by obj_xref.pl to generate
obj_xref.h. obj_xref.txt links signature OIDs to corresponding public key
algorithms and digests. obj_xref.h contains lookup tables for querying this
information in both directions.
Dependency graph:
objects.txt
|
V
[objects.pl] <--+
/ \ |
V V |
obj_mac.h obj_mac.num obj_xref.txt
| \ /
V V V
[obj_dat.pl] [obj_xref.pl]
| |
V V
obj_dat.h obj_xref.h
+36 -39
View File
@@ -1,6 +1,6 @@
/* THIS FILE IS GENERATED FROM objects.h by obj_dat.pl via the
* following command:
* perl obj_dat.pl obj_mac.h obj_dat.h */
* perl obj_dat.pl ../../include/openssl/obj_mac.h obj_dat.h */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
@@ -58,7 +58,7 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
#define NUM_NID 951
#define NUM_NID 948
#define NUM_SN 941
#define NUM_LN 941
#define NUM_OBJ 883
@@ -2451,9 +2451,6 @@ static const ASN1_OBJECT kObjects[NUM_NID]={
{"brainpoolP512t1","brainpoolP512t1",NID_brainpoolP512t1,9,
&(lvalues[6097]),0},
{"PSPECIFIED","pSpecified",NID_pSpecified,9,&(lvalues[6106]),0},
{NULL,NULL,NID_undef,0,NULL,0},
{NULL,NULL,NID_undef,0,NULL,0},
{NULL,NULL,NID_undef,0,NULL,0},
{"dhSinglePass-stdDH-sha1kdf-scheme",
"dhSinglePass-stdDH-sha1kdf-scheme",
NID_dhSinglePass_stdDH_sha1kdf_scheme,9,&(lvalues[6115]),0},
@@ -2769,19 +2766,19 @@ static const unsigned int kNIDsInShortNameOrder[NUM_SN]={
891, /* "deltaRevocationList" */
107, /* "description" */
871, /* "destinationIndicator" */
950, /* "dh-cofactor-kdf" */
949, /* "dh-std-kdf" */
947, /* "dh-cofactor-kdf" */
946, /* "dh-std-kdf" */
28, /* "dhKeyAgreement" */
944, /* "dhSinglePass-cofactorDH-sha1kdf-scheme" */
945, /* "dhSinglePass-cofactorDH-sha224kdf-scheme" */
946, /* "dhSinglePass-cofactorDH-sha256kdf-scheme" */
947, /* "dhSinglePass-cofactorDH-sha384kdf-scheme" */
948, /* "dhSinglePass-cofactorDH-sha512kdf-scheme" */
939, /* "dhSinglePass-stdDH-sha1kdf-scheme" */
940, /* "dhSinglePass-stdDH-sha224kdf-scheme" */
941, /* "dhSinglePass-stdDH-sha256kdf-scheme" */
942, /* "dhSinglePass-stdDH-sha384kdf-scheme" */
943, /* "dhSinglePass-stdDH-sha512kdf-scheme" */
941, /* "dhSinglePass-cofactorDH-sha1kdf-scheme" */
942, /* "dhSinglePass-cofactorDH-sha224kdf-scheme" */
943, /* "dhSinglePass-cofactorDH-sha256kdf-scheme" */
944, /* "dhSinglePass-cofactorDH-sha384kdf-scheme" */
945, /* "dhSinglePass-cofactorDH-sha512kdf-scheme" */
936, /* "dhSinglePass-stdDH-sha1kdf-scheme" */
937, /* "dhSinglePass-stdDH-sha224kdf-scheme" */
938, /* "dhSinglePass-stdDH-sha256kdf-scheme" */
939, /* "dhSinglePass-stdDH-sha384kdf-scheme" */
940, /* "dhSinglePass-stdDH-sha512kdf-scheme" */
920, /* "dhpublicnumber" */
382, /* "directory" */
887, /* "distinguishedName" */
@@ -3723,19 +3720,19 @@ static const unsigned int kNIDsInLongNameOrder[NUM_LN]={
107, /* "description" */
871, /* "destinationIndicator" */
80, /* "desx-cbc" */
950, /* "dh-cofactor-kdf" */
949, /* "dh-std-kdf" */
947, /* "dh-cofactor-kdf" */
946, /* "dh-std-kdf" */
28, /* "dhKeyAgreement" */
944, /* "dhSinglePass-cofactorDH-sha1kdf-scheme" */
945, /* "dhSinglePass-cofactorDH-sha224kdf-scheme" */
946, /* "dhSinglePass-cofactorDH-sha256kdf-scheme" */
947, /* "dhSinglePass-cofactorDH-sha384kdf-scheme" */
948, /* "dhSinglePass-cofactorDH-sha512kdf-scheme" */
939, /* "dhSinglePass-stdDH-sha1kdf-scheme" */
940, /* "dhSinglePass-stdDH-sha224kdf-scheme" */
941, /* "dhSinglePass-stdDH-sha256kdf-scheme" */
942, /* "dhSinglePass-stdDH-sha384kdf-scheme" */
943, /* "dhSinglePass-stdDH-sha512kdf-scheme" */
941, /* "dhSinglePass-cofactorDH-sha1kdf-scheme" */
942, /* "dhSinglePass-cofactorDH-sha224kdf-scheme" */
943, /* "dhSinglePass-cofactorDH-sha256kdf-scheme" */
944, /* "dhSinglePass-cofactorDH-sha384kdf-scheme" */
945, /* "dhSinglePass-cofactorDH-sha512kdf-scheme" */
936, /* "dhSinglePass-stdDH-sha1kdf-scheme" */
937, /* "dhSinglePass-stdDH-sha224kdf-scheme" */
938, /* "dhSinglePass-stdDH-sha256kdf-scheme" */
939, /* "dhSinglePass-stdDH-sha384kdf-scheme" */
940, /* "dhSinglePass-stdDH-sha512kdf-scheme" */
11, /* "directory services (X.500)" */
378, /* "directory services - algorithms" */
887, /* "distinguishedName" */
@@ -4703,14 +4700,14 @@ static const unsigned int kNIDsInOIDOrder[NUM_OBJ]={
505, /* OBJ_mime_mhs_headings 1 3 6 1 7 1 1 */
506, /* OBJ_mime_mhs_bodies 1 3 6 1 7 1 2 */
119, /* OBJ_ripemd160WithRSA 1 3 36 3 3 1 2 */
940, /* OBJ_dhSinglePass_stdDH_sha224kdf_scheme 1 3 132 1 11 0 */
941, /* OBJ_dhSinglePass_stdDH_sha256kdf_scheme 1 3 132 1 11 1 */
942, /* OBJ_dhSinglePass_stdDH_sha384kdf_scheme 1 3 132 1 11 2 */
943, /* OBJ_dhSinglePass_stdDH_sha512kdf_scheme 1 3 132 1 11 3 */
945, /* OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme 1 3 132 1 14 0 */
946, /* OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme 1 3 132 1 14 1 */
947, /* OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme 1 3 132 1 14 2 */
948, /* OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme 1 3 132 1 14 3 */
937, /* OBJ_dhSinglePass_stdDH_sha224kdf_scheme 1 3 132 1 11 0 */
938, /* OBJ_dhSinglePass_stdDH_sha256kdf_scheme 1 3 132 1 11 1 */
939, /* OBJ_dhSinglePass_stdDH_sha384kdf_scheme 1 3 132 1 11 2 */
940, /* OBJ_dhSinglePass_stdDH_sha512kdf_scheme 1 3 132 1 11 3 */
942, /* OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme 1 3 132 1 14 0 */
943, /* OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme 1 3 132 1 14 1 */
944, /* OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme 1 3 132 1 14 2 */
945, /* OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme 1 3 132 1 14 3 */
631, /* OBJ_setAttr_GenCryptgrm 2 23 42 3 3 3 1 */
632, /* OBJ_setAttr_T2Enc 2 23 42 3 3 4 1 */
633, /* OBJ_setAttr_T2cleartxt 2 23 42 3 3 4 2 */
@@ -5053,8 +5050,8 @@ static const unsigned int kNIDsInOIDOrder[NUM_OBJ]={
932, /* OBJ_brainpoolP384t1 1 3 36 3 3 2 8 1 1 12 */
933, /* OBJ_brainpoolP512r1 1 3 36 3 3 2 8 1 1 13 */
934, /* OBJ_brainpoolP512t1 1 3 36 3 3 2 8 1 1 14 */
939, /* OBJ_dhSinglePass_stdDH_sha1kdf_scheme 1 3 133 16 840 63 0 2 */
944, /* OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme 1 3 133 16 840 63 0 3 */
936, /* OBJ_dhSinglePass_stdDH_sha1kdf_scheme 1 3 133 16 840 63 0 2 */
941, /* OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme 1 3 133 16 840 63 0 3 */
418, /* OBJ_aes_128_ecb 2 16 840 1 101 3 4 1 1 */
419, /* OBJ_aes_128_cbc 2 16 840 1 101 3 4 1 2 */
420, /* OBJ_aes_128_ofb128 2 16 840 1 101 3 4 1 3 */
+8 -2
View File
@@ -1,9 +1,15 @@
#!/usr/local/bin/perl
#!/usr/bin/env perl
# fixes bug in floating point emulation on sparc64 when
# this script produces off-by-one output on sparc64
use integer;
if (scalar @ARGV != 2)
{
print "Usage: perl obj_dat.pl ../../include/openssl/obj_mac.h obj_dat.h\n";
exit 1;
}
sub obj_cmp
{
local(@a,@b,$_,$r);
@@ -170,7 +176,7 @@ foreach (sort obj_cmp @a)
print OUT <<'EOF';
/* THIS FILE IS GENERATED FROM objects.h by obj_dat.pl via the
* following command:
* perl obj_dat.pl obj_mac.h obj_dat.h */
* perl obj_dat.pl ../../include/openssl/obj_mac.h obj_dat.h */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
+947 -938
View File
File diff suppressed because it is too large Load Diff
+3 -4
View File
@@ -1,4 +1,6 @@
/* AUTOGENERATED BY objxref.pl, DO NOT EDIT */
/* THIS FILE IS GENERATED FROM obj_xref.txt by obj_xref.pl via the
* following command:
* perl obj_xref.pl obj_mac.num obj_xref.txt > obj_xref.h */
typedef struct
{
@@ -53,9 +55,6 @@ static const nid_triple sigoid_srt[] =
static const nid_triple * const sigoid_srt_xref[] =
{
&sigoid_srt[29],
&sigoid_srt[17],
&sigoid_srt[18],
&sigoid_srt[0],
&sigoid_srt[1],
&sigoid_srt[7],
+14 -3
View File
@@ -1,7 +1,13 @@
#!/usr/local/bin/perl
#!/usr/bin/env perl
use strict;
if (scalar @ARGV != 2)
{
print "Usage: perl obj_xref.pl obj_mac.num obj_xref.txt > obj_xref.h\n";
exit 1;
}
my %xref_tbl;
my %oid_tbl;
@@ -60,7 +66,9 @@ my $pname = $0;
$pname =~ s|^.[^/]/||;
print <<EOF;
/* AUTOGENERATED BY $pname, DO NOT EDIT */
/* THIS FILE IS GENERATED FROM obj_xref.txt by obj_xref.pl via the
* following command:
* perl obj_xref.pl obj_mac.num obj_xref.txt > obj_xref.h */
typedef struct
{
@@ -90,7 +98,10 @@ EOF
foreach (@srt2)
{
my $x = $xref_tbl{$_}[2];
my ($p1, $p2, $x) = @{$xref_tbl{$_}};
# If digest or signature algorithm is "undef" then the algorithm
# needs special handling and is excluded from the cross reference table.
next if $p1 eq "undef" || $p2 eq "undef";
print "\t\&sigoid_srt\[$x\],\n";
}
+16 -9
View File
@@ -1,4 +1,10 @@
#!/usr/local/bin/perl
#!/usr/bin/env perl
if (scalar @ARGV != 3)
{
print "Usage: perl objects.pl objects.txt obj_mac.num ../../include/openssl/obj_mac.h\n";
exit 1;
}
open (NUMIN,"$ARGV[1]") || die "Can't open number file $ARGV[1]";
$max_nid=0;
@@ -121,7 +127,7 @@ open (OUT,">$ARGV[2]") || die "Can't open output file $ARGV[2]";
print OUT <<'EOF';
/* THIS FILE IS GENERATED FROM objects.txt by objects.pl via the
* following command:
* perl objects.pl objects.txt obj_mac.num obj_mac.h */
* perl objects.pl objects.txt obj_mac.num ../../include/openssl/obj_mac.h */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
@@ -129,21 +135,21 @@ print OUT <<'EOF';
* 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:
@@ -158,10 +164,10 @@ print OUT <<'EOF';
* 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
* 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
@@ -173,11 +179,12 @@ print OUT <<'EOF';
* 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.] */
* [including the GNU Public Licence.]
*/
#define SN_undef "UNDEF"
#define LN_undef "undefined"
+2 -2
View File
@@ -340,7 +340,7 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
kstr=(unsigned char *)buf;
}
assert(iv_len <= (int)sizeof(iv));
if (RAND_pseudo_bytes(iv,iv_len) < 0) /* Generate a salt */
if (!RAND_bytes(iv, iv_len)) /* Generate a salt */
goto err;
/* The 'iv' is used as the iv and as a salt. It is
* NOT taken from the BytesToKey function */
@@ -390,7 +390,7 @@ err:
int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen,
pem_password_cb *callback,void *u)
{
int i,j,o,klen;
int i=0,j,o,klen;
long len;
EVP_CIPHER_CTX ctx;
unsigned char key[EVP_MAX_KEY_LENGTH];
+1 -1
View File
@@ -121,7 +121,7 @@ my %globals;
$self->{sz} = "";
} elsif ($self->{op} =~ /^v/) { # VEX
$self->{sz} = "";
} elsif ($self->{op} =~ /movq/ && $line =~ /%xmm/) {
} elsif ($self->{op} =~ /mov[dq]/ && $line =~ /%xmm/) {
$self->{sz} = "";
} elsif ($self->{op} =~ /([a-z]{3,})([qlwb])$/) {
$self->{op} = $1;
+1 -1
View File
@@ -104,7 +104,7 @@ int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
sstr = ASN1_STRING_data(pbe->salt);
if (salt)
memcpy(sstr, salt, saltlen);
else if (RAND_pseudo_bytes(sstr, saltlen) < 0)
else if (!RAND_bytes(sstr, saltlen))
goto err;
if(!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str))
+2 -2
View File
@@ -141,7 +141,7 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
{
if (aiv)
memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher));
else if (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
else if (!RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)))
goto err;
}
@@ -243,7 +243,7 @@ X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
if (salt)
memcpy (osalt->data, salt, saltlen);
else if (RAND_pseudo_bytes (osalt->data, saltlen) < 0)
else if (!RAND_bytes(osalt->data, saltlen))
goto merr;
if(iter <= 0)
+2 -2
View File
@@ -263,8 +263,8 @@ typedef int (*keygen_func)(EVP_CIPHER_CTX *ctx, const uint8_t *pass_raw,
struct pbe_suite {
int pbe_nid;
const EVP_CIPHER* (*cipher_func)();
const EVP_MD* (*md_func)();
const EVP_CIPHER* (*cipher_func)(void);
const EVP_MD* (*md_func)(void);
keygen_func keygen;
};
+4 -4
View File
@@ -181,13 +181,13 @@ int RSA_padding_add_PKCS1_type_2(uint8_t *to, unsigned tlen,
/* pad out with non-zero random data */
j = tlen - 3 - flen;
if (RAND_pseudo_bytes(p, j) <= 0) {
if (!RAND_bytes(p, j)) {
return 0;
}
for (i = 0; i < j; i++) {
while (*p == 0) {
if (RAND_pseudo_bytes(p, 1) <= 0) {
if (!RAND_bytes(p, 1)) {
return 0;
}
}
@@ -411,7 +411,7 @@ int RSA_padding_add_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen,
memset(db + mdlen, 0, emlen - flen - 2 * mdlen - 1);
db[emlen - flen - mdlen - 1] = 0x01;
memcpy(db + emlen - flen - mdlen, from, flen);
if (RAND_pseudo_bytes(seed, mdlen) <= 0) {
if (!RAND_bytes(seed, mdlen)) {
return 0;
}
@@ -718,7 +718,7 @@ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
ERR_R_MALLOC_FAILURE);
goto err;
}
if (RAND_pseudo_bytes(salt, sLen) <= 0) {
if (!RAND_bytes(salt, sLen)) {
goto err;
}
}
+7
View File
@@ -260,6 +260,13 @@ int RSA_is_opaque(const RSA *rsa) {
return rsa->meth && (rsa->meth->flags & RSA_FLAG_OPAQUE);
}
int RSA_supports_digest(const RSA *rsa, const EVP_MD *md) {
if (rsa->meth && rsa->meth->supports_digest) {
return rsa->meth->supports_digest(rsa, md);
}
return 1;
}
int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_RSA, argl, argp, new_func,
-8
View File
@@ -51,11 +51,3 @@ perlasm(sha512-586.${ASM_EXT} asm/sha512-586.pl)
perlasm(sha1-armv4-large.${ASM_EXT} asm/sha1-armv4-large.pl)
perlasm(sha256-armv4.${ASM_EXT} asm/sha256-armv4.pl)
perlasm(sha512-armv4.${ASM_EXT} asm/sha512-armv4.pl)
add_executable(
sha1_test
sha1_test.c
)
target_link_libraries(sha1_test crypto)
+5 -2
View File
@@ -93,16 +93,19 @@
# P4 10.6 -
# AMD K8 7.1 -
# Core2 7.3 6.0/+22% -
# Atom 12.5 9.3(*)/+35% -
# Westmere 7.3 5.5/+33% -
# Sandy Bridge 8.8 6.2/+40% 5.1(**)/+73%
# Ivy Bridge 7.2 4.8/+51% 4.7(**)/+53%
# Haswell 6.5 4.3/+51% 4.1(**)/+58%
# Bulldozer 11.6 6.0/+92%
# VIA Nano 10.6 7.5/+41%
# Atom 12.5 9.3(*)/+35%
# Silvermont 14.5 9.9(*)/+46%
#
# (*) Loop is 1056 instructions long and expected result is ~8.25.
# It remains mystery [to me] why ILP is limited to 1.7.
# The discrepancy is because of front-end limitations, so
# called MS-ROM penalties, and on Silvermont even rotate's
# limited parallelism.
#
# (**) As per above comment, the result is for AVX *plus* sh[rl]d.
+1
View File
@@ -53,6 +53,7 @@
# Bulldozer 36 - 27/22 17.0 13.6
# VIA Nano 36 - 25/22 16.8 16.5
# Atom 50 - 30/25 21.9 18.9
# Silvermont 40 - 34/31 22.9 20.6
#
# (*) numbers after slash are for unrolled loop, where applicable;
# (**) x86_64 assembly performance is presented for reference
+1
View File
@@ -28,6 +28,7 @@
# Bulldozer 121 - 50 14.0 13.5
# VIA Nano 91 - 52 33 14.7
# Atom 126 - 68 48(***) 14.7
# Silvermont 97 - 58 42(***) 17.5
#
# (*) whichever best applicable.
# (**) x86_64 assembler performance is presented for reference
+1
View File
@@ -89,6 +89,7 @@
# Bulldozer 21.1 13.6(+54%) 13.6(+54%(***)) 13.5 8.58(+57%)
# VIA Nano 23.0 16.5(+39%) - 14.7 -
# Atom 23.0 18.9(+22%) - 14.7 -
# Silvermont 27.4 20.6(+33%) - 17.5 -
#
# (*) whichever best applicable;
# (**) switch from ror to shrd stands for fair share of improvement;
-128
View File
@@ -1,128 +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 <stdio.h>
#include <openssl/crypto.h>
#include <openssl/digest.h>
#include <openssl/sha.h>
static const char *const test[] = {
"abc", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", NULL, };
static const char *const expected[] = {
"a9993e364706816aba3e25717850c26c9cd0d89d",
"84983e441c3bd26ebaae4aa1f95129e5e54670f1", };
static int test_incremental(void) {
EVP_MD_CTX ctx;
char buf[1000];
uint8_t md[SHA_DIGEST_LENGTH];
char md_hex[sizeof(md) * 2 + 1];
size_t i;
static const char expected[] = "34aa973cd4c4daa4f61eeb2bdbad27316534016f";
memset(buf, 'a', sizeof(buf));
EVP_MD_CTX_init(&ctx);
EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL);
for (i = 0; i < 1000; i++) {
EVP_DigestUpdate(&ctx, buf, sizeof(buf));
}
EVP_DigestFinal_ex(&ctx, md, NULL);
EVP_MD_CTX_cleanup(&ctx);
for (i = 0; i < sizeof(md); i++) {
sprintf(&md_hex[i * 2], "%02x", md[i]);
}
if (strcmp(md_hex, expected) != 0) {
fprintf(stderr, "test_incremental: got %s, wanted %s\n", md_hex, expected);
return 0;
}
return 1;
}
int main(int argc, char **argv) {
size_t i, j;
uint8_t md[SHA_DIGEST_LENGTH];
char md_hex[sizeof(md) * 2 + 1];
int ok = 1;
CRYPTO_library_init();
for (i = 0; test[i] != NULL; i++) {
EVP_Digest(test[i], strlen(test[i]), md, NULL, EVP_sha1(), NULL);
for (j = 0; j < sizeof(md); j++) {
sprintf(&md_hex[j * 2], "%02x", md[j]);
}
if (strcmp(md_hex, expected[i]) != 0) {
fprintf(stderr, "#%u: got %s, wanted %s\n", (unsigned)i, md_hex,
expected[i]);
ok = 0;
}
}
ok &= test_incremental();
if (ok) {
printf("PASS\n");
}
return ok ? 0 : 1;
}
+1
View File
@@ -554,6 +554,7 @@ int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in)
mbflag |= MBSTRING_FLAG;
stmp.data = NULL;
stmp.length = 0;
stmp.flags = 0;
ret = ASN1_mbstring_copy(&str, in->data, in->length, mbflag, B_ASN1_UTF8STRING);
if(ret < 0) return ret;
*out = stmp.data;
+6
View File
@@ -84,6 +84,12 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
return 0;
}
if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7)
{
OPENSSL_PUT_ERROR(X509, ASN1_item_verify, X509_R_INVALID_BIT_STRING_BITS_LEFT);
return 0;
}
EVP_MD_CTX_init(&ctx);
if (!EVP_DigestVerifyInitFromAlgorithm(&ctx, a, pkey))
-1
View File
@@ -91,7 +91,6 @@ int X509_CRL_print(BIO *out, X509_CRL *x)
BIO_printf(out, "Certificate Revocation List (CRL):\n");
l = X509_CRL_get_version(x);
BIO_printf(out, "%8sVersion %lu (0x%lx)\n", "", l+1, l);
i = OBJ_obj2nid(x->sig_alg->algorithm);
X509_signature_print(out, x->sig_alg, NULL);
p=X509_NAME_oneline(X509_CRL_get_issuer(x),NULL,0);
BIO_printf(out,"%8sIssuer: %s\n","",p);
+1
View File
@@ -94,6 +94,7 @@ const ERR_STRING_DATA X509_error_string_data[] = {
{ERR_PACK(ERR_LIB_X509, 0, X509_R_CRL_VERIFY_FAILURE), "CRL_VERIFY_FAILURE"},
{ERR_PACK(ERR_LIB_X509, 0, X509_R_ERR_ASN1_LIB), "ERR_ASN1_LIB"},
{ERR_PACK(ERR_LIB_X509, 0, X509_R_IDP_MISMATCH), "IDP_MISMATCH"},
{ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_BIT_STRING_BITS_LEFT), "INVALID_BIT_STRING_BITS_LEFT"},
{ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_DIRECTORY), "INVALID_DIRECTORY"},
{ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_FIELD_NAME), "INVALID_FIELD_NAME"},
{ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_TRUST), "INVALID_TRUST"},
+6
View File
@@ -64,6 +64,12 @@
int X509_set_version(X509 *x, long version)
{
if (x == NULL) return(0);
if (version == 0)
{
M_ASN1_INTEGER_free(x->cert_info->version);
x->cert_info->version = NULL;
return(1);
}
if (x->cert_info->version == NULL)
{
if ((x->cert_info->version=M_ASN1_INTEGER_new()) == NULL)
+13 -4
View File
@@ -168,6 +168,8 @@ int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int),
{
int idx;
X509_TRUST *trtmp;
char *name_dup;
/* This is set according to what we change: application can't set it */
flags &= ~X509_TRUST_DYNAMIC;
/* This will always be set for application modified trust entries */
@@ -183,13 +185,18 @@ int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int),
trtmp->flags = X509_TRUST_DYNAMIC;
} else trtmp = X509_TRUST_get0(idx);
/* OPENSSL_free existing name if dynamic */
if(trtmp->flags & X509_TRUST_DYNAMIC_NAME) OPENSSL_free(trtmp->name);
/* dup supplied name */
if(!(trtmp->name = BUF_strdup(name))) {
/* Duplicate the supplied name. */
name_dup = BUF_strdup(name);
if (name_dup == NULL) {
OPENSSL_PUT_ERROR(X509, X509_TRUST_add, ERR_R_MALLOC_FAILURE);
if (idx == -1)
OPENSSL_free(trtmp);
return 0;
}
/* OPENSSL_free existing name if dynamic */
if (trtmp->flags & X509_TRUST_DYNAMIC_NAME) OPENSSL_free(trtmp->name);
trtmp->name = name_dup;
/* Keep the dynamic flag of existing entry */
trtmp->flags &= X509_TRUST_DYNAMIC;
/* Set all other flags */
@@ -204,10 +211,12 @@ int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int),
if(idx == -1) {
if(!trtable && !(trtable = sk_X509_TRUST_new(tr_cmp))) {
OPENSSL_PUT_ERROR(X509, X509_TRUST_add, ERR_R_MALLOC_FAILURE);
trtable_free(trtmp);
return 0;
}
if (!sk_X509_TRUST_push(trtable, trtmp)) {
OPENSSL_PUT_ERROR(X509, X509_TRUST_add, ERR_R_MALLOC_FAILURE);
trtable_free(trtmp);
return 0;
}
}
+28 -42
View File
@@ -484,7 +484,6 @@ static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer)
ctx->current_cert = x;
ctx->current_issuer = issuer;
return ctx->verify_cb(0, ctx);
return 0;
}
/* Alternative lookup method: look from a STACK stored in other_ctx */
@@ -1901,7 +1900,7 @@ ASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_tm)
ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s,
int offset_day, long offset_sec, time_t *in_tm)
{
time_t t;
time_t t = 0;
if (in_tm) t = *in_tm;
else time(&t);
@@ -2248,38 +2247,26 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
STACK_OF(X509) *chain)
{
int ret = 1;
int ex_data_allocated = 0;
memset(ctx, 0, sizeof(X509_STORE_CTX));
ctx->ctx=store;
ctx->current_method=0;
ctx->cert=x509;
ctx->untrusted=chain;
ctx->crls = NULL;
ctx->last_untrusted=0;
ctx->other_ctx=NULL;
ctx->valid=0;
ctx->chain=NULL;
ctx->error=0;
ctx->explicit_policy=0;
ctx->error_depth=0;
ctx->current_cert=NULL;
ctx->current_issuer=NULL;
ctx->current_crl=NULL;
ctx->current_crl_score=0;
ctx->current_reasons=0;
ctx->tree = NULL;
ctx->parent = NULL;
if(!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx,
&ctx->ex_data))
{
goto err;
}
ex_data_allocated = 1;
ctx->param = X509_VERIFY_PARAM_new();
if (!ctx->param)
{
OPENSSL_PUT_ERROR(X509, X509_STORE_CTX_init, ERR_R_MALLOC_FAILURE);
return 0;
}
goto err;
/* Inherit callbacks and flags from X509_STORE if not set
* use defaults.
*/
* use defaults. */
if (store)
ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param);
@@ -2299,10 +2286,7 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
X509_VERIFY_PARAM_lookup("default"));
if (ret == 0)
{
OPENSSL_PUT_ERROR(X509, X509_STORE_CTX_init, ERR_R_MALLOC_FAILURE);
return 0;
}
goto err;
if (store && store->check_issued)
ctx->check_issued = store->check_issued;
@@ -2356,19 +2340,21 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
ctx->check_policy = check_policy;
/* This memset() can't make any sense anyway, so it's removed. As
* X509_STORE_CTX_cleanup does a proper "free" on the ex_data, we put a
* corresponding "new" here and remove this bogus initialisation. */
/* memset(&(ctx->ex_data),0,sizeof(CRYPTO_EX_DATA)); */
if(!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx,
&(ctx->ex_data)))
{
OPENSSL_free(ctx);
OPENSSL_PUT_ERROR(X509, X509_STORE_CTX_init, ERR_R_MALLOC_FAILURE);
return 0;
}
return 1;
err:
if (ex_data_allocated)
{
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, &ctx->ex_data);
}
if (ctx->param != NULL)
{
X509_VERIFY_PARAM_free(ctx->param);
}
memset(ctx, 0, sizeof(X509_STORE_CTX));
OPENSSL_PUT_ERROR(X509, X509_STORE_CTX_init, ERR_R_MALLOC_FAILURE);
return 0;
}
/* Set alternative lookup method: just a STACK of trusted certificates.
+12
View File
@@ -140,3 +140,15 @@ void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md)
X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
}
/* X509_ALGOR_cmp returns 0 if |a| and |b| are equal and non-zero otherwise. */
int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b)
{
int rv;
rv = OBJ_cmp(a->algorithm, b->algorithm);
if (rv)
return rv;
if (!a->parameter && !b->parameter)
return 0;
return ASN1_TYPE_cmp(a->parameter, b->parameter);
}
+2
View File
@@ -69,6 +69,8 @@ extern const ASN1_ITEM RSAPublicKey_it;
int X509_verify(X509 *a, EVP_PKEY *r)
{
if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature))
return 0;
return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF),a->sig_alg,
a->signature,a->cert_info,r));
}

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