Compare commits

..

118 Commits

Author SHA1 Message Date
David Benjamin 907ae62b9d ASN1_get_object should not accept large universal tags.
The high bits of the type get used for the V_ASN1_NEG bit, so when used with
ASN1_ANY/ASN1_TYPE, universal tags become ambiguous. This allows one to create
a negative zero, which should be impossible. Impose an upper bound on universal
tags accepted by crypto/asn1 and add a test.

BUG=590615

(Cherry-picked from fb2c6f8c8565e1e2d85c24408050c96521acbcdc.)

Change-Id: Ia988acf73fd11807869510a2b3825637a8d98853
Reviewed-on: https://boringssl-review.googlesource.com/7298
Reviewed-by: Adam Langley <agl@google.com>
2016-03-03 22:13:54 +00:00
David Benjamin 65be20fe2f Fix encoding bug in i2c_ASN1_INTEGER
(Imported from upstream's 3661bb4e7934668bd99ca777ea8b30eedfafa871.)

Fix bug where i2c_ASN1_INTEGER mishandles zero if it is marked as
negative.

Thanks to Huzaifa Sidhpurwala <huzaifas@redhat.com> and Hanno Böck
<hanno@hboeck.de> for reporting this issue.

BUG=590615

(Cherry-picked from c4eec0c16b02c97a62a95b6a08656c3a9ddb6baa.)

Change-Id: I61c5556e8a065817e3d36569433bff83a104d4c8
Reviewed-on: https://boringssl-review.googlesource.com/7297
Reviewed-by: Adam Langley <agl@google.com>
2016-03-03 22:11:56 +00:00
David Benjamin ab441a3a39 Remove support for mis-encoded PKCS#8 DSA keys.
Previously, OpenSSL supported many different DSA PKCS#8 encodings. Only
support the standard format. One of the workaround formats (SEQUENCE of
private key and public key) seems to be a workaround for an old Netscape
bug. From inspection, NSS seems to have fixed this from the first open
source commit.

Change-Id: I1e097b675145954b4d7a0bed8733e5a25c25fd8e
Reviewed-on: https://boringssl-review.googlesource.com/7074
Reviewed-by: Adam Langley <agl@google.com>
2016-02-22 15:20:12 -05:00
David Benjamin afe57cb14d Add a tool to generate Ed25519 keys.
Make it slightly easier for people to use.

Change-Id: I567e95bf1a5c203170a0b9732fd522fcbe5b7bc1
Reviewed-on: https://boringssl-review.googlesource.com/6773
Reviewed-by: Adam Langley <agl@google.com>
2015-12-18 23:34:13 +00:00
Adam Langley 77c3c0b025 Enable Ed25519 when building with OPENSSL_SMALL.
OPENSSL_SMALL will still cause the smaller base-point table to be used
and so won't be as fast at signing as the full version, but Ed25519 will
now work in those builds.

Without OPENSSL_SMALL:

Did 20000 Ed25519 key generation operations in 1008347us (19834.4 ops/sec)
Did 20000 Ed25519 signing operations in 1025594us (19500.9 ops/sec)
Did 6138 Ed25519 verify operations in 1001712us (6127.5 ops/sec)
Did 21000 Curve25519 base-point multiplication operations in 1019237us (20603.6 ops/sec)
Did 7095 Curve25519 arbitrary point multiplication operations in 1065986us (6655.8 ops/sec)

With (on the same machine):

Did 8415 Ed25519 key generation operations in 1020958us (8242.3 ops/sec)
Did 8952 Ed25519 signing operations in 1077635us (8307.1 ops/sec)
Did 6358 Ed25519 verify operations in 1047533us (6069.5 ops/sec)
Did 6620 Curve25519 base-point multiplication operations in 1008922us (6561.5 ops/sec)
Did 7183 Curve25519 arbitrary point multiplication operations in 1096285us (6552.1 ops/sec)

Change-Id: Ib443c0e2bdfd11e044087e66efd55b651a5667e7
Reviewed-on: https://boringssl-review.googlesource.com/6772
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-12-18 23:15:33 +00:00
David Benjamin 9f897b2580 Remove the stitched RC4-MD5 code and use the generic one.
This removes 16k from a release-mode build of the bssl tool. Now that we've
finished the AEAD refactor, there's no use in keeping this around as a
prototype for "stateful AEADs".

Before:
Did 2264000 RC4-MD5 (16 bytes) seal operations in 1000430us (2263026.9 ops/sec): 36.2 MB/s
Did 266000 RC4-MD5 (1350 bytes) seal operations in 1000984us (265738.5 ops/sec): 358.7 MB/s
Did 50000 RC4-MD5 (8192 bytes) seal operations in 1014209us (49299.5 ops/sec): 403.9 MB/s
After:
Did 1895000 RC4-MD5 (16 bytes) seal operations in 1000239us (1894547.2 ops/sec): 30.3 MB/s
Did 199000 RC4-MD5 (1350 bytes) seal operations in 1001361us (198729.5 ops/sec): 268.3 MB/s
Did 39000 RC4-MD5 (8192 bytes) seal operations in 1014832us (38430.0 ops/sec): 314.8 MB/s

There is a non-trivial performance hit, but this cipher doesn't matter much and
the stitched mode code reaches into MD5_CTX and RC4_KEY in somewhat unfortunate
ways.

Change-Id: I9ecd28d6afb54e90ce61baecc641742af2ae6269
Reviewed-on: https://boringssl-review.googlesource.com/6752
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 23:57:42 +00:00
David Benjamin 1741a9d143 Save some mallocs in computing the MAC for e_tls.c.
We can reuse the HMAC_CTX that stores the key. The API is kind of unfortunate
as, in principle, it should be possible to do an allocation-averse HMAC with a
shared key on multiple threads at once (EVP_AEAD_CTX is normally logically
const). At some point it may be worth rethinking those APIs somewhat.  But
these "stateful AEADs" are already stateful in their EVP_CIPHER_CTX, so this is
fine.

Each cipher was run individually to minimize the effect of other ciphers doing
their mallocs. (Although the cost of a malloc is presumably going to depend a
lot on the malloc implementation and what's happened before in the process, so
take these numbers with a bucket of salt. They vary widely even with the same
arguments.)

Taking malloc out of seal/open also helps with the malloc tests. DTLS currently
cannot distinguish a malloc failure (should be fatal) from a decryption failure
(not fatal), so the malloc tests get stuck. But this doesn't completely get us
there since tls_cbc.c mallocs. This also assumes EVP_CIPHER_CTX, EVP_MD_CTX,
and HMAC_CTX are all clever about reusing their allocations when reset (which
they are).

Before:
Did 1315000 AES-128-CBC-SHA1 (16 bytes) seal operations in 1000087us (1314885.6 ops/sec): 21.0 MB/s
Did 181000 AES-128-CBC-SHA1 (1350 bytes) seal operations in 1004918us (180114.2 ops/sec): 243.2 MB/s
Did 34000 AES-128-CBC-SHA1 (8192 bytes) seal operations in 1024250us (33195.0 ops/sec): 271.9 MB/s
After:
Did 1766000 AES-128-CBC-SHA1 (16 bytes) seal operations in 1000319us (1765436.8 ops/sec): 28.2 MB/s
Did 187000 AES-128-CBC-SHA1 (1350 bytes) seal operations in 1004002us (186254.6 ops/sec): 251.4 MB/s
Did 35000 AES-128-CBC-SHA1 (8192 bytes) seal operations in 1014885us (34486.7 ops/sec): 282.5 MB/s

Before:
Did 391000 DES-EDE3-CBC-SHA1 (16 bytes) seal operations in 1000038us (390985.1 ops/sec): 6.3 MB/s
Did 16000 DES-EDE3-CBC-SHA1 (1350 bytes) seal operations in 1060226us (15091.1 ops/sec): 20.4 MB/s
Did 2827 DES-EDE3-CBC-SHA1 (8192 bytes) seal operations in 1035971us (2728.8 ops/sec): 22.4 MB/s
After:
Did 444000 DES-EDE3-CBC-SHA1 (16 bytes) seal operations in 1001814us (443196.0 ops/sec): 7.1 MB/s
Did 17000 DES-EDE3-CBC-SHA1 (1350 bytes) seal operations in 1042535us (16306.4 ops/sec): 22.0 MB/s
Did 2590 DES-EDE3-CBC-SHA1 (8192 bytes) seal operations in 1012378us (2558.3 ops/sec): 21.0 MB/s

Before:
Did 1316000 AES-256-CBC-SHA1 (16 bytes) seal operations in 1000510us (1315329.2 ops/sec): 21.0 MB/s
Did 157000 AES-256-CBC-SHA1 (1350 bytes) seal operations in 1002944us (156539.1 ops/sec): 211.3 MB/s
Did 29000 AES-256-CBC-SHA1 (8192 bytes) seal operations in 1030284us (28147.6 ops/sec): 230.6 MB/s
After:
Did 1645000 AES-256-CBC-SHA1 (16 bytes) seal operations in 1000313us (1644485.3 ops/sec): 26.3 MB/s
Did 162000 AES-256-CBC-SHA1 (1350 bytes) seal operations in 1003060us (161505.8 ops/sec): 218.0 MB/s
Did 36000 AES-256-CBC-SHA1 (8192 bytes) seal operations in 1014819us (35474.3 ops/sec): 290.6 MB/s

Before:
Did 1435000 RC4-SHA1 (16 bytes) seal operations in 1000245us (1434648.5 ops/sec): 23.0 MB/s
Did 207000 RC4-SHA1 (1350 bytes) seal operations in 1004675us (206036.8 ops/sec): 278.1 MB/s
Did 38000 RC4-SHA1 (8192 bytes) seal operations in 1022712us (37156.1 ops/sec): 304.4 MB/s
After:
Did 1853000 RC4-SHA1 (16 bytes) seal operations in 1000433us (1852198.0 ops/sec): 29.6 MB/s
Did 206000 RC4-SHA1 (1350 bytes) seal operations in 1002370us (205512.9 ops/sec): 277.4 MB/s
Did 42000 RC4-SHA1 (8192 bytes) seal operations in 1024209us (41007.3 ops/sec): 335.9 MB/s

Change-Id: I0edb89bddf146cf91a8e7a99c56b2278c8f38094
Reviewed-on: https://boringssl-review.googlesource.com/6751
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 23:56:28 +00:00
David Benjamin df571631cc Add RC4-SHA1 and DES-EDE3-CBC-SHA1 to bssl speed.
For completeness. In so far as we care about legacy ciphers' performance at
all, we should have the others too.

Change-Id: Idd2d93345f3af8b6ac5772a1cb3c201f84fe3197
Reviewed-on: https://boringssl-review.googlesource.com/6750
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 23:53:23 +00:00
David Benjamin 13414b3a04 Implement draft-ietf-tls-chacha20-poly1305-04.
Only ECDHE-based ciphers are implemented. To ease the transition, the
pre-standard cipher shares a name with the standard one. The cipher rule parser
is hacked up to match the name to both ciphers. From the perspective of the
cipher suite configuration language, there is only one cipher.

This does mean it is impossible to disable the old variant without a code
change, but this situation will be very short-lived, so this is fine.

Also take this opportunity to make the CK and TXT names align with convention.

Change-Id: Ie819819c55bce8ff58e533f1dbc8bef5af955c21
Reviewed-on: https://boringssl-review.googlesource.com/6686
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 23:34:56 +00:00
David Benjamin 37489902ba Implement draft-ietf-tls-chacha20-poly1305-04 in Go.
This will be used to test the C implementation against.

Change-Id: I2d396d27630937ea610144e381518eae76f78dab
Reviewed-on: https://boringssl-review.googlesource.com/6685
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 23:33:54 +00:00
David Benjamin 2089fdd10e Implement RFC 7539 in Go.
In preparation for a Go implementation of the new TLS ciphers to test
against, implement the AEAD primitive.

Change-Id: I69b5b51257c3de16bdd36912ed2bc9d91ac853c8
Reviewed-on: https://boringssl-review.googlesource.com/6684
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 23:33:39 +00:00
David Benjamin 86e412dc18 Add client cert support to bssl client.
Handy to test servers with misbehaving client auth.

Change-Id: I93f7b77c35e223761edade648bc03d1f97ed82fd
Reviewed-on: https://boringssl-review.googlesource.com/6614
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 23:15:41 +00:00
David Benjamin 23a681b9f9 Fix build.
There were a couple more asm lines to turn into __asm__ when the patches got
reordered slightly.

Change-Id: I44be5caee6d09bb3db5dea4791592b12d175822c
Reviewed-on: https://boringssl-review.googlesource.com/6741
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 21:26:12 +00:00
David Benjamin e3203923b5 Rename the Go ChaCha20-Poly1305 implementation.
In preparation for implementing the RFC 7539 variant to test against.

Change-Id: I0ce5e856906e00925ad1d849017f9e7fda087a8e
Reviewed-on: https://boringssl-review.googlesource.com/6683
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 21:24:00 +00:00
David Benjamin 8ffab72683 Point EVP_aead_chacha20_poly1305 at the standardized version.
The consumers have all been updated, so we can move EVP_aead_chacha20_poly1305
to its final state. Unfortunately, the _rfc7539-suffixed version will need to
stick around for just a hair longer. Also the tls1.h macros, but the remaining
consumers are okay with that changing underneath them.

Change-Id: Ibbb70ec1860d6ac6a7e1d7b45e70fe692bf5ebe5
Reviewed-on: https://boringssl-review.googlesource.com/6600
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 21:22:11 +00:00
David Benjamin fef6fb592b Fix ChaCha20-Poly1305 tests.
https://boringssl-review.googlesource.com/6101 was mismerged from *ring* and
lost some tests. Also add the corresponding tag truncation tests for the new
construction. So long as we have that feature, we should have tests for it.
(Although, do we actually need to support it?)

Change-Id: I70784cbac345e0ad11b496102856c53932b7362e
Reviewed-on: https://boringssl-review.googlesource.com/6682
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 21:20:49 +00:00
David Benjamin 60a08ac211 Remove unreachable code to duplicate DH keys.
dh_tmp can only contain parameters, now that DHE always generates keys fresh
for each connection.

Change-Id: I56dad4cbec7e21326360d79df211031fd9734004
Reviewed-on: https://boringssl-review.googlesource.com/6702
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 21:20:12 +00:00
David Benjamin 4ec0cce743 Slightly tweak some array allocations.
clang scan-build is annoyed it's not obvious the sizeof line matches the
pointer type. This is easy to fix and makes it be quiet.

Change-Id: Iec80d2a087f81179c88cae300f56d3f76b32b347
Reviewed-on: https://boringssl-review.googlesource.com/6701
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 21:19:32 +00:00
David Benjamin 2936170d68 Fix memory leak in DSA redo case.
Found by clang scan-build.

Change-Id: I44a9d5ea165ede836c72aed8725d0bb0981b1004
Reviewed-on: https://boringssl-review.googlesource.com/6700
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 21:17:09 +00:00
David Benjamin a01deee96b Make CBB_len relative to its argument.
Rather than the length of the top-level CBB, which is kind of odd when ASN.1
length prefixes are not yet determined, return the number of bytes written to
the CBB so far. This can be computed without increasing the size of CBB at all.
Have offset and pending_*.

This means functions which take in a CBB as argument will not be sensitive to
whether the CBB is a top-level or child CBB. The extensions logic had to be
careful to only ever compare differences of lengths, which was awkward.

The reversal will also allow for the following pattern in the future, once
CBB_add_space is split into, say, CBB_reserve and CBB_did_write and we add a
CBB_data:

  uint8_t *signature;
  size_t signature_len = 0;
  if (!CBB_add_asn1(out, &cert, CBB_ASN1_SEQUENCE) ||
      /* Emit the TBSCertificate. */
      !CBB_add_asn1(&cert, &tbs_cert, CBS_ASN1_SEQUENCE) ||
      !CBB_add_tbs_cert_stuff(&tbs_cert, stuff) ||
      !CBB_flush(&cert) ||
      /* Feed it into md_ctx. */
      !EVP_DigestSignInit(&md_ctx, NULL, EVP_sha256(), NULL, pkey) ||
      !EVP_DigestSignUpdate(&md_ctx, CBB_data(&cert), CBB_len(&cert)) ||
      /* Emit the signature algorithm. */
      !CBB_add_asn1(&cert, &sig_alg, CBS_ASN1_SEQUENCE) ||
      !CBB_add_sigalg_stuff(&sig_alg, other_stuff) ||
      /* Emit the signature. */
      !EVP_DigestSignFinal(&md_ctx, NULL, &signature_len) ||
      !CBB_reserve(&cert, &signature, signature_len) ||
      !EVP_DigestSignFinal(&md_ctx, signature, &signature_len) ||
      !CBB_did_write(&cert, signature_len)) {
    goto err;
  }

(Were TBSCertificate not the first field, we'd still have to sample
CBB_len(&cert), but at least that's reasonable straight-forward. The
alternative would be if CBB_data and CBB_len somehow worked on
recently-invalidated CBBs, but that would go wrong once the invalidated CBB's
parent flushed and possibly shifts everything.)

And similar for signing ServerKeyExchange.

Change-Id: I7761e492ae472d7632875b5666b6088970261b14
Reviewed-on: https://boringssl-review.googlesource.com/6681
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 21:16:12 +00:00
Adam Langley 77385bb43d Mark platform-specific HOST_[c2l|l2c] as (void).
I skipped a patch when landing and so 793c21e2 caused a build failure
when platform-specific versions of these macros were used.

Change-Id: I8ed6dbb92a511ef306d45087c3eb87781fdfed31
Reviewed-on: https://boringssl-review.googlesource.com/6740
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 20:16:46 +00:00
David Benjamin 6969971fef Remove a dead prototype.
Change-Id: I05cf52b31bd532505393e9a1ccae27f89f81f6f4
Reviewed-on: https://boringssl-review.googlesource.com/6680
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 20:03:53 +00:00
David Benjamin 1b36716ce2 Remove crypto/header_removed.h.
This is a remnant from when the headers in include/ where still
symlinks.

Change-Id: Ice27c412c0cdcc43312f5297119678091dcd5d38
Reviewed-on: https://boringssl-review.googlesource.com/6670
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 20:03:40 +00:00
David Benjamin 017231a544 Remove asm __asm__ define.
It's only used in one file. No sense in polluting the namespace here.

Change-Id: Iaf3870a4be2d2cad950f4d080e25fe7f0d3929c7
Reviewed-on: https://boringssl-review.googlesource.com/6660
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 20:03:17 +00:00
David Benjamin 793c21e266 Make HOST_l2c return void.
Nothing ever uses the return value. It'd be better off discarding it rather
than make callers stick (void) everywhere.

Change-Id: Ia28c970a1e5a27db441e4511249589d74408849b
Reviewed-on: https://boringssl-review.googlesource.com/6653
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 20:02:37 +00:00
David Benjamin 0aff3ffb88 Store the partial block as uint8_t, not uint32_t.
The uint32_t likely dates to them using HASH_LONG everywhere. Nothing ever
touches c->data as a uint32_t, only bytes. (Which makes sense seeing as it
stores the partial block.)

Change-Id: I634cb7f2b6306523aa663f8697b7dc92aa491320
Reviewed-on: https://boringssl-review.googlesource.com/6651
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 19:59:29 +00:00
David Benjamin 5a19d7dfa8 Use the straight-forward ROTATE macro.
I would hope any sensible compiler would recognize the rotation. (If
not, we should at least pull this into crypto/internal.h.) Confirmed
that clang at least produces the exact same instructions for
sha256_block_data_order for release + NO_ASM. This is also mostly moot
as SHA-1 and SHA-256 both have assembly versions on x86 that sidestep
most of this.

For the digests, take it out of md32_common.h since it doesn't use the
macro. md32_common.h isn't sure whether it's a multiply-included header
or not. It should be, but it has an #include guard (doesn't quite do
what you'd want) and will get HOST_c2l, etc., confused if one tries to
include it twice.

Change-Id: I1632801de6473ffd2c6557f3412521ec5d6b305c
Reviewed-on: https://boringssl-review.googlesource.com/6650
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 19:57:31 +00:00
David Benjamin 78fefbf3bb Reformat md32_common.h, part 2.
Manual tweaks and then clang-formatted again.

Change-Id: I809fdb71b2135343e5c1264dd659b464780fc54a
Reviewed-on: https://boringssl-review.googlesource.com/6649
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 19:52:06 +00:00
David Benjamin fea1137e55 Reformat md32_common.h, part 1.
We've tweaked it already and upstream's using a different indentation
style now anyway. This is the first of two commits. For verifiability,
this is the output of clang-format with no modifications.

Change-Id: Ia30f20bee0cc8046aedf9ac7106cc4630e8d93e6
Reviewed-on: https://boringssl-review.googlesource.com/6648
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 19:47:50 +00:00
David Benjamin 871fff076b *_Update of length zero is legal.
We can slightly simplify tls1_P_hash. (Confirmed md32_common.h emits
code with the check.)

Change-Id: I0293ceaaee261a7ac775b42a639f7a9f67705456
Reviewed-on: https://boringssl-review.googlesource.com/6647
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 19:46:57 +00:00
David Benjamin d9f0671bbe Remove |need_record_splitting| from |SSL3_STATE|.
It is redundant given the other state in the connection.

Change-Id: I5dc71627132659ab4316a5ea360c9ca480fb7c6c
Reviewed-on: https://boringssl-review.googlesource.com/6646
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 18:45:48 +00:00
David Benjamin cd480380fa Remove unused fields from SSL3_STATE.
These have been unused since we unified everything on EVP_AEAD. I must
have missed them when clearing out dead state. This shaves 136 bytes of
per-connection state.

Change-Id: I705f8de389fd34ab4524554ee9e4b1d6be198994
Reviewed-on: https://boringssl-review.googlesource.com/6645
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 18:42:56 +00:00
David Benjamin 7fc010014c Slightly simplify SSL3_RECORD.
There's no need to track consumed bytes, so rr->data and rr->off may be
merged together.

Change-Id: I8842d005665ea8b4d4a0cced941f3373872cdac4
Reviewed-on: https://boringssl-review.googlesource.com/6644
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 18:41:59 +00:00
David Benjamin ece5ba2797 Reset ssl error codes.
38 error codes have fallen off the list since the last time we did this.

Change-Id: Id7ee30889a5da2f6ab66957fd8e49e97640c8489
Reviewed-on: https://boringssl-review.googlesource.com/6643
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 18:38:20 +00:00
David Benjamin a41280d8cb Pull ChangeCipherSpec into the handshake state machine.
This uses ssl3_read_bytes for now. We still need to dismantle that
function and then invert the handshake state machine, but this gets
things closer to the right shape as an intermediate step and is a large
chunk in itself. It simplifies a lot of the CCS/handshake
synchronization as a lot of the invariants much more clearly follow from
the handshake itself.

Tests need to be adjusted since this changes some error codes. Now all
the CCS/Handshake checks fall through to the usual
SSL_R_UNEXPECTED_RECORD codepath. Most of what used to be a special-case
falls out naturally. (If half of Finished was in the same record as the
pre-CCS message, that part of the handshake record would have been left
unconsumed, so read_change_cipher_spec would have noticed, just like
read_app_data would have noticed.)

Change-Id: I15c7501afe523d5062f0e24a3b65f053008d87be
Reviewed-on: https://boringssl-review.googlesource.com/6642
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 18:36:57 +00:00
David Benjamin 8fd5c23218 Simplify fragmented HelloRequest state.
With server-side renegotiation gone, handshake_fragment's only purpose
in life is to handle a fragmented HelloRequest (we probably do need to
support those if some server does 1/n-1 record-splitting on handshake
records). The logic to route the data into
ssl3_read_bytes(SSL3_RT_HANDSHAKE) never happens, and the contents are
always a HelloRequest prefix.

This also trims a tiny bit of per-connection state.

Change-Id: Ia1b0dda5b7e79d817c28da1478640977891ebc97
Reviewed-on: https://boringssl-review.googlesource.com/6641
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 17:45:31 +00:00
David Benjamin ef5dfd2980 Add tests for malformed HelloRequests.
Change-Id: Iff053022c7ffe5b01c0daf95726cc7d49c33cbd6
Reviewed-on: https://boringssl-review.googlesource.com/6640
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 17:40:29 +00:00
David Benjamin 8411b248c3 Add tests for bad ChangeCipherSpecs.
Change-Id: I7eac3582b7b23b5da95be68277609cfa63195b02
Reviewed-on: https://boringssl-review.googlesource.com/6629
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 17:39:43 +00:00
David Benjamin 502a843dee Switch unrolled loop in BN_usub with memcpy.
See also upstream's 06cf881a3a10d5af3c1255c08cfd0c6ddb5f1cc3,
9f040d6decca7930e978784c917f731e5c45e8f0, and
9f6795e7d2d1e35668ad70ba0afc480062be4e2e.

Change-Id: I27d90e382867a5fe988d152b31f8494e001a6a9f
Reviewed-on: https://boringssl-review.googlesource.com/6628
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 17:38:48 +00:00
David Benjamin c3ae38b4f8 Remove DH EVP_PKEY hooks.
They would never work. Better notice when callers depend on it than fail at
runtime.

This depends on https://android-review.googlesource.com/#/c/183610/ in
Conscrypt.

Change-Id: I3411f291416df834cf85850890617625a2e76939
Reviewed-on: https://boringssl-review.googlesource.com/6552
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 17:38:06 +00:00
Nico Weber 7100ee9832 Chromium's update.sh is dead, long live update.py
update.py used to be used only on Windows until very recently, but
Windows and non-Windows have been at the same clang revision for
a while now.  So even a few months ago update.py and update.sh
would've contained the same clang revision.

BUG=chromium:494442

Change-Id: Ie9127a1c49e31a7810ee431f8e662350c245917c
Reviewed-on: https://boringssl-review.googlesource.com/6620
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 17:30:31 +00:00
David Benjamin f28dd64d43 Fix flaky BadRSAClientKeyExchange-1 test.
Sometimes BadRSAClientKeyExchange-1 fails with DATA_TOO_LARGE_FOR_MODULUS if
the corruption brings the ciphertext above the RSA modulus. Ensure this does
not happen.

Change-Id: I0d8ea6887dfcab946fdf5d38f5b196f5a927c4a9
Reviewed-on: https://boringssl-review.googlesource.com/6731
Reviewed-by: Adam Langley <agl@google.com>
2015-12-16 15:40:18 +00:00
David Benjamin 423488557c Remove unused functions.
Change-Id: I48d6db3b2e521c726962c291cce7baa029e09623
Reviewed-on: https://boringssl-review.googlesource.com/6627
Reviewed-by: Adam Langley <agl@google.com>
2015-12-15 21:32:44 +00:00
David Benjamin 45dab251f3 Skip free callbacks on empty CRYPTO_EX_DATAs.
Avoids bouncing on the lock, but it doesn't really matter since it's all
taking read locks. If we're declaring that callbacks don't get to see
every object being created, they shouldn't see every object being
destroyed.

CRYPTO_dup_ex_data also already had this optimization, though it wasn't
documented.

BUG=391192

Change-Id: I5b8282335112bca3850a7c0168f8bd7f7d4a2d57
Reviewed-on: https://boringssl-review.googlesource.com/6626
Reviewed-by: Adam Langley <agl@google.com>
2015-12-15 21:32:14 +00:00
David Benjamin 8a58933db0 Remove the CRYPTO_EX_new callback.
This callback is never used. The one caller I've ever seen is in Android
code which isn't built with BoringSSL and it was a no-op.

It also doesn't actually make much sense. A callback cannot reasonably
assume that it sees every, say, SSL_CTX created because the index may be
registered after the first SSL_CTX is created. Nor is there any point in
an EX_DATA consumer in one file knowing about an SSL_CTX created in
completely unrelated code.

Replace all the pointers with a typedef to int*. This will ensure code
which passes NULL or 0 continues to compile while breaking code which
passes an actual function.

This simplifies some object creation functions which now needn't worry
about CRYPTO_new_ex_data failing. (Also avoids bouncing on the lock, but
it's taking a read lock, so this doesn't really matter.)

BUG=391192

Change-Id: I02893883c6fa8693682075b7b130aa538a0a1437
Reviewed-on: https://boringssl-review.googlesource.com/6625
Reviewed-by: Adam Langley <agl@google.com>
2015-12-15 21:29:46 +00:00
David Benjamin 0abd6f2eb6 Get struct timeval from sys/time.h.
The naclports patch switches sys/types.h to sys/time.h. Per
http://pubs.opengroup.org/onlinepubs/009604499/basedefs/sys/time.h.html
this is correct.

Change-Id: If6d56cb28fa16a1d8b4515a45532434f6c23a29d
Reviewed-on: https://boringssl-review.googlesource.com/6624
Reviewed-by: Adam Langley <agl@google.com>
2015-12-15 20:32:36 +00:00
David Benjamin 1246670caa Use UINT64_C in sha512.c table.
From the naclports patch:
https://chromium.googlesource.com/external/naclports/+/master/ports/boringssl/nacl.patch

Change-Id: I37ad45fbde0b1b1437d3abd8ed7422bd72cfd959
Reviewed-on: https://boringssl-review.googlesource.com/6623
Reviewed-by: Adam Langley <agl@google.com>
2015-12-15 20:30:10 +00:00
David Benjamin 5ddffbb8bc Make SSL_(CTX_)?set_tmp_ecdh call SSL_(CTX_)?set1_curves.
Then deprecate the old functions. Thanks to upstream's
6977e8ee4a718a76351ba5275a9f0be4e530eab5 for the idea.

Change-Id: I916abd6fca2a3b2a439ec9902d9779707f7e41eb
Reviewed-on: https://boringssl-review.googlesource.com/6622
Reviewed-by: Adam Langley <agl@google.com>
2015-12-15 20:28:47 +00:00
David Benjamin 53e5c2c225 Remove SSL_(CTX_)?set_ecdh_callback.
It has no callers. I prepped for its removal earlier with
https://android.googlesource.com/platform/external/conscrypt/+/c05697c2c50fe1331f08c6f32d0bc9636eecdc2d
and then completely forgot.

Thanks to upstream's 6f78b9e824c053d062188578635c575017b587c5 for
the reminder. Quoth them:

> This only gets used to set a specific curve without actually checking
> that the peer supports it or not and can therefor result in handshake
> failures that can be avoided by selecting a different cipher.

It's also a very confusing API since it does NOT pass ownership of the
EC_KEY to the caller.

Change-Id: I6a00643b3a2d6746e9e0e228b47c2bc9694b0084
Reviewed-on: https://boringssl-review.googlesource.com/6621
Reviewed-by: Adam Langley <agl@google.com>
2015-12-15 20:07:37 +00:00
David Benjamin 756ad17337 Initialize |one_index| in OAEP padding check.
This was a mistake in https://boringssl-review.googlesource.com/6611.

Change-Id: Ifb5c52cc7571b6f1ada4af9b46eab1f9b080b4f6
Reviewed-on: https://boringssl-review.googlesource.com/6730
Reviewed-by: Adam Langley <agl@google.com>
2015-12-15 19:46:39 +00:00
David Benjamin 1634a33495 Convert rsa/padding.c to constant-time helpers.
Remove the custom copy of those helpers.

Change-Id: I810c3ae8dbf7bc0654d3e9fb9900c425d36f64aa
Reviewed-on: https://boringssl-review.googlesource.com/6611
Reviewed-by: Adam Langley <agl@google.com>
2015-12-15 19:39:37 +00:00
David Benjamin b36a395a9a Add slightly better RSA key exchange tests.
Cover not just the wrong version, but also other mistakes.

Change-Id: I46f05a9a37b7e325adc19084d315a415777d3a46
Reviewed-on: https://boringssl-review.googlesource.com/6610
Reviewed-by: Adam Langley <agl@google.com>
2015-12-15 19:26:28 +00:00
David Benjamin 0bd71eb85d Remove weird ret negation logic.
This is a remnant of ssl3_get_client_hello's old DTLS cookie logic, which has
since been removed. (If we ever need HelloVerifyRequest support on the server,
we'll implement something stateless in front.) We can switch this to something
more straightforward now.

See also upstream's 94f98a9019e1c0a3be4ca904b2c27c7af3d937c0,

Change-Id: Ie733030209a381a4915d6744fa12a79ffe972fa5
Reviewed-on: https://boringssl-review.googlesource.com/6601
Reviewed-by: Adam Langley <agl@google.com>
2015-12-15 19:24:51 +00:00
David Benjamin e9cddb8879 Remove SSL_OP_LEGACY_SERVER_CONNECT.
I don't think we're ever going to manage to enforce this, and it doesn't
seem worth the trouble. We don't support application protocols which use
renegotiation outside of the HTTP/1.1 mid-stream client auth hack.
There, it's on the server to reject legacy renegotiations.

This removes the last of SSL_OP_ALL.

Change-Id: I996fdeaabf175b6facb4f687436549c0d3bb0042
Reviewed-on: https://boringssl-review.googlesource.com/6580
Reviewed-by: Adam Langley <agl@google.com>
2015-12-15 19:22:53 +00:00
David Benjamin 3e052de5a0 Tighten SSL_OP_LEGACY_SERVER_CONNECT to align with RFC 5746.
RFC 5746 forbids a server from downgrading or upgrading
renegotiation_info support. Even with SSL_OP_LEGACY_SERVER_CONNECT set
(the default), we can still enforce a few things.

I do not believe this has practical consequences. The attack variant
where the server half is prefixed does not involve a renegotiation on
the client. The converse where the client sees the renegotiation and
prefix does, but we only support renego for the mid-stream HTTP/1.1
client auth hack, which doesn't do this. (And with triple-handshake,
HTTPS clients should be requiring the certificate be unchanged across
renego which makes this moot.)

Ultimately, an application which makes the mistake of using
renegotiation needs to be aware of what exactly that means and how to
handle connection state changing mid-stream. We make renego opt-in now,
so this is a tenable requirement.

(Also the legacy -> secure direction would have been caught by the
server anyway since we send a non-empty RI extension.)

Change-Id: I915965c342f8a9cf3a4b6b32f0a87a00c3df3559
Reviewed-on: https://boringssl-review.googlesource.com/6559
Reviewed-by: Adam Langley <agl@google.com>
2015-12-15 19:17:56 +00:00
David Benjamin 03f000577f Remove SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER.
This dates to SSLeay 0.8.0 (or earlier). The use counter sees virtually
no hits.

Change-Id: Iff4c8899d5cb0ba4afca113c66d15f1d980ffe41
Reviewed-on: https://boringssl-review.googlesource.com/6558
Reviewed-by: Adam Langley <agl@google.com>
2015-12-15 19:14:00 +00:00
David Benjamin ef5e515819 Remove SSL_OP_TLS_D5_BUG.
This dates to SSLeay 0.9.0. The Internet seems to have completely
forgotten what "D5" is. (I can't find reference to it beyond
documentation of this quirk.) The use counter we added sees virtually no
hits.

Change-Id: I9781d401acb98ce3790b1b165fc257a6f5e9b155
Reviewed-on: https://boringssl-review.googlesource.com/6557
Reviewed-by: Adam Langley <agl@google.com>
2015-12-15 19:11:41 +00:00
David Benjamin c100ef4379 Limit depth of ASN1 parse printing.
(Imported from upstream's d88ef40a1e5c81d0d32b4a431e55f5456e678dd2 and
943c4ca62b3f5a160340d57aecb9413407a06e15.)

Change-Id: Idd52aebae6839695be0f3a8a7659adeec6650b98
Reviewed-on: https://boringssl-review.googlesource.com/6556
Reviewed-by: Adam Langley <agl@google.com>
2015-12-15 19:06:04 +00:00
David Benjamin 2205093e7e Add a comment in SetTestState from bssl_shim.
Per Nico's comment in https://boringssl-review.googlesource.com/#/c/3342/3/ssl/test/bssl_shim.cc.

Also remove unnecessary cast and change the variable name to |state|. |async|
is a remnant from when it was |AsyncState| rather than |TestState|.

Change-Id: I83f23593b0c4e64b0ddd056573f75c0aabe96f9e
Reviewed-on: https://boringssl-review.googlesource.com/6555
Reviewed-by: Adam Langley <agl@google.com>
2015-12-15 19:05:46 +00:00
Piotr Sikora 6ae67dfee8 Don't leak Android hacks to other build platforms.
Previously, android_compat_hacks.c and android_compat_keywrap.c
were added to crypto_sources when multiple build platforms were
specified in one invocation.

Change-Id: I4fd8bffc4785bef0148d12cd6f292d79c043b806
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
Reviewed-on: https://boringssl-review.googlesource.com/6566
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-12-15 19:02:31 +00:00
Brian Smith a0ef7b0a56 Enforce that |EC_KEY| private key is in [0, group->order).
Change-Id: I16abea5769737c7edd1be717f9a4f38678af43ce
Reviewed-on: https://boringssl-review.googlesource.com/6564
Reviewed-by: Adam Langley <agl@google.com>
2015-12-15 18:45:03 +00:00
Brian Smith 533a273871 Add |EC_METHOD| method for verifying public key order.
In some cases it would be good to restrict the input range of scalars
given to |EC_METHOD::mul| to be [0, order-1]. This is a first step
towards that goal.

Change-Id: I58a25db06f6c7a68a0ac1fe79794b04f7a173b23
Reviewed-on: https://boringssl-review.googlesource.com/6562
Reviewed-by: Adam Langley <agl@google.com>
2015-12-15 18:39:07 +00:00
Brian Smith a3d9de05fb Add |EC_GROUP_get0_order| to replace |EC_GROUP_get_order|.
|EC_GROUP_get0_order| doesn't require any heap allocations and never
fails, so it is much more convenient and more efficient for callers to
call.

Change-Id: Ic60f768875e7bc8e74362dacdb5cbbc6957b05a6
Reviewed-on: https://boringssl-review.googlesource.com/6532
Reviewed-by: Adam Langley <agl@google.com>
2015-12-15 18:18:13 +00:00
Sam Clegg 88478562a4 Include <sys/time.h> in packeted_bio.h for 'timeval'
At least for newlib (Native Client) including sys/types.h
is not enough to get a timeval declaration.

Change-Id: I4971a1aacc80b6fdc12c0e81c5d8007ed13eb8b7
Reviewed-on: https://boringssl-review.googlesource.com/6722
Reviewed-by: Adam Langley <agl@google.com>
2015-12-15 18:11:18 +00:00
Sam Clegg dca63cfa75 Don't abort in |init_once| if |fcntl| returns ENOSYS
Native Client doesn't support fcntl natively and its default
implemention just returns ENOSYS.

Change-Id: Id8615e2f6f0a75a1140f8efd75afde471ccdf466
Reviewed-on: https://boringssl-review.googlesource.com/6721
Reviewed-by: Adam Langley <agl@google.com>
2015-12-15 18:10:40 +00:00
Joachim Bauch afd565ff9c Add defines for SRTP profiles using GCM ciphers from RFC 7714.
BUG=webrtc:5222

Change-Id: I8399bd595564dedbe5492b8ea6eb915f41367cbf
Reviewed-on: https://boringssl-review.googlesource.com/6690
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: David Benjamin <davidben@google.com>
2015-12-10 23:18:16 +00:00
Adam Langley 902870e3b5 Gate SHA_CTX compatibility on !WINDOWS.
Windows does support anonymous unions but warns about it. Since I'm not
sure what warnings we have enabled in Chromium, this change just drops
the union for Windows.

Change-Id: I914f8cd5855eb07153105250c0f026eaedb35365
Reviewed-on: https://boringssl-review.googlesource.com/6631
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-12-04 22:13:19 +00:00
Adam Langley 34aa55c05e Support the SHA_CTX hack without ANDROID.
wpa_supplicant needs access to the internals of SHA_CTX. We supported
this only for builds with ANDROID defined previously but that's a pain
for wpa_supplicant to deal with. Thus this change enables it
unconditionally.

Perhaps in the future we'll be able to get a function to do this into
OpenSSL and BoringSSL.

Change-Id: Ib5d088c586fe69249c87404adb45aab5a7d5cf80
Reviewed-on: https://boringssl-review.googlesource.com/6630
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-12-04 20:23:46 +00:00
David Benjamin 6d9e5a7448 Re-apply 75b833cc81
I messed up and missed that we were carrying a diff on x86_64-mont5.pl. This
was accidentally dropped in https://boringssl-review.googlesource.com/6616.

To confirm the merge is good now, check out at this revision and run:

  git diff e701f16bd69b6f251ed537e40364c281e85a63b2^ crypto/bn/asm/x86_64-mont5.pl > /tmp/A

Then in OpenSSL's repository:

  git diff d73cc256c8e256c32ed959456101b73ba9842f72^ d73cc256c8e256c32ed959456101b73ba9842f72 crypto/bn/asm/x86_64-mont5.pl  > /tmp/B

And confirm the diffs vary in only metadata:

  diff -u /tmp/A /tmp/B

--- /tmp/A	2015-12-03 11:53:23.127034998 -0500
+++ /tmp/B	2015-12-03 11:53:53.099314287 -0500
@@ -1,8 +1,8 @@
 diff --git a/crypto/bn/asm/x86_64-mont5.pl b/crypto/bn/asm/x86_64-mont5.pl
-index 38def07..3c5a8fc 100644
+index 388e3c6..64e668f 100755
 --- a/crypto/bn/asm/x86_64-mont5.pl
 +++ b/crypto/bn/asm/x86_64-mont5.pl
-@@ -1770,6 +1770,15 @@ sqr8x_reduction:
+@@ -1784,6 +1784,15 @@ sqr8x_reduction:
  .align	32
  .L8x_tail_done:
  	add	(%rdx),%r8		# can this overflow?
@@ -18,7 +18,7 @@
  	xor	%rax,%rax

  	neg	$carry
-@@ -3116,6 +3125,15 @@ sqrx8x_reduction:
+@@ -3130,6 +3139,15 @@ sqrx8x_reduction:
  .align	32
  .Lsqrx8x_tail_done:
  	add	24+8(%rsp),%r8		# can this overflow?
@@ -34,7 +34,7 @@
  	mov	$carry,%rax		# xor	%rax,%rax

  	sub	16+8(%rsp),$carry	# mov 16(%rsp),%cf
-@@ -3159,13 +3177,11 @@ my ($rptr,$nptr)=("%rdx","%rbp");
+@@ -3173,13 +3191,11 @@ my ($rptr,$nptr)=("%rdx","%rbp");
  my @ri=map("%r$_",(10..13));
  my @ni=map("%r$_",(14..15));
  $code.=<<___;

Change-Id: I3fb5253783ed82e4831f5bffde75273bd9609c23
Reviewed-on: https://boringssl-review.googlesource.com/6618
Reviewed-by: Adam Langley <agl@google.com>
2015-12-03 17:25:12 +00:00
David Benjamin 28243c08db Add PSS parameter check.
Avoid seg fault by checking mgf1 parameter is not NULL. This can be
triggered during certificate verification so could be a DoS attack
against a client or a server enabling client authentication.

Thanks to Loïc Jonas Etienne (Qnective AG) for discovering this bug.

CVE-2015-3194

(Imported from upstream's c394a488942387246653833359a5c94b5832674e and test
data from 00456fded43eadd4bb94bf675ae4ea5d158a764f.)

Change-Id: Ic97059d42722fd810973ccb0c26c415c4eaae79a
Reviewed-on: https://boringssl-review.googlesource.com/6617
Reviewed-by: Adam Langley <agl@google.com>
2015-12-03 16:47:12 +00:00
David Benjamin e701f16bd6 bn/asm/x86_64-mont5.pl: fix carry propagating bug (CVE-2015-3193).
(Imported from upstream's d73cc256c8e256c32ed959456101b73ba9842f72.)

Change-Id: I673301fee57f0ab5bef24553caf8b2aac67fb3a9
Reviewed-on: https://boringssl-review.googlesource.com/6616
Reviewed-by: Adam Langley <agl@google.com>
2015-12-03 16:44:35 +00:00
David Benjamin cb852981cd Fix leak with ASN.1 combine.
When parsing a combined structure pass a flag to the decode routine
so on error a pointer to the parent structure is not zeroed as
this will leak any additional components in the parent.

This can leak memory in any application parsing PKCS#7 or CMS structures.

CVE-2015-3195.

Thanks to Adam Langley (Google/BoringSSL) for discovering this bug using
libFuzzer.

PR#4131

(Imported from upstream's cc598f321fbac9c04da5766243ed55d55948637d, with test
from our original report. Verified ASan trips up on the test without the fix.)

Change-Id: I007d93f172b2f16bf6845d685d72717ed840276c
Reviewed-on: https://boringssl-review.googlesource.com/6615
Reviewed-by: Adam Langley <agl@google.com>
2015-12-03 16:43:34 +00:00
Adam Langley c4f25ce0c6 Work around yaSSL bug.
yaSSL has a couple of bugs in their DH client implementation. This
change works around the worst of the two.

Firstly, they expect the the DH public value to be the same length as
the prime. This change pads the public value as needed to ensure this.

Secondly, although they handle the first byte of the shared key being
zero, they don't handle the case of the second, third, etc bytes being
zero. So whenever that happens the handshake fails. I don't think that
there's anything that we can do about that one.

Change-Id: I789c9e5739f19449473305d59fe5c3fb9b4a6167
Reviewed-on: https://boringssl-review.googlesource.com/6578
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-11-30 22:41:24 +00:00
Brian Smith c5eb4676b6 Remove dead code in p256-x86_64.
Change-Id: I9d0b3fa39445d08202c67d905d2c676d5d968c33
Reviewed-on: https://boringssl-review.googlesource.com/6561
Reviewed-by: Adam Langley <agl@google.com>
2015-11-20 23:45:43 +00:00
David Benjamin 758d12732a Add get0 getters for EVP_PKEY.
Right now your options are:
- Bounce on a reference and deal with cleanup needlessly.
- Manually check the type tag and peek into the union.

We probably have no hope of opaquifying this struct, but for new code, let's
recommend using this function rather than the more error-prone thing.

Change-Id: I9b39ff95fe4264a3f7d1e0d2894db337aa968f6c
Reviewed-on: https://boringssl-review.googlesource.com/6551
Reviewed-by: Adam Langley <agl@google.com>
2015-11-20 23:34:12 +00:00
Mostyn Bramley-Moore fde89b43c3 avoid clashes with libc's 'open' in e_chacha20poly1305.c
Some strange toolchains can have an implicit (or explicit) fcntl.h include,
so let's avoid using the name 'open' for local functions.  This should not
cause any trouble.

Change-Id: Ie131b5920ac23938013c2c03302b97a7418c7180
Reviewed-on: https://boringssl-review.googlesource.com/6540
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-11-20 20:02:23 +00:00
Brian Smith 60a45aa7cc Remove reference to removed |RSA_FLAG_NO_CONSTTIME| flag.
Change-Id: I0bfdccf009772d4ff8cd419758ab5bfae95f5cc5
Reviewed-on: https://boringssl-review.googlesource.com/6530
Reviewed-by: Adam Langley <agl@google.com>
2015-11-20 19:59:29 +00:00
David Benjamin 81edc9beb6 Do away with BN_LLONG in favor of BN_ULLONG.
BN_LLONG is only ever used in #ifdefs. The actual type is BN_ULLONG. Switch the
ifdefs to check on BN_ULLONG and remove BN_LLONG. Also fix signedness of all
the constants (potentially avoiding undefined behavior in some operations).

Change-Id: I3e7739bbe14c50ea7db04fc507a034a8cb315a5f
Reviewed-on: https://boringssl-review.googlesource.com/6518
Reviewed-by: Adam Langley <agl@google.com>
2015-11-20 19:59:07 +00:00
Matt Braithwaite e8fe07fcc4 Fix AES XTS mode key size.
I screwed up the |EVP_CIPHER| parameters for XTS when I first imported
it, and there were no tests to catch it.  (The problem was that
|EVP_CIPH_XTS_MODE| means “the key size is actually twice what it says
here.”)

With these changes, OpenSSL's tests pass.

(Along the way, make a few other things about XTS slightly less
decrepit.)

Change-Id: Icbfbc5e6d532d1c132392ee366f9cab42802d674
Reviewed-on: https://boringssl-review.googlesource.com/6529
Reviewed-by: Adam Langley <agl@google.com>
2015-11-19 18:08:33 +00:00
David Benjamin 93a5b44296 Make CRYPTO_library_init use a CRYPTO_once_t.
Initialization by multiple consumers on ARM is still problematic due to
CRYPTO_set_NEON_{capable,functional}, until we reimplement that in-library, but
if that is called before the first CRYPTO_library_init, this change makes it
safe.

BUG=556462

Change-Id: I5845d09cca909bace8293ba7adf09a3bd0d4f943
Reviewed-on: https://boringssl-review.googlesource.com/6519
Reviewed-by: Adam Langley <agl@google.com>
2015-11-19 18:05:22 +00:00
Brian Smith bf762186c6 Remove the |ri| field of |BN_MONT_CTX|.
The |ri| field was only used in |BN_MONT_CTX_set|, so make it a local
variable of that function.

Change-Id: Id8c3d44ac2e30e3961311a7b1a6731fe2c33a0eb
Reviewed-on: https://boringssl-review.googlesource.com/6526
Reviewed-by: Adam Langley <agl@google.com>
2015-11-19 01:40:13 +00:00
Brian Smith 596ab10b0f s/BN_BITS/BN_BITS2/ in |BN_mod_inverse_ex|; remove |BN_BITS| & |BN_MASK|.
The comment in |BN_mod_inverse_ex| makes it clear that |BN_BITS2| was
intended. Besides fixing the code to match the comment, remove
the now-unused |BN_BITS| and the already-unused |BN_MASK| to prevent
future confusion of this sort.

On MSVC builds there seems to be very little difference in performance
between the two code paths according to |bssl speed|.

Change-Id: I765b7b3d464e2057b1d7952af25b6deb2724976a
Reviewed-on: https://boringssl-review.googlesource.com/6525
Reviewed-by: Adam Langley <agl@google.com>
2015-11-19 01:39:32 +00:00
Brian Smith 7af36e1e38 Share common definitions of |TOBN| and |BIGNUM_STATIC|.
Previously, both crypto/dh and crypto/ec defined |TOBN| macros that did
the same thing, but which took their arguments in the opposite order.
This change makes the code consistently use the same macro. It also
makes |STATIC_BIGNUM| available for internal use outside of crypto/bn.

Change-Id: Ide57f6a5b74ea95b3585724c7e1a630c82a864d9
Reviewed-on: https://boringssl-review.googlesource.com/6528
Reviewed-by: Adam Langley <agl@google.com>
2015-11-19 01:38:52 +00:00
David Benjamin ff2df337a0 Reformat the cipher suite table.
clang-format packing them tightly made newlines inconsistent which
wasn't very helpful.

Change-Id: I46a787862ed1f5b0eee101394e24c779b6bc652b
Reviewed-on: https://boringssl-review.googlesource.com/6517
Reviewed-by: Adam Langley <agl@google.com>
2015-11-19 01:32:55 +00:00
David Benjamin 9f2e2770e1 Remove strength_bits.
Trim the cipher table further. Those values are entirely determined by
algorithm_enc.

Change-Id: I355c245b0663e41e54e62d15903a4a9a667b4ffe
Reviewed-on: https://boringssl-review.googlesource.com/6516
Reviewed-by: Adam Langley <agl@google.com>
2015-11-19 01:32:28 +00:00
David Benjamin d6e9eec3f8 Remove algo_strength.
FIPS is the same as HIGH (but for CHACHA20), so those are redundant.
Likewise, MEDIUM vs HIGH was just RC4. Remove those in favor of
redefining those legacy rules to mean this.

One less field to keep track of in each cipher.

Change-Id: I2b2489cffb9e16efb0ac7d7290c173cac061432a
Reviewed-on: https://boringssl-review.googlesource.com/6515
Reviewed-by: Adam Langley <agl@google.com>
2015-11-19 01:30:44 +00:00
David Benjamin dcb6ef0f0b Remove algorithm_ssl.
It's redundant with other cipher properties. We can express these in code.
Cipher rule matching gets a little bit complicated due to the confusing legacy
protocol version cipher rules, so add some tests for it. (It's really hard to
grep for uses of them, so I've kept them working to be safe.)

Change-Id: Ic6b3fcd55d76d4a51b31bf7ae629a2da50a7450e
Reviewed-on: https://boringssl-review.googlesource.com/6453
Reviewed-by: Adam Langley <agl@google.com>
2015-11-19 01:28:24 +00:00
David Benjamin d28f59c27b Switch the keylog BIO to a callback.
The keylog BIO is internally synchronized by the SSL_CTX lock, but an
application may wish to log keys from multiple SSL_CTXs. This is in
preparation for switching Chromium to use a separate SSL_CTX per profile
to more naturally split up the session caches.

It will also be useful for routing up SSLKEYLOGFILE in WebRTC. There,
each log line must be converted to an IPC up from the renderer
processes.

This will require changes in Chromium when we roll BoringSSL.

BUG=458365,webrtc:4417

Change-Id: I2945bdb4def0a9c36e751eab3d5b06c330d66b54
Reviewed-on: https://boringssl-review.googlesource.com/6514
Reviewed-by: Adam Langley <agl@google.com>
2015-11-19 01:23:49 +00:00
David Benjamin fba735cfd8 Register the *25519 tests as dependencies of all_tests.
This ensures the run_tests target updates those binaries.

Change-Id: I32b68026da4852424b5621e014e71037c8a5754c
Reviewed-on: https://boringssl-review.googlesource.com/6513
Reviewed-by: Adam Langley <agl@google.com>
2015-11-19 01:09:09 +00:00
Brian Smith f3376ace43 Remove |EC_POINTs_mul| & simplify p256-x86_64.
Without |EC_POINTs_mul|, there's never more than one variable point
passed to a |EC_METHOD|'s |mul| method. This allows them to be
simplified considerably. In this commit, the p256-x86_64 implementation
has been simplified to eliminate the heap allocation and looping
related that was previously necessary to deal with the possibility of
there being multiple input points. The other implementations were left
mostly as-is; they should be similarly simplified in the future.

Change-Id: I70751d1d5296be2562af0730e7ccefdba7a1acae
Reviewed-on: https://boringssl-review.googlesource.com/6493
Reviewed-by: Adam Langley <agl@google.com>
2015-11-19 01:08:46 +00:00
Brian Smith 301efc8cea Fix error handling in |p256-x86_64|.
This makes similar fixes as were done in the following OpenSSL commits:

    c028254b12a8ea0d0f8a677172eda2e2d78073f3: Correctly set Z_is_one on
    the return value in the NISTZ256 implementation.

    e22d2199e2a5cc9b243f45c2b633d1e31fadecd7: Error checking and memory
    leak leak fixes in NISTZ256.

    4446044a793a9103a4bc70c0214005e6a4463767: NISTZ256: set Z_is_one to
    boolean 0/1 as is customary.

    a4d5269e6d0dba0c276c968448a3576f7604666a: NISTZ256: don't swallow
    malloc errors.

The fixes aren't exactly the same. In particular, the comments "This is
an unusual input, we don't guarantee constant-timeness" and the changes
to |ecp_nistz256_mult_precompute| (which isn't in BoringSSL) were
omitted.

Change-Id: Ia7bb982daa62fb328e8bd2d4dd49a8857e104096
Reviewed-on: https://boringssl-review.googlesource.com/6492
Reviewed-by: Adam Langley <agl@google.com>
2015-11-19 00:52:33 +00:00
Brian Smith e2136d9c28 Remove |EC_GROUP_precompute_mult| and |EC_KEY_precompute_mult|.
Change-Id: I1663ec6046b8f1f67a62e4c6483af719d6f362ad
Reviewed-on: https://boringssl-review.googlesource.com/6486
Reviewed-by: Adam Langley <agl@google.com>
2015-11-19 00:35:59 +00:00
Brian Smith 9b26297608 Make |EC_GROUP_precompute_mult|/|EC_KEY_precompute_mult| no-ops.
This moves us closer to having |EC_GROUP| and |EC_KEY| being immutable.
The functions are left as no-ops for backward compatibility.

Change-Id: Ie23921ab0364f0771c03aede37b064804c9f69e0
Reviewed-on: https://boringssl-review.googlesource.com/6485
Reviewed-by: Adam Langley <agl@google.com>
2015-11-19 00:27:39 +00:00
Brian Smith 5058d79948 Remove p224-64 and p256-64 dead code for non-default generators.
This extends 9f1f04f313 to the other
implementations.

|EC_GFp_nistp224_method| and |EC_GFp_nistp256_method| are not marked
|OPENSSL_EXPORT|. |EC_GROUP_set_generator| doesn't allow the generator
to be changed for any |EC_GROUP| for built-in curves. Consequently,
there's no way (except some kind of terrible abuse) that this code
could be executed with a non-default generator.

Change-Id: I5d9b6be4e6f9d384159cb3d708390a8e3c69f23f
Reviewed-on: https://boringssl-review.googlesource.com/6489
Reviewed-by: Adam Langley <agl@google.com>
2015-11-19 00:23:14 +00:00
Adam Langley b1b6229fc8 Add NEON implementation of curve25519.
Nexus 7 goes from 1002.8 ops/sec to 4704.8 at a cost of 10KB of code.
(It'll actually save code if built with -mfpu=neon because then the
generic version can be discarded by the compiler.)

Change-Id: Ia6d02efb2c2d1bb02a07eb56ec4ca3b0dba99382
Reviewed-on: https://boringssl-review.googlesource.com/6524
Reviewed-by: Adam Langley <agl@google.com>
2015-11-19 00:20:38 +00:00
Adam Langley 9e65d487b8 Allow |CRYPTO_is_NEON_capable| to be known at compile time, if possible.
If -mfpu=neon is passed then we don't need to worry about checking for
NEON support at run time. This change allows |CRYPTO_is_NEON_capable| to
statically return 1 in this case. This then allows the compiler to
discard generic code in several cases.

Change-Id: I3b229740ea3d5cb0a304f365c400a0996d0c66ef
Reviewed-on: https://boringssl-review.googlesource.com/6523
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-11-19 00:15:11 +00:00
Adam Langley 3ac32b1eda Fix curve25519 code for MSVC.
MSVC doesn't like unary minus on unsigned types. Also, the speed test
always failed because the inputs were all zeros and thus had small
order.

Change-Id: Ic2d3c2c9bd57dc66295d93891396871cebac1e0b
2015-11-17 15:15:05 -08:00
Adam Langley 4fb0dc4b03 Add X25519 and Ed25519 support.
(Ed25519 support is disabled when |OPENSSL_SMALL| is defined.)

libcrypto.a sizes:

x86-64 -O3 -march=native: +78012 (1584902 → 1662914)
x86-64 -O3 -march=native -DOPENSSL_SMALL: +10596 (1356206 → 1366802)
Android armv7 Thumb -O2 -DOPENSSL_SMALL: +13132 (1258462 → 1271594)

Change-Id: I6a7e64d481e4ce4daa7d5057578081358746cfb9
Reviewed-on: https://boringssl-review.googlesource.com/6497
Reviewed-by: Adam Langley <agl@google.com>
2015-11-17 21:56:12 +00:00
Piotr Sikora c324f1783e Make sure pthread_once() succeeds.
It can fail on FreeBSD when library is not linked against either
threading library and results in init routine not being executed
at all, leading to errors in other parts of the code.

Change-Id: I1063f6940e381e6470593c063fbfecf3f47991cd
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
Reviewed-on: https://boringssl-review.googlesource.com/6522
Reviewed-by: Adam Langley <agl@google.com>
2015-11-17 21:44:40 +00:00
Piotr Sikora 9361243065 Don't include <alloca.h>, it's no longer needed.
Relevant code was removed in 5d5e39f5d2.

Change-Id: I198844064030c04f88e5541f2bbaa29ae13d14bb
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
Reviewed-on: https://boringssl-review.googlesource.com/6521
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-11-17 19:21:40 +00:00
Adam Langley b00061cea7 Add SSL_CIPHER_is_AES[128|256]CBC.
Change-Id: I3072f884be77b8646e90d316154b96448f0cf2a1
Reviewed-on: https://boringssl-review.googlesource.com/6520
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-11-17 19:15:06 +00:00
David Benjamin 3a59611726 size_t SSL*_use_*_ASN1.
So long as we're not getting rid of them (the certificate variants may
be useful when we decouple from crypto/x509 anyway), get the types and
bounds checks right.

Also reject trailing data and require the input be a single element.
Note: this is a slight compatibility risk, but we did it for
SSL*_use_RSAPrivateKey_ASN1 previously and I think it's probably worth
seeing if anything breaks here.

Change-Id: I64fa3fc6249021ccf59584d68e56ff424a190082
Reviewed-on: https://boringssl-review.googlesource.com/6490
Reviewed-by: Adam Langley <agl@google.com>
2015-11-16 23:59:14 +00:00
David Benjamin b324159be9 Fix ssl3_send_server_key_exchange error path.
This codepath should not actually be reachable, unless maybe the caller is
doing something really dumb. (Unconfiguring the key partway through the
connection.)

Change-Id: Ic8e0cfc3c426439016370f9a85be9c05509358f1
Reviewed-on: https://boringssl-review.googlesource.com/6483
Reviewed-by: Adam Langley <agl@google.com>
2015-11-16 23:27:27 +00:00
David Benjamin f584a5aaa2 Reset epoch state in one place.
TLS resets it in t1_enc.c while DTLS has it sprinkled everywhere.

Change-Id: I78f0f0e646b4dc82a1058199c4b00f2e917aa5bc
Reviewed-on: https://boringssl-review.googlesource.com/6511
Reviewed-by: Adam Langley <agl@google.com>
2015-11-16 23:19:31 +00:00
David Benjamin 2077cf9152 Use UINT64_C instead of OPENSSL_U64.
stdint.h already has macros for this. The spec says that, in C++,
__STDC_CONSTANT_MACROS is needed, so define it for bytestring_test.cc.
Chromium seems to use these macros without trouble, so I'm assuming we
can rely on them.

Change-Id: I56d178689b44d22c6379911bbb93d3b01dd832a3
Reviewed-on: https://boringssl-review.googlesource.com/6510
Reviewed-by: Adam Langley <agl@google.com>
2015-11-16 23:18:00 +00:00
David Benjamin af07365b49 Check for overflow when parsing a CBS with d2i_*.
Until we've done away with the d2i_* stack completely, boundaries need
to be mindful of the type mismatch. d2i_* takes a long, not a size_t.

Change-Id: If02f9ca2cfde02d0929ac18275d09bf5df400f3a
Reviewed-on: https://boringssl-review.googlesource.com/6491
Reviewed-by: Adam Langley <agl@google.com>
2015-11-16 23:17:42 +00:00
David Benjamin 780cd92b98 modes/asm/ghash-armv4.pl: extend Apple fix to all clang cases.
Triggered by RT#3989.

(Imported from upstream's fbab8baddef8d3346ae40ff068871e2ddaf10270. This
doesn't seem to affect us, but avoid getting out of sync.)

Change-Id: I164e2a72e4b75e286ceaa03745ed9bcbf6c3e32e
Reviewed-on: https://boringssl-review.googlesource.com/6512
Reviewed-by: Adam Langley <agl@google.com>
2015-11-16 23:11:19 +00:00
Adam Langley f9c77dedfa Drop CBB allocation failure test.
To no great surprise, ASAN didn't like this test and I suspect that
Chromium, with its crashing allocator, won't like it either. Oh well.

Change-Id: I235dbb965dbba186f8f37d7df45f8eac9addc7eb
Reviewed-on: https://boringssl-review.googlesource.com/6496
Reviewed-by: Adam Langley <agl@google.com>
2015-11-16 22:25:59 +00:00
Adam Langley a33915d690 Have |CBB_init| zero the |CBB| before any possible failures.
People expect to do:

CBB foo;

if (!CBB_init(&foo, 100) ||
    …
    …) {
  CBB_cleanup(&foo);
  return 0;
}

However, currently, if the allocation of |initial_capacity| fails in
|CBB_init| then |CBB_cleanup| will operate on uninitialised values. This
change makes the above pattern safe.

Change-Id: I3e002fda8f0a3ac18650b504e7e84a842d4165ca
Reviewed-on: https://boringssl-review.googlesource.com/6495
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-11-16 21:59:46 +00:00
Adam Langley c5c85defb2 Make RAND_seed read a byte of random data.
OpenSSH calls |RAND_seed| before jailing in the expectation that that
will be sufficient to ensure that later RAND calls are successful.

See internal bug 25695426.

Change-Id: I9d3f5665249af6610328ac767cb83059bb2953dd
Reviewed-on: https://boringssl-review.googlesource.com/6494
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-11-16 21:58:46 +00:00
Adam Langley d9e27021e1 Don't encode or decode ∞.
|EC_POINT_point2oct| would encode ∞, which is surprising, and
|EC_POINT_oct2point| would decode ∞, which is insane. This change
removes both behaviours.

Thanks to Brian Smith for pointing it out.

Change-Id: Ia89f257dc429a69b9ea7b7b15f75454ccc9c3bdd
Reviewed-on: https://boringssl-review.googlesource.com/6488
Reviewed-by: Adam Langley <agl@google.com>
2015-11-12 23:52:37 +00:00
Adam Langley e7806fd477 Remove point-on-curve check from |ec_GFp_simple_oct2point|.
In the case of a compressed point, the decompression ensures that the
point is on the curve. In the uncompressed case,
|EC_POINT_set_affine_coordinates_GFp| checks that the point is on the
curve as of 38feb990a1.

Change-Id: Icd69809ae396838b4aef4fa89b3b354560afed55
Reviewed-on: https://boringssl-review.googlesource.com/6487
Reviewed-by: Brian Smith <brian@briansmith.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-11-12 23:51:17 +00:00
David Benjamin 20c373118c Become partially -Wmissing-variable-declarations-clean.
There's a few things that will be kind of a nuisance and possibly not worth it
(crypto/asn1 dumps a lot of undeclared things, etc.). But it caught some
mistakes. Even without the warning, making sure to include the externs before
defining a function helps catch type mismatches.

Change-Id: I3dab282aaba6023e7cebc94ed7a767a5d7446b08
Reviewed-on: https://boringssl-review.googlesource.com/6484
Reviewed-by: Adam Langley <agl@google.com>
2015-11-12 20:09:20 +00:00
Brian Smith 7308aaa9b4 Remove EC_GFp_simple_method (dead code).
Change-Id: I1820bd5412313e00a69123370178c0fe3e12b5ef
Reviewed-on: https://boringssl-review.googlesource.com/6482
Reviewed-by: Adam Langley <agl@google.com>
2015-11-12 20:07:51 +00:00
Brian Smith f872951880 Fix null pointer dereference when using "simple" EC.
This regressed in f0523e9f20.

Change-Id: I70c3fcb0d91ac00e5088b086312384756eda6140
Reviewed-on: https://boringssl-review.googlesource.com/6481
Reviewed-by: Adam Langley <agl@google.com>
2015-11-12 20:05:13 +00:00
Brian Smith 8bde5d2e51 Remove the unused |Ni| member of |BN_MONT_CTX|.
Change-Id: I0a542c48c7adae28f05778d6c34c9b6836fc3449
Reviewed-on: https://boringssl-review.googlesource.com/6480
Reviewed-by: Adam Langley <agl@google.com>
2015-11-12 20:04:43 +00:00
David Benjamin ce7ae6fa27 Enable AVX code for SHA-*.
SHA-1, SHA-256, and SHA-512 get a 12-26%, 17-23%, and 33-37% improvement,
respectively on x86-64. SHA-1 and SHA-256 get a 8-20% and 14-17% improvement on
x86. (x86 does not have AVX code for SHA-512.) This costs us 12k of binary size
on x86-64 and 8k of binary size on x86.

$ bssl speed SHA- (x86-64, before)
Did 4811000 SHA-1 (16 bytes) operations in 1000013us (4810937.5 ops/sec): 77.0 MB/s
Did 1414000 SHA-1 (256 bytes) operations in 1000253us (1413642.3 ops/sec): 361.9 MB/s
Did 56000 SHA-1 (8192 bytes) operations in 1002640us (55852.5 ops/sec): 457.5 MB/s
Did 2536000 SHA-256 (16 bytes) operations in 1000140us (2535645.0 ops/sec): 40.6 MB/s
Did 603000 SHA-256 (256 bytes) operations in 1001613us (602028.9 ops/sec): 154.1 MB/s
Did 25000 SHA-256 (8192 bytes) operations in 1010132us (24749.2 ops/sec): 202.7 MB/s
Did 1767000 SHA-512 (16 bytes) operations in 1000477us (1766157.5 ops/sec): 28.3 MB/s
Did 638000 SHA-512 (256 bytes) operations in 1000933us (637405.3 ops/sec): 163.2 MB/s
Did 32000 SHA-512 (8192 bytes) operations in 1025646us (31199.8 ops/sec): 255.6 MB/s

$ bssl speed SHA- (x86-64, after)
Did 5438000 SHA-1 (16 bytes) operations in 1000060us (5437673.7 ops/sec): 87.0 MB/s
Did 1590000 SHA-1 (256 bytes) operations in 1000181us (1589712.3 ops/sec): 407.0 MB/s
Did 71000 SHA-1 (8192 bytes) operations in 1007958us (70439.4 ops/sec): 577.0 MB/s
Did 2955000 SHA-256 (16 bytes) operations in 1000251us (2954258.5 ops/sec): 47.3 MB/s
Did 740000 SHA-256 (256 bytes) operations in 1000628us (739535.6 ops/sec): 189.3 MB/s
Did 31000 SHA-256 (8192 bytes) operations in 1019619us (30403.5 ops/sec): 249.1 MB/s
Did 2348000 SHA-512 (16 bytes) operations in 1000285us (2347331.0 ops/sec): 37.6 MB/s
Did 878000 SHA-512 (256 bytes) operations in 1001064us (877066.8 ops/sec): 224.5 MB/s
Did 43000 SHA-512 (8192 bytes) operations in 1002485us (42893.4 ops/sec): 351.4 MB/s

$ bssl speed SHA- (x86, before, SHA-512 redacted because irrelevant)
Did 4319000 SHA-1 (16 bytes) operations in 1000066us (4318715.0 ops/sec): 69.1 MB/s
Did 1306000 SHA-1 (256 bytes) operations in 1000437us (1305429.5 ops/sec): 334.2 MB/s
Did 58000 SHA-1 (8192 bytes) operations in 1014807us (57153.7 ops/sec): 468.2 MB/s
Did 2291000 SHA-256 (16 bytes) operations in 1000343us (2290214.5 ops/sec): 36.6 MB/s
Did 594000 SHA-256 (256 bytes) operations in 1000684us (593594.0 ops/sec): 152.0 MB/s
Did 25000 SHA-256 (8192 bytes) operations in 1030688us (24255.6 ops/sec): 198.7 MB/s

$ bssl speed SHA- (x86, after, SHA-512 redacted because irrelevant)
Did 4673000 SHA-1 (16 bytes) operations in 1000063us (4672705.6 ops/sec): 74.8 MB/s
Did 1484000 SHA-1 (256 bytes) operations in 1000453us (1483328.1 ops/sec): 379.7 MB/s
Did 69000 SHA-1 (8192 bytes) operations in 1008305us (68431.7 ops/sec): 560.6 MB/s
Did 2684000 SHA-256 (16 bytes) operations in 1000196us (2683474.0 ops/sec): 42.9 MB/s
Did 679000 SHA-256 (256 bytes) operations in 1000525us (678643.7 ops/sec): 173.7 MB/s
Did 29000 SHA-256 (8192 bytes) operations in 1033251us (28066.8 ops/sec): 229.9 MB/s

Change-Id: I952a3b4fc4c52ebb50690da3b8c97770e8342e98
Reviewed-on: https://boringssl-review.googlesource.com/6470
Reviewed-by: Adam Langley <agl@google.com>
2015-11-12 20:03:32 +00:00
Brian Smith 9f1f04f313 Remove nistz256 dead code for non-default generators.
|EC_GFp_nistz256_method| is not marked |OPENSSL_EXPORT| so only the
built-in P-256 curve uses it. |EC_GROUP_set_generator| doesn't allow
the generator to be changed for any |EC_GROUP| for a built-in curve.
Consequently, there's no way (except some kind of terrible abuse) that
the nistz code could be executed with a non-default generator.

Change-Id: Ib22f00bc74c103b7869ed1e35032b1f3d26cdad2
Reviewed-on: https://boringssl-review.googlesource.com/6446
Reviewed-by: Adam Langley <agl@google.com>
2015-11-12 19:59:16 +00:00
166 changed files with 13866 additions and 5071 deletions
+2
View File
@@ -105,6 +105,7 @@ add_subdirectory(rc4)
add_subdirectory(conf)
add_subdirectory(chacha)
add_subdirectory(poly1305)
add_subdirectory(curve25519)
# Level 1, depends only on 0.*
add_subdirectory(digest)
@@ -174,6 +175,7 @@ add_library(
$<TARGET_OBJECTS:conf>
$<TARGET_OBJECTS:chacha>
$<TARGET_OBJECTS:poly1305>
$<TARGET_OBJECTS:curve25519>
$<TARGET_OBJECTS:buf>
$<TARGET_OBJECTS:bn>
$<TARGET_OBJECTS:bio>
+11
View File
@@ -43,3 +43,14 @@ add_library(
x_bignum.c
x_long.c
)
add_executable(
asn1_test
asn1_test.cc
$<TARGET_OBJECTS:test_support>
)
target_link_libraries(asn1_test crypto)
add_dependencies(all_tests asn1_test)
+3 -1
View File
@@ -125,6 +125,8 @@ int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
{
ret=a->length;
i=a->data[0];
if (ret == 1 && i == 0)
neg = 0;
if (!neg && (i > 127)) {
pad=1;
pb=0;
@@ -158,7 +160,7 @@ int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
p += a->length - 1;
i = a->length;
/* Copy zeros to destination as long as source is zero */
while(!*n) {
while(!*n && i > 1) {
*(p--) = 0;
n--;
i--;
+5
View File
@@ -161,6 +161,11 @@ int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
p++;
if (--max == 0) goto err;
}
/* To avoid ambiguity with V_ASN1_NEG, impose a limit on universal tags. */
if (xclass == V_ASN1_UNIVERSAL && tag > V_ASN1_MAX_UNIVERSAL)
goto err;
*ptag=tag;
*pclass=xclass;
if (!asn1_get_length(&p,&inf,plength,(int)max)) goto err;
+9
View File
@@ -61,6 +61,8 @@
#include <openssl/mem.h>
#define ASN1_PARSE_MAXDEPTH 128
static int asn1_print_info(BIO *bp, int tag, int xclass,int constructed,
int indent);
static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
@@ -125,6 +127,13 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
#else
dump_indent = 6; /* Because we know BIO_dump_indent() */
#endif
if (depth > ASN1_PARSE_MAXDEPTH)
{
BIO_puts(bp, "BAD RECURSION DEPTH\n");
return 0;
}
p= *pp;
tot=p+length;
op=p-1;
+51
View File
@@ -0,0 +1,51 @@
/* Copyright (c) 2016, 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/asn1.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include "../test/scoped_types.h"
// kTag258 is an ASN.1 structure with a universal tag with number 258.
static const uint8_t kTag258[] = {
0x1f, 0x82, 0x02, 0x01, 0x00,
};
static_assert(V_ASN1_NEG_INTEGER == 258,
"V_ASN1_NEG_INTEGER changed. Update kTag258 to collide with it.");
bool TestLargeTags() {
const uint8_t *p = kTag258;
ScopedASN1_TYPE obj(d2i_ASN1_TYPE(NULL, &p, sizeof(kTag258)));
if (obj) {
fprintf(stderr, "Parsed value with illegal tag (type = %d).\n", obj->type);
return false;
}
return true;
}
int main() {
CRYPTO_library_init();
if (!TestLargeTags()) {
return 1;
}
printf("PASS\n");
return 0;
}
+4 -2
View File
@@ -170,6 +170,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
int otag;
int ret = 0;
ASN1_VALUE **pchptr, *ptmpval;
int combine = aclass & ASN1_TFLG_COMBINE;
if (!pval)
return 0;
if (aux && aux->asn1_cb)
@@ -526,7 +527,8 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
auxerr:
OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
err:
ASN1_item_ex_free(pval, it);
if (combine == 0)
ASN1_item_ex_free(pval, it);
if (errtt)
ERR_add_error_data(4, "Field=", errtt->field_name,
", Type=", it->sname);
@@ -742,7 +744,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
{
/* Nothing special */
ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item),
-1, 0, opt, ctx);
-1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx);
if (!ret)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
+1 -1
View File
@@ -72,7 +72,7 @@
/* ASN1_PCTX routines */
ASN1_PCTX default_pctx =
static ASN1_PCTX default_pctx =
{
ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */
0, /* nm_flags */
+4 -21
View File
@@ -56,6 +56,8 @@
#include <openssl/bn.h>
#include <string.h>
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -311,27 +313,8 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
}
}
if (rp != ap) {
for (;;) {
if (!dif--) {
break;
}
rp[0] = ap[0];
if (!dif--) {
break;
}
rp[1] = ap[1];
if (!dif--) {
break;
}
rp[2] = ap[2];
if (!dif--) {
break;
}
rp[3] = ap[3];
rp += 4;
ap += 4;
}
if (dif > 0 && rp != ap) {
memcpy(rp, ap, sizeof(*rp) * dif);
}
r->top = max;
+19 -3
View File
@@ -1770,6 +1770,15 @@ sqr8x_reduction:
.align 32
.L8x_tail_done:
add (%rdx),%r8 # can this overflow?
adc \$0,%r9
adc \$0,%r10
adc \$0,%r11
adc \$0,%r12
adc \$0,%r13
adc \$0,%r14
adc \$0,%r15 # can't overflow, because we
# started with "overhung" part
# of multiplication
xor %rax,%rax
neg $carry
@@ -3116,6 +3125,15 @@ sqrx8x_reduction:
.align 32
.Lsqrx8x_tail_done:
add 24+8(%rsp),%r8 # can this overflow?
adc \$0,%r9
adc \$0,%r10
adc \$0,%r11
adc \$0,%r12
adc \$0,%r13
adc \$0,%r14
adc \$0,%r15 # can't overflow, because we
# started with "overhung" part
# of multiplication
mov $carry,%rax # xor %rax,%rax
sub 16+8(%rsp),$carry # mov 16(%rsp),%cf
@@ -3159,13 +3177,11 @@ my ($rptr,$nptr)=("%rdx","%rbp");
my @ri=map("%r$_",(10..13));
my @ni=map("%r$_",(14..15));
$code.=<<___;
xor %rbx,%rbx
xor %ebx,%ebx
sub %r15,%rsi # compare top-most words
adc %rbx,%rbx
mov %rcx,%r10 # -$num
.byte 0x67
or %rbx,%rax
.byte 0x67
mov %rcx,%r9 # -$num
xor \$1,%rax
sar \$3+2,%rcx # cf=0
+3 -4
View File
@@ -166,11 +166,10 @@ void BN_clear(BIGNUM *bn) {
}
const BIGNUM *BN_value_one(void) {
static const BN_ULONG data_one = 1;
static const BIGNUM const_one = {(BN_ULONG *)&data_one, 1, 1, 0,
BN_FLG_STATIC_DATA};
static const BN_ULONG kOneLimbs[1] = { 1 };
static const BIGNUM kOne = STATIC_BIGNUM(kOneLimbs);
return &const_one;
return &kOne;
}
void BN_with_flags(BIGNUM *out, const BIGNUM *in, int flags) {
+28 -7
View File
@@ -330,6 +330,13 @@ int main(int argc, char *argv[]) {
return 0;
}
static int HexToBIGNUM(ScopedBIGNUM *out, const char *in) {
BIGNUM *raw = NULL;
int ret = BN_hex2bn(&raw, in);
out->reset(raw);
return ret;
}
static bool test_add(FILE *fp) {
ScopedBIGNUM a(BN_new());
ScopedBIGNUM b(BN_new());
@@ -1107,6 +1114,27 @@ static bool test_mod_exp(FILE *fp, BN_CTX *ctx) {
return false;
}
}
// Regression test for carry propagation bug in sqr8x_reduction.
if (!HexToBIGNUM(&a, "050505050505") ||
!HexToBIGNUM(&b, "02") ||
!HexToBIGNUM(
&c,
"4141414141414141414141274141414141414141414141414141414141414141"
"4141414141414141414141414141414141414141414141414141414141414141"
"4141414141414141414141800000000000000000000000000000000000000000"
"0000000000000000000000000000000000000000000000000000000000000000"
"0000000000000000000000000000000000000000000000000000000000000000"
"0000000000000000000000000000000000000000000000000000000001") ||
!BN_mod_exp(d.get(), a.get(), b.get(), c.get(), ctx) ||
!BN_mul(e.get(), a.get(), a.get(), ctx)) {
return false;
}
if (BN_cmp(d.get(), e.get()) != 0) {
fprintf(stderr, "BN_mod_exp and BN_mul produce different results!\n");
return false;
}
return true;
}
@@ -1545,13 +1573,6 @@ static bool test_dec2bn(BN_CTX *ctx) {
return true;
}
static int HexToBIGNUM(ScopedBIGNUM *out, const char *in) {
BIGNUM *raw = NULL;
int ret = BN_hex2bn(&raw, in);
out->reset(raw);
return ret;
}
static bool test_hex2bn(BN_CTX *ctx) {
ScopedBIGNUM bn;
int ret = HexToBIGNUM(&bn, "0");
+6 -6
View File
@@ -260,10 +260,10 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
q = BN_MASK2;
} else {
/* n0 < d0 */
#ifdef BN_LLONG
#ifdef BN_ULLONG
BN_ULLONG t2;
#if defined(BN_LLONG) && !defined(div_asm)
#if defined(BN_ULLONG) && !defined(div_asm)
q = (BN_ULONG)(((((BN_ULLONG)n0) << BN_BITS2) | n1) / d0);
#else
q = div_asm(n0, n1, d0);
@@ -288,7 +288,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
}
t2 -= d1;
}
#else /* !BN_LLONG */
#else /* !BN_ULLONG */
BN_ULONG t2l, t2h;
#if defined(div_asm)
@@ -331,7 +331,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
}
t2l -= d1;
}
#endif /* !BN_LLONG */
#endif /* !BN_ULLONG */
}
l0 = bn_mul_words(tmp->d, sdiv->d, div_n, q);
@@ -601,7 +601,7 @@ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) {
}
BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w) {
#ifndef BN_LLONG
#ifndef BN_ULLONG
BN_ULONG ret = 0;
#else
BN_ULLONG ret = 0;
@@ -614,7 +614,7 @@ BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w) {
w &= BN_MASK2;
for (i = a->top - 1; i >= 0; i--) {
#ifndef BN_LLONG
#ifndef BN_ULLONG
ret = ((ret << BN_BITS4) | ((a->d[i] >> BN_BITS4) & BN_MASK2l)) % w;
ret = ((ret << BN_BITS4) | (a->d[i] & BN_MASK2l)) % w;
#else
+1 -1
View File
@@ -279,7 +279,7 @@ BIGNUM *BN_mod_inverse_ex(BIGNUM *out, int *out_no_inverse, const BIGNUM *a,
* sign*Y*a == A (mod |n|).
*/
if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048))) {
if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS2 <= 32 ? 450 : 2048))) {
/* Binary inversion algorithm; requires odd modulus.
* This is faster than the general algorithm if the modulus
* is sufficiently small (about 400 .. 500 bits on 32-bit
+13 -19
View File
@@ -69,13 +69,7 @@
(!defined(OPENSSL_X86_64) && !defined(OPENSSL_X86)) || \
(defined(OPENSSL_X86_64) && defined(OPENSSL_WINDOWS))
#if defined(OPENSSL_WINDOWS)
#define alloca _alloca
#else
#include <alloca.h>
#endif
#ifdef BN_LLONG
#ifdef BN_ULLONG
#define mul_add(r, a, w, c) \
{ \
BN_ULLONG t; \
@@ -222,9 +216,9 @@
(c) = h & BN_MASK2; \
(r) = l & BN_MASK2; \
}
#endif /* !BN_LLONG */
#endif /* !BN_ULLONG */
#if defined(BN_LLONG) || defined(BN_UMULT_HIGH)
#if defined(BN_ULLONG) || defined(BN_UMULT_HIGH)
BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
BN_ULONG w) {
@@ -304,7 +298,7 @@ void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) {
}
}
#else /* !(defined(BN_LLONG) || defined(BN_UMULT_HIGH)) */
#else /* !(defined(BN_ULLONG) || defined(BN_UMULT_HIGH)) */
BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
BN_ULONG w) {
@@ -390,9 +384,9 @@ void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) {
}
}
#endif /* !(defined(BN_LLONG) || defined(BN_UMULT_HIGH)) */
#endif /* !(defined(BN_ULLONG) || defined(BN_UMULT_HIGH)) */
#if defined(BN_LLONG)
#if defined(BN_ULLONG)
BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) {
return (BN_ULONG)(((((BN_ULLONG)h) << BN_BITS2) | l) / (BN_ULLONG)d);
@@ -470,9 +464,9 @@ BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) {
return ret;
}
#endif /* !defined(BN_LLONG) */
#endif /* !defined(BN_ULLONG) */
#ifdef BN_LLONG
#ifdef BN_ULLONG
BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
int n) {
BN_ULLONG ll = 0;
@@ -512,7 +506,7 @@ BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
return (BN_ULONG)ll;
}
#else /* !BN_LLONG */
#else /* !BN_ULLONG */
BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
int n) {
@@ -569,7 +563,7 @@ BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
return (BN_ULONG)c;
}
#endif /* !BN_LLONG */
#endif /* !BN_ULLONG */
BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
int n) {
@@ -631,7 +625,7 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
/* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
/* 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
#ifdef BN_ULLONG
/* Keep in mind that additions to multiplication result can not overflow,
* because its high half cannot be all-ones. */
@@ -722,7 +716,7 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
#else /* !BN_LLONG */
#else /* !BN_ULLONG */
/* Keep in mind that additions to hi can not overflow, because
* the high word of a multiplication result cannot be all-ones. */
@@ -774,7 +768,7 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
} 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 */
#endif /* !BN_ULLONG */
void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
BN_ULONG c1, c2, c3;
+23 -20
View File
@@ -144,44 +144,41 @@ BIGNUM *bn_expand(BIGNUM *bn, size_t bits);
#if !defined(_MSC_VER)
/* MSVC doesn't support two-word integers on 64-bit. */
#define BN_LLONG __int128_t
#define BN_ULLONG __uint128_t
#endif
#define BN_BITS 128
#define BN_BITS2 64
#define BN_BYTES 8
#define BN_BITS4 32
#define BN_MASK (0xffffffffffffffffffffffffffffffffLL)
#define BN_MASK2 (0xffffffffffffffffL)
#define BN_MASK2l (0xffffffffL)
#define BN_MASK2h (0xffffffff00000000L)
#define BN_MASK2h1 (0xffffffff80000000L)
#define BN_TBIT (0x8000000000000000L)
#define BN_MASK2 (0xffffffffffffffffUL)
#define BN_MASK2l (0xffffffffUL)
#define BN_MASK2h (0xffffffff00000000UL)
#define BN_MASK2h1 (0xffffffff80000000UL)
#define BN_TBIT (0x8000000000000000UL)
#define BN_DEC_CONV (10000000000000000000UL)
#define BN_DEC_NUM 19
#define TOBN(hi, lo) ((BN_ULONG)hi << 32 | lo)
#elif defined(OPENSSL_32_BIT)
#define BN_LLONG int64_t
#define BN_ULLONG uint64_t
#define BN_MASK (0xffffffffffffffffLL)
#define BN_BITS 64
#define BN_BITS2 32
#define BN_BYTES 4
#define BN_BITS4 16
#define BN_MASK2 (0xffffffffL)
#define BN_MASK2l (0xffff)
#define BN_MASK2h1 (0xffff8000L)
#define BN_MASK2h (0xffff0000L)
#define BN_TBIT (0x80000000L)
#define BN_DEC_CONV (1000000000L)
#define BN_MASK2 (0xffffffffUL)
#define BN_MASK2l (0xffffUL)
#define BN_MASK2h1 (0xffff8000UL)
#define BN_MASK2h (0xffff0000UL)
#define BN_TBIT (0x80000000UL)
#define BN_DEC_CONV (1000000000UL)
#define BN_DEC_NUM 9
#define TOBN(hi, lo) lo, hi
#else
#error "Must define either OPENSSL_32_BIT or OPENSSL_64_BIT"
#endif
/* Pentium pro 16,16,16,32,64 */
/* Alpha 16,16,16,16.64 */
#define BN_MULL_SIZE_NORMAL (16) /* 32 */
@@ -190,7 +187,13 @@ BIGNUM *bn_expand(BIGNUM *bn, size_t bits);
#define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL (32) /* 32 */
#define BN_MONT_CTX_SET_SIZE_WORD (64) /* 32 */
#if defined(BN_LLONG)
#define STATIC_BIGNUM(x) \
{ \
(BN_ULONG *)x, sizeof(x) / sizeof(BN_ULONG), \
sizeof(x) / sizeof(BN_ULONG), 0, BN_FLG_STATIC_DATA \
}
#if defined(BN_ULLONG)
#define Lw(t) (((BN_ULONG)(t))&BN_MASK2)
#define Hw(t) (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2)
#endif
@@ -220,7 +223,7 @@ int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl);
int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
const BN_ULONG *np, const BN_ULONG *n0, int num);
#if !defined(BN_LLONG)
#if !defined(BN_ULLONG)
#define LBITS(a) ((a) & BN_MASK2l)
#define HBITS(a) (((a) >> BN_BITS4) & BN_MASK2l)
@@ -252,7 +255,7 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
(h) = ht; \
}
#endif /* !defined(BN_LLONG) */
#endif /* !defined(BN_ULLONG) */
#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64)
# if defined(__GNUC__) && __GNUC__ >= 2
+4 -9
View File
@@ -134,7 +134,6 @@ BN_MONT_CTX *BN_MONT_CTX_new(void) {
memset(ret, 0, sizeof(BN_MONT_CTX));
BN_init(&ret->RR);
BN_init(&ret->N);
BN_init(&ret->Ni);
return ret;
}
@@ -146,7 +145,6 @@ void BN_MONT_CTX_free(BN_MONT_CTX *mont) {
BN_free(&mont->RR);
BN_free(&mont->N);
BN_free(&mont->Ni);
OPENSSL_free(mont);
}
@@ -156,11 +154,9 @@ BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, const BN_MONT_CTX *from) {
}
if (!BN_copy(&to->RR, &from->RR) ||
!BN_copy(&to->N, &from->N) ||
!BN_copy(&to->Ni, &from->Ni)) {
!BN_copy(&to->N, &from->N)) {
return NULL;
}
to->ri = from->ri;
to->n0[0] = from->n0[0];
to->n0[1] = from->n0[1];
return to;
@@ -193,8 +189,6 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) {
tmod.dmax = 2;
tmod.neg = 0;
mont->ri = (BN_num_bits(mod) + (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2;
#if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2 <= 32)
/* Only certain BN_BITS2<=32 platforms actually make use of
* n0[1], and we could use the #else case (with a shorter R
@@ -278,9 +272,10 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) {
mont->n0[1] = 0;
#endif
/* setup RR for conversions */
/* RR = (2^ri)^2 == 2^(ri*2) == 1 << (ri*2), which has its (ri*2)th bit set. */
int ri = (BN_num_bits(mod) + (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2;
BN_zero(&(mont->RR));
if (!BN_set_bit(&(mont->RR), mont->ri * 2)) {
if (!BN_set_bit(&(mont->RR), ri * 2)) {
goto err;
}
if (!BN_mod(&(mont->RR), &(mont->RR), &(mont->N), ctx)) {
+12 -7
View File
@@ -12,6 +12,10 @@
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#if !defined(__STDC_CONSTANT_MACROS)
#define __STDC_CONSTANT_MACROS
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -22,7 +26,6 @@
#include <openssl/bytestring.h>
#include "internal.h"
#include "../internal.h"
#include "../test/scoped_types.h"
@@ -341,12 +344,14 @@ static bool TestCBBPrefixed() {
size_t buf_len;
CBB cbb, contents, inner_contents, inner_inner_contents;
if (!CBB_init(&cbb, 0)) {
return false;
}
if (!CBB_add_u8_length_prefixed(&cbb, &contents) ||
if (!CBB_init(&cbb, 0) ||
CBB_len(&cbb) != 0 ||
!CBB_add_u8_length_prefixed(&cbb, &contents) ||
!CBB_add_u8_length_prefixed(&cbb, &contents) ||
!CBB_add_u8(&contents, 1) ||
CBB_len(&contents) != 1 ||
!CBB_flush(&cbb) ||
CBB_len(&cbb) != 3 ||
!CBB_add_u16_length_prefixed(&cbb, &contents) ||
!CBB_add_u16(&contents, 0x203) ||
!CBB_add_u24_length_prefixed(&cbb, &contents) ||
@@ -627,9 +632,9 @@ static const ASN1Uint64Test kASN1Uint64Tests[] = {
{127, "\x02\x01\x7f", 3},
{128, "\x02\x02\x00\x80", 4},
{0xdeadbeef, "\x02\x05\x00\xde\xad\xbe\xef", 7},
{OPENSSL_U64(0x0102030405060708),
{UINT64_C(0x0102030405060708),
"\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08", 10},
{OPENSSL_U64(0xffffffffffffffff),
{UINT64_C(0xffffffffffffffff),
"\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff", 11},
};
+26 -26
View File
@@ -25,6 +25,7 @@ void CBB_zero(CBB *cbb) {
}
static int cbb_init(CBB *cbb, uint8_t *buf, size_t cap) {
/* This assumes that |cbb| has already been zeroed. */
struct cbb_buffer_st *base;
base = OPENSSL_malloc(sizeof(struct cbb_buffer_st));
@@ -37,16 +38,15 @@ static int cbb_init(CBB *cbb, uint8_t *buf, size_t cap) {
base->cap = cap;
base->can_resize = 1;
memset(cbb, 0, sizeof(CBB));
cbb->base = base;
cbb->is_top_level = 1;
return 1;
}
int CBB_init(CBB *cbb, size_t initial_capacity) {
uint8_t *buf;
CBB_zero(cbb);
buf = OPENSSL_malloc(initial_capacity);
uint8_t *buf = OPENSSL_malloc(initial_capacity);
if (initial_capacity > 0 && buf == NULL) {
return 0;
}
@@ -60,6 +60,8 @@ int CBB_init(CBB *cbb, size_t initial_capacity) {
}
int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len) {
CBB_zero(cbb);
if (!cbb_init(cbb, buf, len)) {
return 0;
}
@@ -177,28 +179,28 @@ int CBB_flush(CBB *cbb) {
return 0;
}
if (cbb->child == NULL || cbb->pending_len_len == 0) {
if (cbb->child == NULL || cbb->child->pending_len_len == 0) {
return 1;
}
child_start = cbb->offset + cbb->pending_len_len;
child_start = cbb->child->offset + cbb->child->pending_len_len;
if (!CBB_flush(cbb->child) ||
child_start < cbb->offset ||
child_start < cbb->child->offset ||
cbb->base->len < child_start) {
return 0;
}
len = cbb->base->len - child_start;
if (cbb->pending_is_asn1) {
if (cbb->child->pending_is_asn1) {
/* For ASN.1 we assume that we'll only need a single byte for the length.
* If that turned out to be incorrect, we have to move the contents along
* in order to make space. */
size_t len_len;
uint8_t initial_length_byte;
assert (cbb->pending_len_len == 1);
assert (cbb->child->pending_len_len == 1);
if (len > 0xfffffffe) {
/* Too large. */
@@ -230,12 +232,13 @@ int CBB_flush(CBB *cbb) {
memmove(cbb->base->buf + child_start + extra_bytes,
cbb->base->buf + child_start, len);
}
cbb->base->buf[cbb->offset++] = initial_length_byte;
cbb->pending_len_len = len_len - 1;
cbb->base->buf[cbb->child->offset++] = initial_length_byte;
cbb->child->pending_len_len = len_len - 1;
}
for (i = cbb->pending_len_len - 1; i < cbb->pending_len_len; i--) {
cbb->base->buf[cbb->offset + i] = len;
for (i = cbb->child->pending_len_len - 1; i < cbb->child->pending_len_len;
i--) {
cbb->base->buf[cbb->child->offset + i] = len;
len >>= 8;
}
if (len != 0) {
@@ -244,17 +247,15 @@ int CBB_flush(CBB *cbb) {
cbb->child->base = NULL;
cbb->child = NULL;
cbb->pending_len_len = 0;
cbb->pending_is_asn1 = 0;
cbb->offset = 0;
return 1;
}
size_t CBB_len(const CBB *cbb) {
assert(cbb->child == NULL);
assert(cbb->offset + cbb->pending_len_len <= cbb->base->len);
return cbb->base->len;
return cbb->base->len - cbb->offset - cbb->pending_len_len;
}
static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents,
@@ -265,7 +266,7 @@ static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents,
return 0;
}
cbb->offset = cbb->base->len;
size_t offset = cbb->base->len;
if (!cbb_buffer_add(cbb->base, &prefix_bytes, len_len)) {
return 0;
}
@@ -274,8 +275,9 @@ static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents,
memset(out_contents, 0, sizeof(CBB));
out_contents->base = cbb->base;
cbb->child = out_contents;
cbb->pending_len_len = len_len;
cbb->pending_is_asn1 = 0;
cbb->child->offset = offset;
cbb->child->pending_len_len = len_len;
cbb->child->pending_is_asn1 = 0;
return 1;
}
@@ -303,7 +305,7 @@ int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag) {
return 0;
}
cbb->offset = cbb->base->len;
size_t offset = cbb->base->len;
if (!CBB_add_u8(cbb, 0)) {
return 0;
}
@@ -311,8 +313,9 @@ int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag) {
memset(out_contents, 0, sizeof(CBB));
out_contents->base = cbb->base;
cbb->child = out_contents;
cbb->pending_len_len = 1;
cbb->pending_is_asn1 = 1;
cbb->child->offset = offset;
cbb->child->pending_len_len = 1;
cbb->child->pending_is_asn1 = 1;
return 1;
}
@@ -365,13 +368,10 @@ void CBB_discard_child(CBB *cbb) {
return;
}
cbb->base->len = cbb->offset;
cbb->base->len = cbb->child->offset;
cbb->child->base = NULL;
cbb->child = NULL;
cbb->pending_len_len = 0;
cbb->pending_is_asn1 = 0;
cbb->offset = 0;
}
int CBB_add_asn1_uint64(CBB *cbb, uint64_t value) {
+1 -1
View File
@@ -200,7 +200,7 @@ struct AEADName {
static const struct AEADName kAEADs[] = {
{ "aes-128-gcm", EVP_aead_aes_128_gcm },
{ "aes-256-gcm", EVP_aead_aes_256_gcm },
{ "chacha20-poly1305", EVP_aead_chacha20_poly1305_rfc7539 },
{ "chacha20-poly1305", EVP_aead_chacha20_poly1305 },
{ "chacha20-poly1305-old", EVP_aead_chacha20_poly1305_old },
{ "rc4-md5-tls", EVP_aead_rc4_md5_tls },
{ "rc4-sha1-tls", EVP_aead_rc4_sha1_tls },
+1 -1
View File
@@ -1652,7 +1652,7 @@ static int aead_aes_ctr_hmac_sha256_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
if (in_len + aes_ctx->tag_len < in_len ||
/* This input is so large it would overflow the 32-bit block counter. */
in_len_64 >= (OPENSSL_U64(1) << 32) * AES_BLOCK_SIZE) {
in_len_64 >= (UINT64_C(1) << 32) * AES_BLOCK_SIZE) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
+23 -21
View File
@@ -108,10 +108,11 @@ static void aead_poly1305(aead_poly1305_update update,
CRYPTO_poly1305_finish(&ctx, tag);
}
static int seal(aead_poly1305_update poly1305_update, const EVP_AEAD_CTX *ctx,
uint8_t *out, size_t *out_len, size_t max_out_len,
const uint8_t nonce[12], const uint8_t *in, size_t in_len,
const uint8_t *ad, size_t ad_len) {
static int seal_impl(aead_poly1305_update poly1305_update,
const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
size_t max_out_len, const uint8_t nonce[12],
const uint8_t *in, size_t in_len, const uint8_t *ad,
size_t ad_len) {
const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
const uint64_t in_len_64 = in_len;
@@ -146,10 +147,11 @@ static int seal(aead_poly1305_update poly1305_update, const EVP_AEAD_CTX *ctx,
return 1;
}
static int open(aead_poly1305_update poly1305_update, const EVP_AEAD_CTX *ctx,
uint8_t *out, size_t *out_len, size_t max_out_len,
const uint8_t nonce[12], const uint8_t *in, size_t in_len,
const uint8_t *ad, size_t ad_len) {
static int open_impl(aead_poly1305_update poly1305_update,
const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
size_t max_out_len, const uint8_t nonce[12],
const uint8_t *in, size_t in_len, const uint8_t *ad,
size_t ad_len) {
const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
size_t plaintext_len;
const uint64_t in_len_64 = in_len;
@@ -212,8 +214,8 @@ static int aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
return 0;
}
return seal(poly1305_update, ctx, out, out_len, max_out_len, nonce, in,
in_len, ad, ad_len);
return seal_impl(poly1305_update, ctx, out, out_len, max_out_len, nonce, in,
in_len, ad, ad_len);
}
static int aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
@@ -225,8 +227,8 @@ static int aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
return 0;
}
return open(poly1305_update, ctx, out, out_len, max_out_len, nonce, in,
in_len, ad, ad_len);
return open_impl(poly1305_update, ctx, out, out_len, max_out_len, nonce, in,
in_len, ad, ad_len);
}
static const EVP_AEAD aead_chacha20_poly1305 = {
@@ -243,10 +245,14 @@ static const EVP_AEAD aead_chacha20_poly1305 = {
NULL, /* get_iv */
};
const EVP_AEAD *EVP_aead_chacha20_poly1305_rfc7539(void) {
const EVP_AEAD *EVP_aead_chacha20_poly1305(void) {
return &aead_chacha20_poly1305;
}
const EVP_AEAD *EVP_aead_chacha20_poly1305_rfc7539(void) {
return EVP_aead_chacha20_poly1305();
}
static void poly1305_update_old(poly1305_state *ctx, const uint8_t *ad,
size_t ad_len, const uint8_t *ciphertext,
size_t ciphertext_len) {
@@ -267,8 +273,8 @@ static int aead_chacha20_poly1305_old_seal(
uint8_t nonce_96[12];
memset(nonce_96, 0, 4);
memcpy(nonce_96 + 4, nonce, 8);
return seal(poly1305_update_old, ctx, out, out_len, max_out_len, nonce_96, in,
in_len, ad, ad_len);
return seal_impl(poly1305_update_old, ctx, out, out_len, max_out_len,
nonce_96, in, in_len, ad, ad_len);
}
static int aead_chacha20_poly1305_old_open(
@@ -282,8 +288,8 @@ static int aead_chacha20_poly1305_old_open(
uint8_t nonce_96[12];
memset(nonce_96, 0, 4);
memcpy(nonce_96 + 4, nonce, 8);
return open(poly1305_update_old, ctx, out, out_len, max_out_len, nonce_96, in,
in_len, ad, ad_len);
return open_impl(poly1305_update_old, ctx, out, out_len, max_out_len,
nonce_96, in, in_len, ad, ad_len);
}
static const EVP_AEAD aead_chacha20_poly1305_old = {
@@ -303,7 +309,3 @@ static const EVP_AEAD aead_chacha20_poly1305_old = {
const EVP_AEAD *EVP_aead_chacha20_poly1305_old(void) {
return &aead_chacha20_poly1305_old;
}
const EVP_AEAD *EVP_aead_chacha20_poly1305(void) {
return &aead_chacha20_poly1305_old;
}
-311
View File
@@ -54,21 +54,13 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
#include <openssl/aead.h>
#include <assert.h>
#include <string.h>
#include <openssl/cipher.h>
#include <openssl/cpu.h>
#include <openssl/err.h>
#include <openssl/md5.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/rc4.h>
#include "internal.h"
static int rc4_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
const uint8_t *iv, int enc) {
@@ -93,306 +85,3 @@ static const EVP_CIPHER rc4 = {
NULL /* cleanup */, NULL /* ctrl */, };
const EVP_CIPHER *EVP_rc4(void) { return &rc4; }
struct aead_rc4_md5_tls_ctx {
RC4_KEY rc4;
MD5_CTX head, tail, md;
size_t payload_length;
unsigned char tag_len;
};
static int
aead_rc4_md5_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len,
size_t tag_len) {
struct aead_rc4_md5_tls_ctx *rc4_ctx;
size_t i;
uint8_t hmac_key[MD5_CBLOCK];
if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) {
tag_len = MD5_DIGEST_LENGTH;
}
if (tag_len > MD5_DIGEST_LENGTH) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
/* The keys consists of |MD5_DIGEST_LENGTH| bytes of HMAC(MD5) key followed
* by some number of bytes of RC4 key. */
if (key_len <= MD5_DIGEST_LENGTH) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
return 0;
}
rc4_ctx = OPENSSL_malloc(sizeof(struct aead_rc4_md5_tls_ctx));
if (rc4_ctx == NULL) {
OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
return 0;
}
memset(rc4_ctx, 0, sizeof(struct aead_rc4_md5_tls_ctx));
RC4_set_key(&rc4_ctx->rc4, key_len - MD5_DIGEST_LENGTH,
key + MD5_DIGEST_LENGTH);
memset(hmac_key, 0, sizeof(hmac_key));
memcpy(hmac_key, key, MD5_DIGEST_LENGTH);
for (i = 0; i < sizeof(hmac_key); i++) {
hmac_key[i] ^= 0x36;
}
MD5_Init(&rc4_ctx->head);
MD5_Update(&rc4_ctx->head, hmac_key, sizeof(hmac_key));
for (i = 0; i < sizeof(hmac_key); i++) {
hmac_key[i] ^= 0x36 ^ 0x5c;
}
MD5_Init(&rc4_ctx->tail);
MD5_Update(&rc4_ctx->tail, hmac_key, sizeof(hmac_key));
rc4_ctx->tag_len = tag_len;
ctx->aead_state = rc4_ctx;
return 1;
}
static void aead_rc4_md5_tls_cleanup(EVP_AEAD_CTX *ctx) {
struct aead_rc4_md5_tls_ctx *rc4_ctx = ctx->aead_state;
OPENSSL_cleanse(rc4_ctx, sizeof(struct aead_rc4_md5_tls_ctx));
OPENSSL_free(rc4_ctx);
}
#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64)
#define STITCHED_CALL
/* rc4_md5_enc is defined in rc4_md5-x86_64.pl */
void rc4_md5_enc(RC4_KEY *key, const void *in0, void *out, MD5_CTX *ctx,
const void *inp, size_t blocks);
#endif
static int aead_rc4_md5_tls_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
size_t *out_len, size_t max_out_len,
const uint8_t *nonce, size_t nonce_len,
const uint8_t *in, size_t in_len,
const uint8_t *ad, size_t ad_len) {
struct aead_rc4_md5_tls_ctx *rc4_ctx = ctx->aead_state;
MD5_CTX md;
#if defined(STITCHED_CALL)
size_t rc4_off, md5_off, blocks;
#else
const size_t rc4_off = 0;
const size_t md5_off = 0;
#endif
uint8_t digest[MD5_DIGEST_LENGTH];
if (in_len + rc4_ctx->tag_len < in_len) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
if (nonce_len != 0) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_IV_TOO_LARGE);
return 0;
}
if (max_out_len < in_len + rc4_ctx->tag_len) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
if (nonce_len != 0) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
memcpy(&md, &rc4_ctx->head, sizeof(MD5_CTX));
/* The MAC's payload begins with the additional data. See
* https://tools.ietf.org/html/rfc5246#section-6.2.3.1 */
MD5_Update(&md, ad, ad_len);
/* To allow for CBC mode which changes cipher length, |ad| doesn't include the
* length for legacy ciphers. */
uint8_t ad_extra[2];
ad_extra[0] = (uint8_t)(in_len >> 8);
ad_extra[1] = (uint8_t)(in_len & 0xff);
MD5_Update(&md, ad_extra, sizeof(ad_extra));
#if defined(STITCHED_CALL)
/* 32 is $MOD from rc4_md5-x86_64.pl. */
rc4_off = 32 - 1 - (rc4_ctx->rc4.x & (32 - 1));
md5_off = MD5_CBLOCK - md.num;
/* Ensure RC4 is behind MD5. */
if (rc4_off > md5_off) {
md5_off += MD5_CBLOCK;
}
assert(md5_off >= rc4_off);
if (in_len > md5_off && (blocks = (in_len - md5_off) / MD5_CBLOCK) &&
(OPENSSL_ia32cap_P[0] & (1 << 20)) == 0) {
/* Process the initial portions of the plaintext normally. */
MD5_Update(&md, in, md5_off);
RC4(&rc4_ctx->rc4, rc4_off, in, out);
/* Process the next |blocks| blocks of plaintext with stitched routines. */
rc4_md5_enc(&rc4_ctx->rc4, in + rc4_off, out + rc4_off, &md, in + md5_off,
blocks);
blocks *= MD5_CBLOCK;
rc4_off += blocks;
md5_off += blocks;
md.Nh += blocks >> 29;
md.Nl += blocks <<= 3;
if (md.Nl < (unsigned int)blocks) {
md.Nh++;
}
} else {
rc4_off = 0;
md5_off = 0;
}
#endif
/* Finish computing the MAC. */
MD5_Update(&md, in + md5_off, in_len - md5_off);
MD5_Final(digest, &md);
memcpy(&md, &rc4_ctx->tail, sizeof(MD5_CTX));
MD5_Update(&md, digest, sizeof(digest));
if (rc4_ctx->tag_len == MD5_DIGEST_LENGTH) {
MD5_Final(out + in_len, &md);
} else {
MD5_Final(digest, &md);
memcpy(out + in_len, digest, rc4_ctx->tag_len);
}
/* Encrypt the remainder of the plaintext and the MAC. */
RC4(&rc4_ctx->rc4, in_len - rc4_off, in + rc4_off, out + rc4_off);
RC4(&rc4_ctx->rc4, MD5_DIGEST_LENGTH, out + in_len, out + in_len);
*out_len = in_len + rc4_ctx->tag_len;
return 1;
}
static int aead_rc4_md5_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
size_t *out_len, size_t max_out_len,
const uint8_t *nonce, size_t nonce_len,
const uint8_t *in, size_t in_len,
const uint8_t *ad, size_t ad_len) {
struct aead_rc4_md5_tls_ctx *rc4_ctx = ctx->aead_state;
MD5_CTX md;
size_t plaintext_len;
#if defined(STITCHED_CALL)
unsigned int l;
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;
#endif
uint8_t digest[MD5_DIGEST_LENGTH];
if (in_len < rc4_ctx->tag_len) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
plaintext_len = in_len - rc4_ctx->tag_len;
if (nonce_len != 0) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
if (max_out_len < in_len) {
/* This requires that the caller provide space for the MAC, even though it
* will always be removed on return. */
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
memcpy(&md, &rc4_ctx->head, sizeof(MD5_CTX));
/* The MAC's payload begins with the additional data. See
* https://tools.ietf.org/html/rfc5246#section-6.2.3.1 */
MD5_Update(&md, ad, ad_len);
/* To allow for CBC mode which changes cipher length, |ad| doesn't include the
* length for legacy ciphers. */
uint8_t ad_extra[2];
ad_extra[0] = (uint8_t)(plaintext_len >> 8);
ad_extra[1] = (uint8_t)(plaintext_len & 0xff);
MD5_Update(&md, ad_extra, sizeof(ad_extra));
#if defined(STITCHED_CALL)
rc4_off = 32 - 1 - (rc4_ctx->rc4.x & (32 - 1));
md5_off = MD5_CBLOCK - md.num;
/* Ensure MD5 is a full block behind RC4 so it has plaintext to operate on in
* both normal and stitched routines. */
if (md5_off > rc4_off) {
rc4_off += 2 * MD5_CBLOCK;
} else {
rc4_off += MD5_CBLOCK;
}
if (in_len > rc4_off && (blocks = (in_len - rc4_off) / MD5_CBLOCK) &&
(OPENSSL_ia32cap_P[0] & (1 << 20)) == 0) {
/* Decrypt the initial portion of the ciphertext and digest the plaintext
* normally. */
RC4(&rc4_ctx->rc4, rc4_off, in, out);
MD5_Update(&md, out, md5_off);
/* Decrypt and digest the next |blocks| blocks of ciphertext with the
* stitched routines. */
rc4_md5_enc(&rc4_ctx->rc4, in + rc4_off, out + rc4_off, &md, out + md5_off,
blocks);
blocks *= MD5_CBLOCK;
rc4_off += blocks;
md5_off += blocks;
l = (md.Nl + (blocks << 3)) & 0xffffffffU;
if (l < md.Nl) {
md.Nh++;
}
md.Nl = l;
md.Nh += blocks >> 29;
} else {
md5_off = 0;
rc4_off = 0;
}
#endif
/* Process the remainder of the input. */
RC4(&rc4_ctx->rc4, in_len - rc4_off, in + rc4_off, out + rc4_off);
MD5_Update(&md, out + md5_off, plaintext_len - md5_off);
MD5_Final(digest, &md);
/* Calculate HMAC and verify it */
memcpy(&md, &rc4_ctx->tail, sizeof(MD5_CTX));
MD5_Update(&md, digest, MD5_DIGEST_LENGTH);
MD5_Final(digest, &md);
if (CRYPTO_memcmp(out + plaintext_len, digest, rc4_ctx->tag_len)) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
*out_len = plaintext_len;
return 1;
}
static int aead_rc4_md5_tls_get_rc4_state(const EVP_AEAD_CTX *ctx,
const RC4_KEY **out_key) {
struct aead_rc4_md5_tls_ctx *rc4_ctx = ctx->aead_state;
*out_key = &rc4_ctx->rc4;
return 1;
}
static const EVP_AEAD aead_rc4_md5_tls = {
16 + MD5_DIGEST_LENGTH, /* key len (RC4 + MD5) */
0, /* nonce len */
MD5_DIGEST_LENGTH, /* overhead */
MD5_DIGEST_LENGTH, /* max tag length */
aead_rc4_md5_tls_init,
NULL, /* init_with_direction */
aead_rc4_md5_tls_cleanup,
aead_rc4_md5_tls_seal,
aead_rc4_md5_tls_open,
aead_rc4_md5_tls_get_rc4_state,
NULL, /* get_iv */
};
const EVP_AEAD *EVP_aead_rc4_md5_tls(void) { return &aead_rc4_md5_tls; }
+38 -24
View File
@@ -20,6 +20,7 @@
#include <openssl/cipher.h>
#include <openssl/err.h>
#include <openssl/hmac.h>
#include <openssl/md5.h>
#include <openssl/mem.h>
#include <openssl/sha.h>
#include <openssl/type_check.h>
@@ -111,7 +112,6 @@ static int aead_tls_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
/* Unlike a normal AEAD, a TLS AEAD may only be used in one direction. */
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION);
return 0;
}
if (in_len + EVP_AEAD_max_overhead(ctx->aead) < in_len ||
@@ -146,17 +146,13 @@ static int aead_tls_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
* in-place. */
uint8_t mac[EVP_MAX_MD_SIZE];
unsigned mac_len;
HMAC_CTX hmac_ctx;
HMAC_CTX_init(&hmac_ctx);
if (!HMAC_CTX_copy_ex(&hmac_ctx, &tls_ctx->hmac_ctx) ||
!HMAC_Update(&hmac_ctx, ad, ad_len) ||
!HMAC_Update(&hmac_ctx, ad_extra, sizeof(ad_extra)) ||
!HMAC_Update(&hmac_ctx, in, in_len) ||
!HMAC_Final(&hmac_ctx, mac, &mac_len)) {
HMAC_CTX_cleanup(&hmac_ctx);
if (!HMAC_Init_ex(&tls_ctx->hmac_ctx, NULL, 0, NULL, NULL) ||
!HMAC_Update(&tls_ctx->hmac_ctx, ad, ad_len) ||
!HMAC_Update(&tls_ctx->hmac_ctx, ad_extra, sizeof(ad_extra)) ||
!HMAC_Update(&tls_ctx->hmac_ctx, in, in_len) ||
!HMAC_Final(&tls_ctx->hmac_ctx, mac, &mac_len)) {
return 0;
}
HMAC_CTX_cleanup(&hmac_ctx);
/* Configure the explicit IV. */
if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE &&
@@ -216,7 +212,6 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
/* Unlike a normal AEAD, a TLS AEAD may only be used in one direction. */
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION);
return 0;
}
if (in_len < HMAC_size(&tls_ctx->hmac_ctx)) {
@@ -324,18 +319,14 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
* implemented. */
assert(EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) != EVP_CIPH_CBC_MODE);
HMAC_CTX hmac_ctx;
HMAC_CTX_init(&hmac_ctx);
unsigned mac_len_u;
if (!HMAC_CTX_copy_ex(&hmac_ctx, &tls_ctx->hmac_ctx) ||
!HMAC_Update(&hmac_ctx, ad_fixed, ad_len) ||
!HMAC_Update(&hmac_ctx, out, data_len) ||
!HMAC_Final(&hmac_ctx, mac, &mac_len_u)) {
HMAC_CTX_cleanup(&hmac_ctx);
if (!HMAC_Init_ex(&tls_ctx->hmac_ctx, NULL, 0, NULL, NULL) ||
!HMAC_Update(&tls_ctx->hmac_ctx, ad_fixed, ad_len) ||
!HMAC_Update(&tls_ctx->hmac_ctx, out, data_len) ||
!HMAC_Final(&tls_ctx->hmac_ctx, mac, &mac_len_u)) {
return 0;
}
mac_len = mac_len_u;
HMAC_CTX_cleanup(&hmac_ctx);
assert(mac_len == HMAC_size(&tls_ctx->hmac_ctx));
record_mac = &out[data_len];
@@ -359,6 +350,13 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
return 1;
}
static int aead_rc4_md5_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
size_t key_len, size_t tag_len,
enum evp_aead_direction_t dir) {
return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_rc4(), EVP_md5(),
0);
}
static int aead_rc4_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
size_t key_len, size_t tag_len,
enum evp_aead_direction_t dir) {
@@ -433,8 +431,8 @@ static int aead_des_ede3_cbc_sha1_tls_implicit_iv_init(
EVP_sha1(), 1);
}
static int aead_rc4_sha1_tls_get_rc4_state(const EVP_AEAD_CTX *ctx,
const RC4_KEY **out_key) {
static int aead_rc4_tls_get_rc4_state(const EVP_AEAD_CTX *ctx,
const RC4_KEY **out_key) {
const AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX*) ctx->aead_state;
if (EVP_CIPHER_CTX_cipher(&tls_ctx->cipher_ctx) != EVP_rc4()) {
return 0;
@@ -464,18 +462,32 @@ static int aead_null_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
EVP_sha1(), 1 /* implicit iv */);
}
static const EVP_AEAD aead_rc4_md5_tls = {
MD5_DIGEST_LENGTH + 16, /* key len (MD5 + RC4) */
0, /* nonce len */
MD5_DIGEST_LENGTH, /* overhead */
MD5_DIGEST_LENGTH, /* max tag length */
NULL, /* init */
aead_rc4_md5_tls_init,
aead_tls_cleanup,
aead_tls_seal,
aead_tls_open,
aead_rc4_tls_get_rc4_state, /* get_rc4_state */
NULL, /* get_iv */
};
static const EVP_AEAD aead_rc4_sha1_tls = {
SHA_DIGEST_LENGTH + 16, /* key len (SHA1 + RC4) */
0, /* nonce len */
SHA_DIGEST_LENGTH, /* overhead */
SHA_DIGEST_LENGTH, /* max tag length */
NULL, /* init */
NULL, /* init */
aead_rc4_sha1_tls_init,
aead_tls_cleanup,
aead_tls_seal,
aead_tls_open,
aead_rc4_sha1_tls_get_rc4_state, /* get_rc4_state */
NULL, /* get_iv */
aead_rc4_tls_get_rc4_state, /* get_rc4_state */
NULL, /* get_iv */
};
static const EVP_AEAD aead_aes_128_cbc_sha1_tls = {
@@ -618,6 +630,8 @@ static const EVP_AEAD aead_null_sha1_tls = {
NULL, /* get_iv */
};
const EVP_AEAD *EVP_aead_rc4_md5_tls(void) { return &aead_rc4_md5_tls; }
const EVP_AEAD *EVP_aead_rc4_sha1_tls(void) { return &aead_rc4_sha1_tls; }
const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls(void) {
@@ -418,5 +418,107 @@ AD: fd6a3fdd879f8880843eac20ae01c1b9dc3487d270a806572088ef2ddc1f1e0de495e71d4813
CT: bd11ed07b7b4b30eeaf25d6a41a549cca0a5aee71f990ac566a37265d7af2ce3c03703427ee0b2755c2bdfc29f9d826aec6ee4ad28af48079ac23db16580b97424f3a4e35cc23625d39f95699d9ff5143e9a2bc26fcfee4f125f5aa2d968ccfc2faaf9db3c28850f6757f735cbc50c94c498bcde4f23bffafa8dd5f70d1a011e35eb26e905d4e68848fedebeb197be595c085ba33f11ba8398258445051751888e9bba111f800f31b37c447074ca6dce6d54b4dfad6cee5138643d4f6ac045e8047248924e88ea4294c7878bc22c9b41924ce301f22693c33733107bf1ba85e34806c5e4366ea66fc52a5f89dd9bf213239158b3d4d2600dde696c61d76c398b9bf10de9118e812e891c8f3355c0ecc6405f79bc32a58905e37888a1d8395fbedc3ac54eca569f
TAG: f7d3b58a34a86e99267e5db206f17bbe
# BoringSSL has additional tests here for truncated tags. *ring* doesn't
# support tag truncation, so those tests were removed.
KEY: 3304e4917ad7777b86c26a636292c9cc4c10d32003c49e07209eb0ef8505031a
NONCE: 4d572d116fbd8c4d
IN: 2f242c2ba33790ecef862b0e077ff8b15eb9d10cf2ff621ed65902494431dcbd
AD: e699bbf250cdd93d229d0740e433897e2d19132e2b722df8b69bb6a7c2cf3b93
CT: fb81e30436e437c7f686f86b1b65c73549a9d09db810d320785c3634934150b3
TAG: 8b
KEY: ed6057bb163f1609ff28b938122f495e3d5ae4ec3dbd7456c9b5c82e28e952dc
NONCE: e6ff6852f3a3afde
IN: 3c50edc967eb0b3b2355f6400e0a036e796c8b7d72c5e583a86e820d53e76c43
AD: 2441db55148e14e9e241d68296eb60d529408f0534143089671bce546db96d88
CT: 6ecabccee31519374d4bed11296e7483d1cb759bea3f4446a96bda8b4ca6d7ac
TAG: 355f
KEY: 73568183c1f9725af30e0f2067606ce802c3fe3ab5cff8d02b3db8c35176ee0d
NONCE: 0bc9e19321b3d00a
IN: ec2590af5ccd226a32ff750c1b029c11e3dd76c469a5579da9418e4c3fdc0d41
AD: df30160ae0cbf2cf8992221bd62dffe691dd602afa784ca691479e957af3acf1
CT: 9e8d8ac30626f8b831448d6976933aa5bb8c6dbc794e1f4b7eeb0e4a59342c07
TAG: 9fd36a
KEY: 273bcb3f8c067da4ec3418799ad40e7e4aee74ad7e629499d646df4a7e585025
NONCE: f60be3eb894b4030
IN: 697498ba964d5ef401da4d94844fab1efc635e7157d0831a325bb5a4cf1fbd34
AD: 9129715deab14f02c76ba8172571b1fa9d50365cd795bfccdfc28e7e7b4f66fc
CT: bd4cd5af83be1c13933302675d9fcaf1c4cacdf269f6ff441d1ea2211c54e7ed
TAG: 7ab12a37
KEY: ad39610c2e6a6d0961207390e076e972c2edadca885c92965fa648b2ce34fdbf
NONCE: a90db690bba83b78
IN: 31c49e3cd3d80a82e6b90316dfb94b38b8a23042519bf40c8181fec873c99002
AD: ddbd7d821d18d44c66295abf245b227b5cf4366811b7b34c07679600abdbfc29
CT: 94628fc303a0546edd51e966f2bd87968f37800c607d5e5a91f727fc1fec406f
TAG: c22ec4e4c8
KEY: 29984954060ba06ece1bcfc0e50195f4632c6df48da1e02ae6c14f7065668971
NONCE: cce53a25aeeaf747
IN: b9b87433a9894f3c9ca8212623d62369a565a2edcddd276e07d611eda3597426
AD: 19fa9aa59697559d8b46d9cd49c3b763c0b73b26b9e334a3eeac2c86fdbaca8d
CT: b68c83397770c36f073710882fa86d43b0e54e8efef0ff75075604d0d7ec4e1b
TAG: 40d4ab752f3d
KEY: 5c3b838b84100b2a818c0842e9fe19a7c50cf5f3ea73364c816ef588e500ff3f
NONCE: fdf6b0229e4bcc2a
IN: 2ba91904c143be99297b39f52856904af41705c176c8c6554b6bc89bddffbcc1
AD: 3539d9dd821f004f4ced1637071f4be6abd7fe98f017f0a8ce3f49dc8d496f46
CT: ff9d6d924e737a1df8c2bd3047e40ab401f903aa0e5b51acb991bac38ac2cc4d
TAG: 1bcaa415a6a3c7
KEY: 6d65e627cab6d5eb1a088b25bd6c3a8a004a7a19cccae909d62fed3559c812f7
NONCE: 7ff00a8798b792de
IN: 6848ee4ac820291a2e1dc3baad97f1ad8b7160dfeaa1bc83b2700ae42b5a366b
AD: d2437b1306bf0ea211449fac863ca0d1074d84caee9009c5d54b9e9bdc8de6b1
CT: 2da0abe2a71e1c0b1ab309c160a8cebe45c6e16170aa5561806484ba2b5b9a9a
TAG: 566003e1f78d2a90
KEY: 63401046a96efbc8c6483a2c396b2a593d3fae0db565525b85999fae13a46b6a
NONCE: 051393d775e635ee
IN: 2b4b6477580382aae782f8b5772c0948a444d8d95caacd85c0856c7e4393fe09
AD: 3d84d2e70e9c062d1f511eb685a9a90c8d5fa50eadf8455c7148666b3e7155e0
CT: 880c1123e54fd8ffb3c293720dd174913572e619ef46504cdaa64fc451b0ec1c
TAG: 339274339c88d50ac0
KEY: 291fccfce0782f1787d62d4b9293d2ada4c04d37a8288ba9ba9aae0d31aad204
NONCE: 7450bbd62e4aba7b
IN: adc251e793181e5d4c4bd983b853eb13f2096ccb340996b6eca4cd2157efcec7
AD: 4c598f6deedc8c1d97da33654763495cca3517430eec4edb006b10c95e031ae6
CT: 28bda22e4922cd8ff6739cd8a6bdafce036d9c61a145a65ca1b86f6d4d3206a1
TAG: d98fd43fe7ac74d4b016
KEY: fa3a9674d4a0eb36b2f7547c956443d09e6b4e4acfc9deda838eb7ebdb999a8d
NONCE: 0a2572592c3bbbf6
IN: ae27f70fda9f5a5be0f704a27f0b8a9c04ce83d3c2e0d7ec152da25f473b0c8a
AD: 6ee8705a9a3655d198497ad410da02005872ecbe397824851b80f4050bfdd311
CT: f356cbd88e4e2aff62d91e3f914032085388955bbba995fde013758b8702e38f
TAG: 00324c76fecd3f50e1e3b8
KEY: 471ec87b992b104d369748d96856b5f66149cb45ca05c17f29d24eb9526fe6db
NONCE: 23a2df9ed0b47439
IN: 2b9452bca0f48e5519ec3d0736597608df6ad9ce799eba913cff71573d79c092
AD: a56722ddfaee5f1b64398c225ee8bcdcfde5c2127101c363bfac52bc409c1082
CT: 7bbc464aac5dd29c25262fe0b116c176d827c2cc8dd63428393b0a9110f3c194
TAG: 2e87f4a6663a62e47c7e197f
KEY: a29d1cfd4ccdc18803fbca9500f4bb29ce99cfcbf8acc41b8208dae4b7ee5d64
NONCE: 634f99e88e237ef0
IN: 09ee5982c5743f396d0c29c13e3fbb8fb89f61705da05466291e010effd51a5c
AD: 564dddfcc3227b413244f1105b610f192decf15c4cfa067f4d7fcd6bd7af11b8
CT: 32916b67a6f32733623344c98c49773f3e721dc2ded105fb245799525bc9c84c
TAG: ff463c07e7ef831321d3fd775f
KEY: 08ba23616d911188f91da063278bef1237dcbf17f52585e53c2c4b6cf3ac9f0d
NONCE: 989ae593eddd3874
IN: 749152c9478944c8271c0c11e07bc1c569eec01493e65b3b94842a1bf5d721f8
AD: a12d1a45b7c9b91ab08751a70b753714052ad24e0b2619fe8c3be303c65f2dbc
CT: 34c40538ee1d22ddf8ac290dd7d423dfc622b5cf8f3412a5343e277822aea713
TAG: 014c7c678e0949e88071d1fe3531
KEY: c2ba8bed8634156afc6bfe3754c91744d4131de39d059f3a866399f916553b5c
NONCE: 80fbf7b433a4cd9c
IN: 419be6623e7964f9f26068dd969e4a139617e67c5ffb269b3013c433fe771c77
AD: 3937592db78a61ff469691b6800792019bc2b3d42512f23c1b1a66a8274495cb
CT: 9d5bd1c7e766763eb00684c038043111d8c6390a8d6e17a15ef97c02ab16f09c
TAG: a64d0eeb4a01481ec0cee8c1c357e3
+108 -4
View File
@@ -47,8 +47,8 @@ AD: "123456789abcdef0"
CT: e275aeb341e1fc9a70c4fd4496fc7cdb
TAG: 41acd0560ea6843d3e5d4e5babf6e946
# Test vectors from chacha20_poly1305_deprecated_tests.txt, modified for the
# RFC 7539 AEAD construction.
# Test vectors from chacha20_poly1305_old_tests.txt, modified for the RFC 7539
# AEAD construction.
KEY: 9a97f65b9b4c721b960a672145fca8d4e32e67f9111ea979ce9c4826806aeee6
NONCE: 000000003de9c0da2bd7f91e
@@ -470,5 +470,109 @@ AD: fd6a3fdd879f8880843eac20ae01c1b9dc3487d270a806572088ef2ddc1f1e0de495e71d4813
CT: bd11ed07b7b4b30eeaf25d6a41a549cca0a5aee71f990ac566a37265d7af2ce3c03703427ee0b2755c2bdfc29f9d826aec6ee4ad28af48079ac23db16580b97424f3a4e35cc23625d39f95699d9ff5143e9a2bc26fcfee4f125f5aa2d968ccfc2faaf9db3c28850f6757f735cbc50c94c498bcde4f23bffafa8dd5f70d1a011e35eb26e905d4e68848fedebeb197be595c085ba33f11ba8398258445051751888e9bba111f800f31b37c447074ca6dce6d54b4dfad6cee5138643d4f6ac045e8047248924e88ea4294c7878bc22c9b41924ce301f22693c33733107bf1ba85e34806c5e4366ea66fc52a5f89dd9bf213239158b3d4d2600dde696c61d76c398b9bf10de9118e812e891c8f3355c0ecc6405f79bc32a58905e37888a1d8395fbedc3ac54eca569f
TAG: 296a397d280d026fc3627f4718971be9
# BoringSSL has additional tests here for truncated tags. *ring* doesn't
# support tag truncation, so those tests were removed.
# Tag truncation tests.
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
NONCE: 000000005d9856060c54ab06
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
TAG: d3
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
NONCE: 000000005d9856060c54ab06
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
TAG: d3f7
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
NONCE: 000000005d9856060c54ab06
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
TAG: d3f7b9
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
NONCE: 000000005d9856060c54ab06
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
TAG: d3f7b9c2
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
NONCE: 000000005d9856060c54ab06
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
TAG: d3f7b9c295
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
NONCE: 000000005d9856060c54ab06
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
TAG: d3f7b9c295f3
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
NONCE: 000000005d9856060c54ab06
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
TAG: d3f7b9c295f374
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
NONCE: 000000005d9856060c54ab06
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
TAG: d3f7b9c295f37465
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
NONCE: 000000005d9856060c54ab06
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
TAG: d3f7b9c295f374651a
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
NONCE: 000000005d9856060c54ab06
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
TAG: d3f7b9c295f374651a84
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
NONCE: 000000005d9856060c54ab06
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
TAG: d3f7b9c295f374651a8413
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
NONCE: 000000005d9856060c54ab06
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
TAG: d3f7b9c295f374651a841386
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
NONCE: 000000005d9856060c54ab06
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
TAG: d3f7b9c295f374651a84138648
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
NONCE: 000000005d9856060c54ab06
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
TAG: d3f7b9c295f374651a84138648a5
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
NONCE: 000000005d9856060c54ab06
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
TAG: d3f7b9c295f374651a84138648a591
+1 -1
View File
@@ -34,7 +34,7 @@ unsigned long getauxval(unsigned long type) __attribute__((weak));
extern uint32_t OPENSSL_armcap_P;
char CRYPTO_is_NEON_capable(void) {
char CRYPTO_is_NEON_capable_at_runtime(void) {
return (OPENSSL_armcap_P & ARMV7_NEON) != 0;
}
+10 -8
View File
@@ -14,6 +14,8 @@
#include <openssl/crypto.h>
#include <openssl/cpu.h>
#include "internal.h"
@@ -86,22 +88,22 @@ uint32_t OPENSSL_armcap_P = ARMV7_NEON_FUNCTIONAL;
#endif
#if defined(OPENSSL_WINDOWS)
#if defined(OPENSSL_WINDOWS) && !defined(BORINGSSL_NO_STATIC_INITIALIZER)
#define OPENSSL_CDECL __cdecl
#else
#define OPENSSL_CDECL
#endif
#if !defined(BORINGSSL_NO_STATIC_INITIALIZER)
#if !defined(OPENSSL_WINDOWS)
static void do_library_init(void) __attribute__ ((constructor));
#else
#if defined(BORINGSSL_NO_STATIC_INITIALIZER)
static CRYPTO_once_t once = CRYPTO_ONCE_INIT;
#elif defined(OPENSSL_WINDOWS)
#pragma section(".CRT$XCU", read)
static void __cdecl do_library_init(void);
__declspec(allocate(".CRT$XCU")) void(*library_init_constructor)(void) =
do_library_init;
#else
static void do_library_init(void) __attribute__ ((constructor));
#endif
#endif /* !BORINGSSL_NO_STATIC_INITIALIZER */
/* do_library_init is the actual initialization function. If
* BORINGSSL_NO_STATIC_INITIALIZER isn't defined, this is set as a static
@@ -117,9 +119,9 @@ static void OPENSSL_CDECL do_library_init(void) {
void CRYPTO_library_init(void) {
/* TODO(davidben): It would be tidier if this build knob could be replaced
* with an internal lazy-init mechanism that would handle things correctly
* in-library. */
* in-library. https://crbug.com/542879 */
#if defined(BORINGSSL_NO_STATIC_INITIALIZER)
do_library_init();
CRYPTO_once(&once, do_library_init);
#endif
}
+38
View File
@@ -0,0 +1,38 @@
include_directories(../../include)
if (${ARCH} STREQUAL "arm")
set(
CURVE25519_ARCH_SOURCES
asm/x25519-arm.S
)
endif()
add_library(
curve25519
OBJECT
curve25519.c
${CURVE25519_ARCH_SOURCES}
)
add_executable(
ed25519_test
ed25519_test.cc
$<TARGET_OBJECTS:test_support>
)
target_link_libraries(ed25519_test crypto)
add_dependencies(all_tests ed25519_test)
add_executable(
x25519_test
x25519_test.cc
)
target_link_libraries(x25519_test crypto)
add_dependencies(all_tests x25519_test)
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+63
View File
@@ -0,0 +1,63 @@
/* Copyright (c) 2015, 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 <string.h>
#include <openssl/curve25519.h>
#include "../test/file_test.h"
static bool TestSignature(FileTest *t, void *arg) {
std::vector<uint8_t> private_key, public_key, message, expected_signature;
if (!t->GetBytes(&private_key, "PRIV") ||
private_key.size() != 64 ||
!t->GetBytes(&public_key, "PUB") ||
public_key.size() != 32 ||
!t->GetBytes(&message, "MESSAGE") ||
!t->GetBytes(&expected_signature, "SIG") ||
expected_signature.size() != 64) {
return false;
}
uint8_t signature[64];
if (!ED25519_sign(signature, message.data(), message.size(),
private_key.data())) {
t->PrintLine("ED25519_sign failed");
return false;
}
if (!t->ExpectBytesEqual(expected_signature.data(), expected_signature.size(),
signature, sizeof(signature))) {
return false;
}
if (!ED25519_verify(message.data(), message.size(), signature,
public_key.data())) {
t->PrintLine("ED25519_verify failed");
return false;
}
return true;
}
int main(int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "%s <test input.txt>\n", argv[0]);
return 1;
}
return FileTestMain(TestSignature, nullptr, argv[1]);
}
File diff suppressed because it is too large Load Diff
+128
View File
@@ -0,0 +1,128 @@
/* Copyright (c) 2015, 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/curve25519.h>
static bool TestX25519() {
/* Taken from
* https://tools.ietf.org/html/draft-irtf-cfrg-curves-11#section-5.2 */
static const uint8_t kScalar1[32] = {
0xa5, 0x46, 0xe3, 0x6b, 0xf0, 0x52, 0x7c, 0x9d, 0x3b, 0x16, 0x15,
0x4b, 0x82, 0x46, 0x5e, 0xdd, 0x62, 0x14, 0x4c, 0x0a, 0xc1, 0xfc,
0x5a, 0x18, 0x50, 0x6a, 0x22, 0x44, 0xba, 0x44, 0x9a, 0xc4,
};
static const uint8_t kPoint1[32] = {
0xe6, 0xdb, 0x68, 0x67, 0x58, 0x30, 0x30, 0xdb, 0x35, 0x94, 0xc1,
0xa4, 0x24, 0xb1, 0x5f, 0x7c, 0x72, 0x66, 0x24, 0xec, 0x26, 0xb3,
0x35, 0x3b, 0x10, 0xa9, 0x03, 0xa6, 0xd0, 0xab, 0x1c, 0x4c,
};
uint8_t out[32];
X25519(out, kScalar1, kPoint1);
static const uint8_t kExpected1[32] = {
0xc3, 0xda, 0x55, 0x37, 0x9d, 0xe9, 0xc6, 0x90, 0x8e, 0x94, 0xea,
0x4d, 0xf2, 0x8d, 0x08, 0x4f, 0x32, 0xec, 0xcf, 0x03, 0x49, 0x1c,
0x71, 0xf7, 0x54, 0xb4, 0x07, 0x55, 0x77, 0xa2, 0x85, 0x52,
};
if (memcmp(kExpected1, out, sizeof(out)) != 0) {
fprintf(stderr, "X25519 test one failed.\n");
return false;
}
static const uint8_t kScalar2[32] = {
0x4b, 0x66, 0xe9, 0xd4, 0xd1, 0xb4, 0x67, 0x3c, 0x5a, 0xd2, 0x26,
0x91, 0x95, 0x7d, 0x6a, 0xf5, 0xc1, 0x1b, 0x64, 0x21, 0xe0, 0xea,
0x01, 0xd4, 0x2c, 0xa4, 0x16, 0x9e, 0x79, 0x18, 0xba, 0x0d,
};
static const uint8_t kPoint2[32] = {
0xe5, 0x21, 0x0f, 0x12, 0x78, 0x68, 0x11, 0xd3, 0xf4, 0xb7, 0x95,
0x9d, 0x05, 0x38, 0xae, 0x2c, 0x31, 0xdb, 0xe7, 0x10, 0x6f, 0xc0,
0x3c, 0x3e, 0xfc, 0x4c, 0xd5, 0x49, 0xc7, 0x15, 0xa4, 0x93,
};
X25519(out, kScalar2, kPoint2);
static const uint8_t kExpected2[32] = {
0x95, 0xcb, 0xde, 0x94, 0x76, 0xe8, 0x90, 0x7d, 0x7a, 0xad, 0xe4,
0x5c, 0xb4, 0xb8, 0x73, 0xf8, 0x8b, 0x59, 0x5a, 0x68, 0x79, 0x9f,
0xa1, 0x52, 0xe6, 0xf8, 0xf7, 0x64, 0x7a, 0xac, 0x79, 0x57,
};
if (memcmp(kExpected2, out, sizeof(out)) != 0) {
fprintf(stderr, "X25519 test two failed.\n");
return false;
}
return true;
}
static bool TestX25519SmallOrder() {
static const uint8_t kSmallOrderPoint[32] = {
0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3,
0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32,
0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8,
};
uint8_t out[32], private_key[32];
memset(private_key, 0x11, sizeof(private_key));
if (X25519(out, private_key, kSmallOrderPoint)) {
fprintf(stderr, "X25519 returned success with a small-order input.\n");
return false;
}
return true;
}
static bool TestX25519Iterated() {
/* Taken from
* https://tools.ietf.org/html/draft-irtf-cfrg-curves-11#section-5.2 */
uint8_t scalar[32] = {9}, point[32] = {9}, out[32];
unsigned i;
for (i = 0; i < 1000; i++) {
X25519(out, scalar, point);
memcpy(point, scalar, sizeof(point));
memcpy(scalar, out, sizeof(scalar));
}
static const uint8_t kExpected[32] = {
0x68, 0x4c, 0xf5, 0x9b, 0xa8, 0x33, 0x09, 0x55, 0x28, 0x00, 0xef,
0x56, 0x6f, 0x2f, 0x4d, 0x3c, 0x1c, 0x38, 0x87, 0xc4, 0x93, 0x60,
0xe3, 0x87, 0x5f, 0x2e, 0xb9, 0x4d, 0x99, 0x53, 0x2c, 0x51,
};
if (memcmp(kExpected, scalar, sizeof(kExpected)) != 0) {
fprintf(stderr, "Iterated X25519 test failed\n");
return false;
}
return true;
}
int main(int argc, char **argv) {
if (!TestX25519() ||
!TestX25519Iterated() ||
!TestX25519SmallOrder()) {
return 1;
}
printf("PASS\n");
return 0;
}
-17
View File
@@ -202,24 +202,7 @@ how to use xors :-) I got it to its final state.
#define ITERATIONS 16
#define HALF_ITERATIONS 8
#if defined(_MSC_VER)
#define ROTATE(a, n) (_lrotr(a, n))
#elif defined(__ICC)
#define ROTATE(a, n) (_rotr(a, n))
#elif defined(__GNUC__) && __GNUC__ >= 2 && !defined(OPENSSL_NO_ASM) && \
!defined(__STRICT_ANSI__) && \
(defined(OPENSSL_X86) || defined(OPENSSL_X86_64))
#define ROTATE(a, n) \
({ \
unsigned int ret; \
asm("rorl %1,%0" : "=r"(ret) : "I"(n), "0"(a) : "cc"); \
ret; \
})
#endif
#ifndef ROTATE
#define ROTATE(a, n) (((a) >> (n)) + ((a) << (32 - (n))))
#endif
#if defined(__cplusplus)
+4 -8
View File
@@ -85,11 +85,7 @@ DH *DH_new(void) {
CRYPTO_MUTEX_init(&dh->method_mont_p_lock);
dh->references = 1;
if (!CRYPTO_new_ex_data(&g_ex_data_class, dh, &dh->ex_data)) {
CRYPTO_MUTEX_cleanup(&dh->method_mont_p_lock);
OPENSSL_free(dh);
return NULL;
}
CRYPTO_new_ex_data(&dh->ex_data);
return dh;
}
@@ -448,11 +444,11 @@ DH *DHparams_dup(const DH *dh) {
return ret;
}
int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
int index;
if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, new_func,
dup_func, free_func)) {
if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func,
free_func)) {
return -1;
}
return index;
+119 -132
View File
@@ -55,182 +55,169 @@
#include <openssl/bn.h>
#include "internal.h"
#include "../bn/internal.h"
#if BN_BITS2 == 32
#define TOBN(lo, hi) lo, hi
#elif BN_BITS2 == 64
#define TOBN(lo, hi) ((BN_ULONG)hi << 32 | lo)
#else
#error "unsupported BN_BITS2"
#endif
static const BN_ULONG dh1024_160_p[] = {
TOBN(0x2E4A4371, 0xDF1FB2BC), TOBN(0x6D4DA708, 0xE68CFDA7),
TOBN(0x365C1A65, 0x45BF37DF), TOBN(0x0DC8B4BD, 0xA151AF5F),
TOBN(0xF55BCCC0, 0xFAA31A4F), TOBN(0xE5644738, 0x4EFFD6FA),
TOBN(0x219A7372, 0x98488E9C), TOBN(0x90C4BD70, 0xACCBDD7D),
TOBN(0xD49B83BF, 0x24975C3C), TOBN(0xA9061123, 0x13ECB4AE),
TOBN(0x2EE652C0, 0x9838EF1E), TOBN(0x75A23D18, 0x6073E286),
TOBN(0x52D23B61, 0x9A6A9DCA), TOBN(0xFB06A3C6, 0x52C99FBC),
TOBN(0xAE5D54EC, 0xDE92DE5E), TOBN(0xA080E01D, 0xB10B8F96),
TOBN(0xDF1FB2BC, 0x2E4A4371), TOBN(0xE68CFDA7, 0x6D4DA708),
TOBN(0x45BF37DF, 0x365C1A65), TOBN(0xA151AF5F, 0x0DC8B4BD),
TOBN(0xFAA31A4F, 0xF55BCCC0), TOBN(0x4EFFD6FA, 0xE5644738),
TOBN(0x98488E9C, 0x219A7372), TOBN(0xACCBDD7D, 0x90C4BD70),
TOBN(0x24975C3C, 0xD49B83BF), TOBN(0x13ECB4AE, 0xA9061123),
TOBN(0x9838EF1E, 0x2EE652C0), TOBN(0x6073E286, 0x75A23D18),
TOBN(0x9A6A9DCA, 0x52D23B61), TOBN(0x52C99FBC, 0xFB06A3C6),
TOBN(0xDE92DE5E, 0xAE5D54EC), TOBN(0xB10B8F96, 0xA080E01D),
};
static const BN_ULONG dh1024_160_g[] = {
TOBN(0x22B3B2E5, 0x855E6EEB), TOBN(0xF97C2A24, 0x858F4DCE),
TOBN(0x18D08BC8, 0x2D779D59), TOBN(0x8E73AFA3, 0xD662A4D1),
TOBN(0x69B6A28A, 0x1DBF0A01), TOBN(0x7A091F53, 0xA6A24C08),
TOBN(0x63F80A76, 0x909D0D22), TOBN(0xB9A92EE1, 0xD7FBD7D3),
TOBN(0x9E2749F4, 0x5E91547F), TOBN(0xB01B886A, 0x160217B4),
TOBN(0x5504F213, 0x777E690F), TOBN(0x5C41564B, 0x266FEA1E),
TOBN(0x14266D31, 0xD6406CFF), TOBN(0x58AC507F, 0xF8104DD2),
TOBN(0xEFB99905, 0x6765A442), TOBN(0xC3FD3412, 0xA4D1CBD5),
TOBN(0x855E6EEB, 0x22B3B2E5), TOBN(0x858F4DCE, 0xF97C2A24),
TOBN(0x2D779D59, 0x18D08BC8), TOBN(0xD662A4D1, 0x8E73AFA3),
TOBN(0x1DBF0A01, 0x69B6A28A), TOBN(0xA6A24C08, 0x7A091F53),
TOBN(0x909D0D22, 0x63F80A76), TOBN(0xD7FBD7D3, 0xB9A92EE1),
TOBN(0x5E91547F, 0x9E2749F4), TOBN(0x160217B4, 0xB01B886A),
TOBN(0x777E690F, 0x5504F213), TOBN(0x266FEA1E, 0x5C41564B),
TOBN(0xD6406CFF, 0x14266D31), TOBN(0xF8104DD2, 0x58AC507F),
TOBN(0x6765A442, 0xEFB99905), TOBN(0xA4D1CBD5, 0xC3FD3412),
};
static const BN_ULONG dh1024_160_q[] = {
TOBN(0x49462353, 0x64B7CB9D), TOBN(0x8ABA4E7D, 0x81A8DF27), 0xF518AA87,
TOBN(0x64B7CB9D, 0x49462353), TOBN(0x81A8DF27, 0x8ABA4E7D), 0xF518AA87,
};
static const BN_ULONG dh2048_224_p[] = {
TOBN(0x0C10E64F, 0x0AC4DFFE), TOBN(0x4E71B81C, 0xCF9DE538),
TOBN(0xFFA31F71, 0x7EF363E2), TOBN(0x6B8E75B9, 0xE3FB73C1),
TOBN(0x4BA80A29, 0xC9B53DCF), TOBN(0x16E79763, 0x23F10B0E),
TOBN(0x13042E9B, 0xC52172E4), TOBN(0xC928B2B9, 0xBE60E69C),
TOBN(0xB9E587E8, 0x80CD86A1), TOBN(0x98C641A4, 0x315D75E1),
TOBN(0x44328387, 0xCDF93ACC), TOBN(0xDC0A486D, 0x15987D9A),
TOBN(0x1FD5A074, 0x7310F712), TOBN(0xDE31EFDC, 0x278273C7),
TOBN(0x415D9330, 0x1602E714), TOBN(0xBC8985DB, 0x81286130),
TOBN(0x70918836, 0xB3BF8A31), TOBN(0xB9C49708, 0x6A00E0A0),
TOBN(0x8BBC27BE, 0xC6BA0B2C), TOBN(0xED34DBF6, 0xC9F98D11),
TOBN(0xB6C12207, 0x7AD5B7D0), TOBN(0x55B7394B, 0xD91E8FEF),
TOBN(0xEFDA4DF8, 0x9037C9ED), TOBN(0xAD6AC212, 0x6D3F8152),
TOBN(0x1274A0A6, 0x1DE6B85A), TOBN(0x309C180E, 0xEB3D688A),
TOBN(0x7BA1DF15, 0xAF9A3C40), TOBN(0xF95A56DB, 0xE6FA141D),
TOBN(0xB61D0A75, 0xB54B1597), TOBN(0x683B9FD1, 0xA20D64E5),
TOBN(0x9559C51F, 0xD660FAA7), TOBN(0x9123A9D0, 0xAD107E1E),
TOBN(0x0AC4DFFE, 0x0C10E64F), TOBN(0xCF9DE538, 0x4E71B81C),
TOBN(0x7EF363E2, 0xFFA31F71), TOBN(0xE3FB73C1, 0x6B8E75B9),
TOBN(0xC9B53DCF, 0x4BA80A29), TOBN(0x23F10B0E, 0x16E79763),
TOBN(0xC52172E4, 0x13042E9B), TOBN(0xBE60E69C, 0xC928B2B9),
TOBN(0x80CD86A1, 0xB9E587E8), TOBN(0x315D75E1, 0x98C641A4),
TOBN(0xCDF93ACC, 0x44328387), TOBN(0x15987D9A, 0xDC0A486D),
TOBN(0x7310F712, 0x1FD5A074), TOBN(0x278273C7, 0xDE31EFDC),
TOBN(0x1602E714, 0x415D9330), TOBN(0x81286130, 0xBC8985DB),
TOBN(0xB3BF8A31, 0x70918836), TOBN(0x6A00E0A0, 0xB9C49708),
TOBN(0xC6BA0B2C, 0x8BBC27BE), TOBN(0xC9F98D11, 0xED34DBF6),
TOBN(0x7AD5B7D0, 0xB6C12207), TOBN(0xD91E8FEF, 0x55B7394B),
TOBN(0x9037C9ED, 0xEFDA4DF8), TOBN(0x6D3F8152, 0xAD6AC212),
TOBN(0x1DE6B85A, 0x1274A0A6), TOBN(0xEB3D688A, 0x309C180E),
TOBN(0xAF9A3C40, 0x7BA1DF15), TOBN(0xE6FA141D, 0xF95A56DB),
TOBN(0xB54B1597, 0xB61D0A75), TOBN(0xA20D64E5, 0x683B9FD1),
TOBN(0xD660FAA7, 0x9559C51F), TOBN(0xAD107E1E, 0x9123A9D0),
};
static const BN_ULONG dh2048_224_g[] = {
TOBN(0x191F2BFA, 0x84B890D3), TOBN(0x2A7065B3, 0x81BC087F),
TOBN(0xF6EC0179, 0x19C418E1), TOBN(0x71CFFF4C, 0x7B5A0F1C),
TOBN(0x9B6AA4BD, 0xEDFE72FE), TOBN(0x94B30269, 0x81E1BCFE),
TOBN(0x8D6C0191, 0x566AFBB4), TOBN(0x409D13CD, 0xB539CCE3),
TOBN(0x5F2FF381, 0x6AA21E7F), TOBN(0x770589EF, 0xD9E263E4),
TOBN(0xD19963DD, 0x10E183ED), TOBN(0x150B8EEB, 0xB70A8137),
TOBN(0x28C8F8AC, 0x051AE3D4), TOBN(0x0C1AB15B, 0xBB77A86F),
TOBN(0x16A330EF, 0x6E3025E3), TOBN(0xD6F83456, 0x19529A45),
TOBN(0x118E98D1, 0xF180EB34), TOBN(0x50717CBE, 0xB5F6C6B2),
TOBN(0xDA7460CD, 0x09939D54), TOBN(0x22EA1ED4, 0xE2471504),
TOBN(0x521BC98A, 0xB8A762D0), TOBN(0x5AC1348B, 0xF4D02727),
TOBN(0x1999024A, 0xC1766910), TOBN(0xA8D66AD7, 0xBE5E9001),
TOBN(0x620A8652, 0xC57DB17C), TOBN(0x00C29F52, 0xAB739D77),
TOBN(0xA70C4AFA, 0xDD921F01), TOBN(0x10B9A6F0, 0xA6824A4E),
TOBN(0xCFE4FFE3, 0x74866A08), TOBN(0x89998CAF, 0x6CDEBE7B),
TOBN(0x8FFDAC50, 0x9DF30B5C), TOBN(0x4F2D9AE3, 0xAC4032EF),
TOBN(0x84B890D3, 0x191F2BFA), TOBN(0x81BC087F, 0x2A7065B3),
TOBN(0x19C418E1, 0xF6EC0179), TOBN(0x7B5A0F1C, 0x71CFFF4C),
TOBN(0xEDFE72FE, 0x9B6AA4BD), TOBN(0x81E1BCFE, 0x94B30269),
TOBN(0x566AFBB4, 0x8D6C0191), TOBN(0xB539CCE3, 0x409D13CD),
TOBN(0x6AA21E7F, 0x5F2FF381), TOBN(0xD9E263E4, 0x770589EF),
TOBN(0x10E183ED, 0xD19963DD), TOBN(0xB70A8137, 0x150B8EEB),
TOBN(0x051AE3D4, 0x28C8F8AC), TOBN(0xBB77A86F, 0x0C1AB15B),
TOBN(0x6E3025E3, 0x16A330EF), TOBN(0x19529A45, 0xD6F83456),
TOBN(0xF180EB34, 0x118E98D1), TOBN(0xB5F6C6B2, 0x50717CBE),
TOBN(0x09939D54, 0xDA7460CD), TOBN(0xE2471504, 0x22EA1ED4),
TOBN(0xB8A762D0, 0x521BC98A), TOBN(0xF4D02727, 0x5AC1348B),
TOBN(0xC1766910, 0x1999024A), TOBN(0xBE5E9001, 0xA8D66AD7),
TOBN(0xC57DB17C, 0x620A8652), TOBN(0xAB739D77, 0x00C29F52),
TOBN(0xDD921F01, 0xA70C4AFA), TOBN(0xA6824A4E, 0x10B9A6F0),
TOBN(0x74866A08, 0xCFE4FFE3), TOBN(0x6CDEBE7B, 0x89998CAF),
TOBN(0x9DF30B5C, 0x8FFDAC50), TOBN(0xAC4032EF, 0x4F2D9AE3),
};
static const BN_ULONG dh2048_224_q[] = {
TOBN(0xB36371EB, 0xBF389A99), TOBN(0x4738CEBC, 0x1F80535A),
TOBN(0x99717710, 0xC58D93FE), 0x801C0D34,
TOBN(0xBF389A99, 0xB36371EB), TOBN(0x1F80535A, 0x4738CEBC),
TOBN(0xC58D93FE, 0x99717710), 0x801C0D34,
};
static const BN_ULONG dh2048_256_p[] = {
TOBN(0x1E1A1597, 0xDB094AE9), TOBN(0xD7EF09CA, 0x693877FA),
TOBN(0x6E11715F, 0x6116D227), TOBN(0xC198AF12, 0xA4B54330),
TOBN(0xD7014103, 0x75F26375), TOBN(0x54E710C3, 0xC3A3960A),
TOBN(0xBD0BE621, 0xDED4010A), TOBN(0x89962856, 0xC0B857F6),
TOBN(0x71506026, 0xB3CA3F79), TOBN(0xE6B486F6, 0x1CCACB83),
TOBN(0x14056425, 0x67E144E5), TOBN(0xA41825D9, 0xF6A167B5),
TOBN(0x96524D8E, 0x3AD83477), TOBN(0x51BFA4AB, 0xF13C6D9A),
TOBN(0x35488A0E, 0x2D525267), TOBN(0xCAA6B790, 0xB63ACAE1),
TOBN(0x81B23F76, 0x4FDB70C5), TOBN(0x12307F5C, 0xBC39A0BF),
TOBN(0xB1E59BB8, 0xB941F54E), TOBN(0xD45F9088, 0x6C5BFC11),
TOBN(0x4275BF7B, 0x22E0B1EF), TOBN(0x5B4758C0, 0x91F9E672),
TOBN(0x6BCF67ED, 0x5A8A9D30), TOBN(0x97517ABD, 0x209E0C64),
TOBN(0x830E9A7C, 0x3BF4296D), TOBN(0x34096FAA, 0x16C3D911),
TOBN(0x61B2AA30, 0xFAF7DF45), TOBN(0xD61957D4, 0xE00DF8F1),
TOBN(0x435E3B00, 0x5D2CEED4), TOBN(0x660DD0F2, 0x8CEEF608),
TOBN(0x65195999, 0xFFBBD19C), TOBN(0xB4B6663C, 0x87A8E61D),
TOBN(0xDB094AE9, 0x1E1A1597), TOBN(0x693877FA, 0xD7EF09CA),
TOBN(0x6116D227, 0x6E11715F), TOBN(0xA4B54330, 0xC198AF12),
TOBN(0x75F26375, 0xD7014103), TOBN(0xC3A3960A, 0x54E710C3),
TOBN(0xDED4010A, 0xBD0BE621), TOBN(0xC0B857F6, 0x89962856),
TOBN(0xB3CA3F79, 0x71506026), TOBN(0x1CCACB83, 0xE6B486F6),
TOBN(0x67E144E5, 0x14056425), TOBN(0xF6A167B5, 0xA41825D9),
TOBN(0x3AD83477, 0x96524D8E), TOBN(0xF13C6D9A, 0x51BFA4AB),
TOBN(0x2D525267, 0x35488A0E), TOBN(0xB63ACAE1, 0xCAA6B790),
TOBN(0x4FDB70C5, 0x81B23F76), TOBN(0xBC39A0BF, 0x12307F5C),
TOBN(0xB941F54E, 0xB1E59BB8), TOBN(0x6C5BFC11, 0xD45F9088),
TOBN(0x22E0B1EF, 0x4275BF7B), TOBN(0x91F9E672, 0x5B4758C0),
TOBN(0x5A8A9D30, 0x6BCF67ED), TOBN(0x209E0C64, 0x97517ABD),
TOBN(0x3BF4296D, 0x830E9A7C), TOBN(0x16C3D911, 0x34096FAA),
TOBN(0xFAF7DF45, 0x61B2AA30), TOBN(0xE00DF8F1, 0xD61957D4),
TOBN(0x5D2CEED4, 0x435E3B00), TOBN(0x8CEEF608, 0x660DD0F2),
TOBN(0xFFBBD19C, 0x65195999), TOBN(0x87A8E61D, 0xB4B6663C),
};
static const BN_ULONG dh2048_256_g[] = {
TOBN(0x6CC41659, 0x664B4C0F), TOBN(0xEF98C582, 0x5E2327CF),
TOBN(0xD4795451, 0xD647D148), TOBN(0x90F00EF8, 0x2F630784),
TOBN(0x1DB246C3, 0x184B523D), TOBN(0xCDC67EB6, 0xC7891428),
TOBN(0x0DF92B52, 0x7FD02837), TOBN(0x64E0EC37, 0xB3353BBB),
TOBN(0x57CD0915, 0xECD06E15), TOBN(0xDF016199, 0xB7D2BBD2),
TOBN(0x052588B9, 0xC8484B1E), TOBN(0x13D3FE14, 0xDB2A3B73),
TOBN(0xD182EA0A, 0xD052B985), TOBN(0xE83B9C80, 0xA4BD1BFF),
TOBN(0xFB3F2E55, 0xDFC967C1), TOBN(0x767164E1, 0xB5045AF2),
TOBN(0x6F2F9193, 0x1D14348F), TOBN(0x428EBC83, 0x64E67982),
TOBN(0x82D6ED38, 0x8AC376D2), TOBN(0xAAB8A862, 0x777DE62A),
TOBN(0xE9EC144B, 0xDDF463E5), TOBN(0xC77A57F2, 0x0196F931),
TOBN(0x41000A65, 0xA55AE313), TOBN(0xC28CBB18, 0x901228F8),
TOBN(0x7E8C6F62, 0xBC3773BF), TOBN(0x0C6B47B1, 0xBE3A6C1B),
TOBN(0xAC0BB555, 0xFF4FED4A), TOBN(0x77BE463F, 0x10DBC150),
TOBN(0x1A0BA125, 0x07F4793A), TOBN(0x21EF2054, 0x4CA7B18F),
TOBN(0x60EDBD48, 0x2E775066), TOBN(0x73134D0B, 0x3FB32C9B),
TOBN(0x664B4C0F, 0x6CC41659), TOBN(0x5E2327CF, 0xEF98C582),
TOBN(0xD647D148, 0xD4795451), TOBN(0x2F630784, 0x90F00EF8),
TOBN(0x184B523D, 0x1DB246C3), TOBN(0xC7891428, 0xCDC67EB6),
TOBN(0x7FD02837, 0x0DF92B52), TOBN(0xB3353BBB, 0x64E0EC37),
TOBN(0xECD06E15, 0x57CD0915), TOBN(0xB7D2BBD2, 0xDF016199),
TOBN(0xC8484B1E, 0x052588B9), TOBN(0xDB2A3B73, 0x13D3FE14),
TOBN(0xD052B985, 0xD182EA0A), TOBN(0xA4BD1BFF, 0xE83B9C80),
TOBN(0xDFC967C1, 0xFB3F2E55), TOBN(0xB5045AF2, 0x767164E1),
TOBN(0x1D14348F, 0x6F2F9193), TOBN(0x64E67982, 0x428EBC83),
TOBN(0x8AC376D2, 0x82D6ED38), TOBN(0x777DE62A, 0xAAB8A862),
TOBN(0xDDF463E5, 0xE9EC144B), TOBN(0x0196F931, 0xC77A57F2),
TOBN(0xA55AE313, 0x41000A65), TOBN(0x901228F8, 0xC28CBB18),
TOBN(0xBC3773BF, 0x7E8C6F62), TOBN(0xBE3A6C1B, 0x0C6B47B1),
TOBN(0xFF4FED4A, 0xAC0BB555), TOBN(0x10DBC150, 0x77BE463F),
TOBN(0x07F4793A, 0x1A0BA125), TOBN(0x4CA7B18F, 0x21EF2054),
TOBN(0x2E775066, 0x60EDBD48), TOBN(0x3FB32C9B, 0x73134D0B),
};
static const BN_ULONG dh2048_256_q[] = {
TOBN(0x64F5FBD3, 0xA308B0FE), TOBN(0x1EB3750B, 0x99B1A47D),
TOBN(0x40129DA2, 0xB4479976), TOBN(0xA709A097, 0x8CF83642),
TOBN(0xA308B0FE, 0x64F5FBD3), TOBN(0x99B1A47D, 0x1EB3750B),
TOBN(0xB4479976, 0x40129DA2), TOBN(0x8CF83642, 0xA709A097),
};
/* dh1024_safe_prime_1 is hard-coded in Apache httpd 2.2,
* modules/ssl/ssl_engine_dh.c. */
static const BN_ULONG dh1024_safe_prime_1[] = {
TOBN(0x24218EB3, 0xE7393E0F), TOBN(0xE2BD68B0, 0x7DE0F4D6),
TOBN(0x88AEAA74, 0x07DD62DB), TOBN(0x9DDD3305, 0x10EA9FCC),
TOBN(0x74087D15, 0xA7DBCA78), TOBN(0x78045B07, 0xDAE88600),
TOBN(0x1AAD3B72, 0x33168A46), TOBN(0x7BEDDCFD, 0xFF590137),
TOBN(0x7A635E81, 0xFE324A46), TOBN(0x420B2A29, 0x5AC179BA),
TOBN(0x177E16D5, 0x13B4B4D7), TOBN(0x639C72FB, 0x849F912E),
TOBN(0x98BCE951, 0xB88174CB), TOBN(0xA45F520B, 0x0C84D239),
TOBN(0x4AFD0AD5, 0x36D693D3), TOBN(0xCBBBDC19, 0xD67DE440),
TOBN(0xE7393E0F, 0x24218EB3), TOBN(0x7DE0F4D6, 0xE2BD68B0),
TOBN(0x07DD62DB, 0x88AEAA74), TOBN(0x10EA9FCC, 0x9DDD3305),
TOBN(0xA7DBCA78, 0x74087D15), TOBN(0xDAE88600, 0x78045B07),
TOBN(0x33168A46, 0x1AAD3B72), TOBN(0xFF590137, 0x7BEDDCFD),
TOBN(0xFE324A46, 0x7A635E81), TOBN(0x5AC179BA, 0x420B2A29),
TOBN(0x13B4B4D7, 0x177E16D5), TOBN(0x849F912E, 0x639C72FB),
TOBN(0xB88174CB, 0x98BCE951), TOBN(0x0C84D239, 0xA45F520B),
TOBN(0x36D693D3, 0x4AFD0AD5), TOBN(0xD67DE440, 0xCBBBDC19),
};
/* dh1024_safe_prime_2 is hard-coded in nginx,
* src/event/ngx_event_openssl.c. */
static const BN_ULONG dh1024_safe_prime_2[] = {
TOBN(0xCFE16B9B, 0x071DF045), TOBN(0x146757DA, 0x88D0F65D),
TOBN(0x58FAFD49, 0x4A63AB1E), TOBN(0xEF9EA027, 0x35D8CECE),
TOBN(0x70CC9A50, 0x25ECE662), TOBN(0x81DC2CA7, 0xF29BA5DF),
TOBN(0xF7D36CC8, 0x8F68B076), TOBN(0xA757E304, 0x60E91A92),
TOBN(0x9BE67780, 0x87A2BC04), TOBN(0xA5FDF1D2, 0xBEECA565),
TOBN(0x922614C5, 0x5CCBBAA8), TOBN(0xE710800C, 0x6C030276),
TOBN(0x0FB3504C, 0x08EED4EB), TOBN(0x68B42D4B, 0xD958A3F5),
TOBN(0x80E9CFDB, 0x7C43FCF5), TOBN(0xD8467490, 0xBBBC2DCA),
TOBN(0x071DF045, 0xCFE16B9B), TOBN(0x88D0F65D, 0x146757DA),
TOBN(0x4A63AB1E, 0x58FAFD49), TOBN(0x35D8CECE, 0xEF9EA027),
TOBN(0x25ECE662, 0x70CC9A50), TOBN(0xF29BA5DF, 0x81DC2CA7),
TOBN(0x8F68B076, 0xF7D36CC8), TOBN(0x60E91A92, 0xA757E304),
TOBN(0x87A2BC04, 0x9BE67780), TOBN(0xBEECA565, 0xA5FDF1D2),
TOBN(0x5CCBBAA8, 0x922614C5), TOBN(0x6C030276, 0xE710800C),
TOBN(0x08EED4EB, 0x0FB3504C), TOBN(0xD958A3F5, 0x68B42D4B),
TOBN(0x7C43FCF5, 0x80E9CFDB), TOBN(0xBBBC2DCA, 0xD8467490),
};
/* dh1024_safe_prime_3 is offered as a parameter by several high-traffic sites,
* including mozilla.org, as of Jan 2015. */
static const BN_ULONG dh1024_safe_prime_3[] = {
TOBN(0x349E721B, 0x671746AE), TOBN(0xD75E93B2, 0x258A0655),
TOBN(0x25592EB6, 0xD425E6FB), TOBN(0xBF7CDD9A, 0x0C46AB04),
TOBN(0x28968680, 0x0AD0BC99), TOBN(0xD0B7EB49, 0xF53907FB),
TOBN(0xEBC85C1D, 0x202EABB3), TOBN(0x364D8C71, 0x3129C693),
TOBN(0x2D46F195, 0x53728351), TOBN(0x8C76CC85, 0xDF326DD6),
TOBN(0x9188E24E, 0xF898B3F9), TOBN(0x2855DFD2, 0x95EFB13C),
TOBN(0x7B2241FE, 0x1F5DAC48), TOBN(0x99A13D9F, 0x117B6BF7),
TOBN(0x3A3468C7, 0x0F97CDDA), TOBN(0x74A8297B, 0xC9BBF5F7)};
TOBN(0x671746AE, 0x349E721B), TOBN(0x258A0655, 0xD75E93B2),
TOBN(0xD425E6FB, 0x25592EB6), TOBN(0x0C46AB04, 0xBF7CDD9A),
TOBN(0x0AD0BC99, 0x28968680), TOBN(0xF53907FB, 0xD0B7EB49),
TOBN(0x202EABB3, 0xEBC85C1D), TOBN(0x3129C693, 0x364D8C71),
TOBN(0x53728351, 0x2D46F195), TOBN(0xDF326DD6, 0x8C76CC85),
TOBN(0xF898B3F9, 0x9188E24E), TOBN(0x95EFB13C, 0x2855DFD2),
TOBN(0x1F5DAC48, 0x7B2241FE), TOBN(0x117B6BF7, 0x99A13D9F),
TOBN(0x0F97CDDA, 0x3A3468C7), TOBN(0xC9BBF5F7, 0x74A8297B)};
/* dh1024_safe_prime_4 is hard-coded in Apache httpd 2.0,
* modules/ssl/ssl_engine_dh.c. */
static const BN_ULONG dh1024_safe_prime_4[] = {
TOBN(0x0DD5C86B, 0x5085E21F), TOBN(0xD823C650, 0x871538DF),
TOBN(0x262E56A8, 0x125136F7), TOBN(0x839EB5DB, 0x974E9EF1),
TOBN(0x1B13A63C, 0xEA9BAD99), TOBN(0x3D76E05E, 0x6044CF02),
TOBN(0x1BAC9B5C, 0x611EBBBE), TOBN(0x4E5327DF, 0x3E371D79),
TOBN(0x061CBC05, 0x000E6EDD), TOBN(0x20129B48, 0x2F971F3C),
TOBN(0x3048D5A2, 0xA6EF09C4), TOBN(0xCBD523A6, 0xFA15A259),
TOBN(0x4A79A770, 0x2A206490), TOBN(0x51BB055E, 0x91B78182),
TOBN(0xBDD4798E, 0x7CF180C3), TOBN(0x495BE32C, 0xE6969D3D)};
TOBN(0x5085E21F, 0x0DD5C86B), TOBN(0x871538DF, 0xD823C650),
TOBN(0x125136F7, 0x262E56A8), TOBN(0x974E9EF1, 0x839EB5DB),
TOBN(0xEA9BAD99, 0x1B13A63C), TOBN(0x6044CF02, 0x3D76E05E),
TOBN(0x611EBBBE, 0x1BAC9B5C), TOBN(0x3E371D79, 0x4E5327DF),
TOBN(0x000E6EDD, 0x061CBC05), TOBN(0x2F971F3C, 0x20129B48),
TOBN(0xA6EF09C4, 0x3048D5A2), TOBN(0xFA15A259, 0xCBD523A6),
TOBN(0x2A206490, 0x4A79A770), TOBN(0x91B78182, 0x51BB055E),
TOBN(0x7CF180C3, 0xBDD4798E), TOBN(0xE6969D3D, 0x495BE32C)};
static const BN_ULONG bn_two_data[] = {2};
#define STATIC_BIGNUM(x) \
{ \
(BN_ULONG *) x, sizeof(x) / sizeof(BN_ULONG), \
sizeof(x) / sizeof(BN_ULONG), 0, BN_FLG_STATIC_DATA \
}
struct standard_parameters {
BIGNUM p, q, g;
};
@@ -260,7 +247,7 @@ static const BIGNUM dh1024_safe_prime[] = {
STATIC_BIGNUM(dh1024_safe_prime_4)
};
BIGNUM bn_two = STATIC_BIGNUM(bn_two_data);
static BIGNUM bn_two = STATIC_BIGNUM(bn_two_data);
static DH *get_standard_parameters(const struct standard_parameters *params,
const ENGINE *engine) {
+153 -183
View File
@@ -51,12 +51,12 @@
#include <openssl/base.h>
#include <assert.h>
#if defined(__cplusplus)
extern "C" {
#endif
#define asm __asm__
/* This is a generic 32-bit "collector" for message digest algorithms. It
* collects input character stream into chunks of 32-bit values and invokes the
@@ -74,14 +74,15 @@ extern "C" {
*
* typedef struct <name>_state_st {
* uint32_t h[<chaining length> / sizeof(uint32_t)];
* uint32_t Nl,Nh;
* uint32_t data[HASH_CBLOCK / sizeof(uint32_t)];
* unsigned int num
* uint32_t Nl, Nh;
* uint8_t data[HASH_CBLOCK];
* unsigned num;
* ...
* } <NAME>_CTX;
*
* <chaining length> is the output length of the hash in bytes, before
* any truncation (e.g. 64 for SHA-224 and SHA-256, 128 for SHA-384 and SHA-512).
* any truncation (e.g. 64 for SHA-224 and SHA-256, 128 for SHA-384 and
* SHA-512).
*
* |HASH_UPDATE| must be defined as the name of the "Update" function to
* generate.
@@ -133,220 +134,189 @@ extern "C" {
#error "HASH_BLOCK_DATA_ORDER must be defined!"
#endif
/*
* Engage compiler specific rotate intrinsic function if available.
*/
#undef ROTATE
# if defined(_MSC_VER)
# define ROTATE(a,n) _lrotl(a,n)
# elif defined(__ICC)
# define ROTATE(a,n) _rotl(a,n)
# elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM)
/*
* Some GNU C inline assembler templates. Note that these are
* rotates by *constant* number of bits! But that's exactly
* what we need here...
* <appro@fy.chalmers.se>
*/
# if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
# define ROTATE(a,n) ({ register uint32_t ret; \
asm ( \
"roll %1,%0" \
: "=r"(ret) \
: "I"(n), "0"((uint32_t)(a)) \
: "cc"); \
ret; \
})
# endif /* OPENSSL_X86 || OPENSSL_X86_64 */
# endif /* COMPILER */
#ifndef ROTATE
#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
#ifndef HASH_MAKE_STRING
#error "HASH_MAKE_STRING must be defined!"
#endif
#if defined(DATA_ORDER_IS_BIG_ENDIAN)
#ifndef PEDANTIC
# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM)
# if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
/*
* This gives ~30-40% performance improvement in SHA-256 compiled
* with gcc [on P4]. Well, first macro to be frank. We can pull
* this trick on x86* platforms only, because these CPUs can fetch
* unaligned data without raising an exception.
*/
# define HOST_c2l(c,l) ({ uint32_t r=*((const uint32_t *)(c)); \
asm ("bswapl %0":"=r"(r):"0"(r)); \
(c)+=4; (l)=r; })
# define HOST_l2c(l,c) ({ uint32_t r=(l); \
asm ("bswapl %0":"=r"(r):"0"(r)); \
*((uint32_t *)(c))=r; (c)+=4; r; })
# elif defined(__aarch64__)
# if defined(__BYTE_ORDER__)
# if defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__
# define HOST_c2l(c,l) ({ uint32_t r; \
asm ("rev %w0,%w1" \
:"=r"(r) \
:"r"(*((const uint32_t *)(c))));\
(c)+=4; (l)=r; })
# define HOST_l2c(l,c) ({ uint32_t r; \
asm ("rev %w0,%w1" \
:"=r"(r) \
:"r"((uint32_t)(l))); \
*((uint32_t *)(c))=r; (c)+=4; r; })
# elif defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__
# define HOST_c2l(c,l) (void)((l)=*((const uint32_t *)(c)), (c)+=4)
# define HOST_l2c(l,c) (*((uint32_t *)(c))=(l), (c)+=4, (l))
# endif
# endif
# endif
# endif
#endif
#if !defined(PEDANTIC) && defined(__GNUC__) && __GNUC__ >= 2 && \
!defined(OPENSSL_NO_ASM)
#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
/* The first macro gives a ~30-40% performance improvement in SHA-256 compiled
* with gcc on P4. This can only be done on x86, where unaligned data fetches
* are possible. */
#define HOST_c2l(c, l) \
(void)({ \
uint32_t r = *((const uint32_t *)(c)); \
__asm__("bswapl %0" : "=r"(r) : "0"(r)); \
(c) += 4; \
(l) = r; \
})
#define HOST_l2c(l, c) \
(void)({ \
uint32_t r = (l); \
__asm__("bswapl %0" : "=r"(r) : "0"(r)); \
*((uint32_t *)(c)) = r; \
(c) += 4; \
r; \
})
#elif defined(__aarch64__) && defined(__BYTE_ORDER__)
#if defined(__ORDER_LITTLE_ENDIAN__) && \
__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define HOST_c2l(c, l) \
(void)({ \
uint32_t r; \
__asm__("rev %w0, %w1" : "=r"(r) : "r"(*((const uint32_t *)(c)))); \
(c) += 4; \
(l) = r; \
})
#define HOST_l2c(l, c) \
(void)({ \
uint32_t r; \
__asm__("rev %w0, %w1" : "=r"(r) : "r"((uint32_t)(l))); \
*((uint32_t *)(c)) = r; \
(c) += 4; \
r; \
})
#elif defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define HOST_c2l(c, l) (void)((l) = *((const uint32_t *)(c)), (c) += 4)
#define HOST_l2c(l, c) (*((uint32_t *)(c)) = (l), (c) += 4, (l))
#endif /* __aarch64__ && __BYTE_ORDER__ */
#endif /* ARCH */
#endif /* !PEDANTIC && GNUC && !NO_ASM */
#ifndef HOST_c2l
#define HOST_c2l(c,l) (void)(l =(((uint32_t)(*((c)++)))<<24), \
l|=(((uint32_t)(*((c)++)))<<16), \
l|=(((uint32_t)(*((c)++)))<< 8), \
l|=(((uint32_t)(*((c)++))) ))
#define HOST_c2l(c, l) \
(void)(l = (((uint32_t)(*((c)++))) << 24), \
l |= (((uint32_t)(*((c)++))) << 16), \
l |= (((uint32_t)(*((c)++))) << 8), l |= (((uint32_t)(*((c)++)))))
#endif
#ifndef HOST_l2c
#define HOST_l2c(l,c) (*((c)++)=(uint8_t)(((l)>>24)&0xff), \
*((c)++)=(uint8_t)(((l)>>16)&0xff), \
*((c)++)=(uint8_t)(((l)>> 8)&0xff), \
*((c)++)=(uint8_t)(((l) )&0xff), \
l)
#define HOST_l2c(l, c) \
(void)(*((c)++) = (uint8_t)(((l) >> 24) & 0xff), \
*((c)++) = (uint8_t)(((l) >> 16) & 0xff), \
*((c)++) = (uint8_t)(((l) >> 8) & 0xff), \
*((c)++) = (uint8_t)(((l)) & 0xff))
#endif
#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
/* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */
# define HOST_c2l(c,l) (void)((l)=*((const uint32_t *)(c)), (c)+=4)
# define HOST_l2c(l,c) (*((uint32_t *)(c))=(l), (c)+=4, l)
#endif
/* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */
#define HOST_c2l(c, l) (void)((l) = *((const uint32_t *)(c)), (c) += 4)
#define HOST_l2c(l, c) (void)(*((uint32_t *)(c)) = (l), (c) += 4, l)
#endif /* OPENSSL_X86 || OPENSSL_X86_64 */
#ifndef HOST_c2l
#define HOST_c2l(c,l) (void)(l =(((uint32_t)(*((c)++))) ), \
l|=(((uint32_t)(*((c)++)))<< 8), \
l|=(((uint32_t)(*((c)++)))<<16), \
l|=(((uint32_t)(*((c)++)))<<24))
#define HOST_c2l(c, l) \
(void)(l = (((uint32_t)(*((c)++)))), l |= (((uint32_t)(*((c)++))) << 8), \
l |= (((uint32_t)(*((c)++))) << 16), \
l |= (((uint32_t)(*((c)++))) << 24))
#endif
#ifndef HOST_l2c
#define HOST_l2c(l,c) (*((c)++)=(uint8_t)(((l) )&0xff), \
*((c)++)=(uint8_t)(((l)>> 8)&0xff), \
*((c)++)=(uint8_t)(((l)>>16)&0xff), \
*((c)++)=(uint8_t)(((l)>>24)&0xff), \
l)
#define HOST_l2c(l, c) \
(void)(*((c)++) = (uint8_t)(((l)) & 0xff), \
*((c)++) = (uint8_t)(((l) >> 8) & 0xff), \
*((c)++) = (uint8_t)(((l) >> 16) & 0xff), \
*((c)++) = (uint8_t)(((l) >> 24) & 0xff))
#endif
#endif
#endif /* DATA_ORDER */
int HASH_UPDATE (HASH_CTX *c, const void *data_, size_t len)
{
const uint8_t *data=data_;
uint8_t *p;
uint32_t l;
size_t n;
int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len) {
const uint8_t *data = data_;
if (len==0) return 1;
if (len == 0) {
return 1;
}
l=(c->Nl+(((uint32_t)len)<<3))&0xffffffffUL;
/* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
* Wei Dai <weidai@eskimo.com> for pointing it out. */
if (l < c->Nl) /* overflow */
c->Nh++;
c->Nh+=(uint32_t)(len>>29); /* might cause compiler warning on 16-bit */
c->Nl=l;
uint32_t l = c->Nl + (((uint32_t)len) << 3);
if (l < c->Nl) {
/* Handle carries. */
c->Nh++;
}
c->Nh += (uint32_t)(len >> 29);
c->Nl = l;
n = c->num;
if (n != 0)
{
p=(uint8_t *)c->data;
size_t n = c->num;
if (n != 0) {
if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) {
memcpy(c->data + n, data, HASH_CBLOCK - n);
HASH_BLOCK_DATA_ORDER(c->h, c->data, 1);
n = HASH_CBLOCK - n;
data += n;
len -= n;
c->num = 0;
/* Keep |c->data| zeroed when unused. */
memset(c->data, 0, HASH_CBLOCK);
} else {
memcpy(c->data + n, data, len);
c->num += (unsigned)len;
return 1;
}
}
if (len >= HASH_CBLOCK || len+n >= HASH_CBLOCK)
{
memcpy (p+n,data,HASH_CBLOCK-n);
HASH_BLOCK_DATA_ORDER (c->h,p,1);
n = HASH_CBLOCK-n;
data += n;
len -= n;
c->num = 0;
memset (p,0,HASH_CBLOCK); /* keep it zeroed */
}
else
{
memcpy (p+n,data,len);
c->num += (unsigned int)len;
return 1;
}
}
n = len / HASH_CBLOCK;
if (n > 0) {
HASH_BLOCK_DATA_ORDER(c->h, data, n);
n *= HASH_CBLOCK;
data += n;
len -= n;
}
n = len/HASH_CBLOCK;
if (n > 0)
{
HASH_BLOCK_DATA_ORDER (c->h,data,n);
n *= HASH_CBLOCK;
data += n;
len -= n;
}
if (len != 0)
{
p = (uint8_t *)c->data;
c->num = (unsigned int)len;
memcpy (p,data,len);
}
return 1;
}
if (len != 0) {
c->num = (unsigned)len;
memcpy(c->data, data, len);
}
return 1;
}
void HASH_TRANSFORM (HASH_CTX *c, const uint8_t *data)
{
HASH_BLOCK_DATA_ORDER (c->h,data,1);
}
void HASH_TRANSFORM(HASH_CTX *c, const uint8_t *data) {
HASH_BLOCK_DATA_ORDER(c->h, data, 1);
}
int HASH_FINAL (uint8_t *md, HASH_CTX *c)
{
uint8_t *p = (uint8_t *)c->data;
size_t n = c->num;
int HASH_FINAL(uint8_t *md, HASH_CTX *c) {
/* |c->data| always has room for at least one byte. A full block would have
* been consumed. */
size_t n = c->num;
assert(n < HASH_CBLOCK);
c->data[n] = 0x80;
n++;
p[n] = 0x80; /* there is always room for one */
n++;
/* Fill the block with zeros if there isn't room for a 64-bit length. */
if (n > (HASH_CBLOCK - 8)) {
memset(c->data + n, 0, HASH_CBLOCK - n);
n = 0;
HASH_BLOCK_DATA_ORDER(c->h, c->data, 1);
}
memset(c->data + n, 0, HASH_CBLOCK - 8 - n);
if (n > (HASH_CBLOCK-8))
{
memset (p+n,0,HASH_CBLOCK-n);
n=0;
HASH_BLOCK_DATA_ORDER (c->h,p,1);
}
memset (p+n,0,HASH_CBLOCK-8-n);
p += HASH_CBLOCK-8;
#if defined(DATA_ORDER_IS_BIG_ENDIAN)
(void)HOST_l2c(c->Nh,p);
(void)HOST_l2c(c->Nl,p);
/* Append a 64-bit length to the block and process it. */
uint8_t *p = c->data + HASH_CBLOCK - 8;
#if defined(DATA_ORDER_IS_BIG_ENDIAN)
HOST_l2c(c->Nh, p);
HOST_l2c(c->Nl, p);
#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
(void)HOST_l2c(c->Nl,p);
(void)HOST_l2c(c->Nh,p);
HOST_l2c(c->Nl, p);
HOST_l2c(c->Nh, p);
#endif
p -= HASH_CBLOCK;
HASH_BLOCK_DATA_ORDER (c->h,p,1);
c->num=0;
memset (p,0,HASH_CBLOCK);
assert(p == c->data + HASH_CBLOCK);
HASH_BLOCK_DATA_ORDER(c->h, c->data, 1);
c->num = 0;
memset(c->data, 0, HASH_CBLOCK);
#ifndef HASH_MAKE_STRING
#error "HASH_MAKE_STRING must be defined!"
#else
HASH_MAKE_STRING(c,md);
#endif
return 1;
}
HASH_MAKE_STRING(c, md);
return 1;
}
#if defined(__cplusplus)
} /* extern C */
} /* extern C */
#endif
#endif /* OPENSSL_HEADER_MD32_COMMON_H */
#endif /* OPENSSL_HEADER_MD32_COMMON_H */
+9 -14
View File
@@ -98,12 +98,7 @@ DSA *DSA_new(void) {
dsa->references = 1;
CRYPTO_MUTEX_init(&dsa->method_mont_p_lock);
if (!CRYPTO_new_ex_data(&g_ex_data_class, dsa, &dsa->ex_data)) {
CRYPTO_MUTEX_cleanup(&dsa->method_mont_p_lock);
OPENSSL_free(dsa);
return NULL;
}
CRYPTO_new_ex_data(&dsa->ex_data);
return dsa;
}
@@ -541,10 +536,6 @@ redo:
goto err;
}
ret = DSA_SIG_new();
if (ret == NULL) {
goto err;
}
/* Redo if r or s is zero as required by FIPS 186-3: this is
* very unlikely. */
if (BN_is_zero(r) || BN_is_zero(s)) {
@@ -554,11 +545,15 @@ redo:
}
goto redo;
}
ret = DSA_SIG_new();
if (ret == NULL) {
goto err;
}
ret->r = r;
ret->s = s;
err:
if (!ret) {
if (ret == NULL) {
OPENSSL_PUT_ERROR(DSA, reason);
BN_free(r);
BN_free(s);
@@ -864,11 +859,11 @@ err:
return ret;
}
int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
int index;
if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, new_func,
dup_func, free_func)) {
if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func,
free_func)) {
return -1;
}
return index;
-241
View File
@@ -67,10 +67,6 @@ $code.=<<___;
.Lpoly:
.quad 0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001
# 2^512 mod P precomputed for NIST P256 polynomial
.LRR:
.quad 0x0000000000000003, 0xfffffffbffffffff, 0xfffffffffffffffe, 0x00000004fffffffd
.LOne:
.long 1,1,1,1,1,1,1,1
.LTwo:
@@ -91,7 +87,6 @@ my ($r_ptr,$a_ptr,$b_ptr)=("%rdi","%rsi","%rdx");
$code.=<<___;
.globl ecp_nistz256_mul_by_2
.type ecp_nistz256_mul_by_2,\@function,2
.align 64
ecp_nistz256_mul_by_2:
@@ -133,224 +128,6 @@ ecp_nistz256_mul_by_2:
ret
.size ecp_nistz256_mul_by_2,.-ecp_nistz256_mul_by_2
################################################################################
# void ecp_nistz256_div_by_2(uint64_t res[4], uint64_t a[4]);
.globl ecp_nistz256_div_by_2
.type ecp_nistz256_div_by_2,\@function,2
.align 32
ecp_nistz256_div_by_2:
push %r12
push %r13
mov 8*0($a_ptr), $a0
mov 8*1($a_ptr), $a1
mov 8*2($a_ptr), $a2
mov $a0, $t0
mov 8*3($a_ptr), $a3
lea .Lpoly(%rip), $a_ptr
mov $a1, $t1
xor $t4, $t4
add 8*0($a_ptr), $a0
mov $a2, $t2
adc 8*1($a_ptr), $a1
adc 8*2($a_ptr), $a2
mov $a3, $t3
adc 8*3($a_ptr), $a3
adc \$0, $t4
xor $a_ptr, $a_ptr # borrow $a_ptr
test \$1, $t0
cmovz $t0, $a0
cmovz $t1, $a1
cmovz $t2, $a2
cmovz $t3, $a3
cmovz $a_ptr, $t4
mov $a1, $t0 # a0:a3>>1
shr \$1, $a0
shl \$63, $t0
mov $a2, $t1
shr \$1, $a1
or $t0, $a0
shl \$63, $t1
mov $a3, $t2
shr \$1, $a2
or $t1, $a1
shl \$63, $t2
shr \$1, $a3
shl \$63, $t4
or $t2, $a2
or $t4, $a3
mov $a0, 8*0($r_ptr)
mov $a1, 8*1($r_ptr)
mov $a2, 8*2($r_ptr)
mov $a3, 8*3($r_ptr)
pop %r13
pop %r12
ret
.size ecp_nistz256_div_by_2,.-ecp_nistz256_div_by_2
################################################################################
# void ecp_nistz256_mul_by_3(uint64_t res[4], uint64_t a[4]);
.globl ecp_nistz256_mul_by_3
.type ecp_nistz256_mul_by_3,\@function,2
.align 32
ecp_nistz256_mul_by_3:
push %r12
push %r13
mov 8*0($a_ptr), $a0
xor $t4, $t4
mov 8*1($a_ptr), $a1
add $a0, $a0 # a0:a3+a0:a3
mov 8*2($a_ptr), $a2
adc $a1, $a1
mov 8*3($a_ptr), $a3
mov $a0, $t0
adc $a2, $a2
adc $a3, $a3
mov $a1, $t1
adc \$0, $t4
sub \$-1, $a0
mov $a2, $t2
sbb .Lpoly+8*1(%rip), $a1
sbb \$0, $a2
mov $a3, $t3
sbb .Lpoly+8*3(%rip), $a3
test $t4, $t4
cmovz $t0, $a0
cmovz $t1, $a1
cmovz $t2, $a2
cmovz $t3, $a3
xor $t4, $t4
add 8*0($a_ptr), $a0 # a0:a3+=a_ptr[0:3]
adc 8*1($a_ptr), $a1
mov $a0, $t0
adc 8*2($a_ptr), $a2
adc 8*3($a_ptr), $a3
mov $a1, $t1
adc \$0, $t4
sub \$-1, $a0
mov $a2, $t2
sbb .Lpoly+8*1(%rip), $a1
sbb \$0, $a2
mov $a3, $t3
sbb .Lpoly+8*3(%rip), $a3
test $t4, $t4
cmovz $t0, $a0
cmovz $t1, $a1
mov $a0, 8*0($r_ptr)
cmovz $t2, $a2
mov $a1, 8*1($r_ptr)
cmovz $t3, $a3
mov $a2, 8*2($r_ptr)
mov $a3, 8*3($r_ptr)
pop %r13
pop %r12
ret
.size ecp_nistz256_mul_by_3,.-ecp_nistz256_mul_by_3
################################################################################
# void ecp_nistz256_add(uint64_t res[4], uint64_t a[4], uint64_t b[4]);
.globl ecp_nistz256_add
.type ecp_nistz256_add,\@function,3
.align 32
ecp_nistz256_add:
push %r12
push %r13
mov 8*0($a_ptr), $a0
xor $t4, $t4
mov 8*1($a_ptr), $a1
mov 8*2($a_ptr), $a2
mov 8*3($a_ptr), $a3
lea .Lpoly(%rip), $a_ptr
add 8*0($b_ptr), $a0
adc 8*1($b_ptr), $a1
mov $a0, $t0
adc 8*2($b_ptr), $a2
adc 8*3($b_ptr), $a3
mov $a1, $t1
adc \$0, $t4
sub 8*0($a_ptr), $a0
mov $a2, $t2
sbb 8*1($a_ptr), $a1
sbb 8*2($a_ptr), $a2
mov $a3, $t3
sbb 8*3($a_ptr), $a3
test $t4, $t4
cmovz $t0, $a0
cmovz $t1, $a1
mov $a0, 8*0($r_ptr)
cmovz $t2, $a2
mov $a1, 8*1($r_ptr)
cmovz $t3, $a3
mov $a2, 8*2($r_ptr)
mov $a3, 8*3($r_ptr)
pop %r13
pop %r12
ret
.size ecp_nistz256_add,.-ecp_nistz256_add
################################################################################
# void ecp_nistz256_sub(uint64_t res[4], uint64_t a[4], uint64_t b[4]);
.globl ecp_nistz256_sub
.type ecp_nistz256_sub,\@function,3
.align 32
ecp_nistz256_sub:
push %r12
push %r13
mov 8*0($a_ptr), $a0
xor $t4, $t4
mov 8*1($a_ptr), $a1
mov 8*2($a_ptr), $a2
mov 8*3($a_ptr), $a3
lea .Lpoly(%rip), $a_ptr
sub 8*0($b_ptr), $a0
sbb 8*1($b_ptr), $a1
mov $a0, $t0
sbb 8*2($b_ptr), $a2
sbb 8*3($b_ptr), $a3
mov $a1, $t1
sbb \$0, $t4
add 8*0($a_ptr), $a0
mov $a2, $t2
adc 8*1($a_ptr), $a1
adc 8*2($a_ptr), $a2
mov $a3, $t3
adc 8*3($a_ptr), $a3
test $t4, $t4
cmovz $t0, $a0
cmovz $t1, $a1
mov $a0, 8*0($r_ptr)
cmovz $t2, $a2
mov $a1, 8*1($r_ptr)
cmovz $t3, $a3
mov $a2, 8*2($r_ptr)
mov $a3, 8*3($r_ptr)
pop %r13
pop %r12
ret
.size ecp_nistz256_sub,.-ecp_nistz256_sub
################################################################################
# void ecp_nistz256_neg(uint64_t res[4], uint64_t a[4]);
.globl ecp_nistz256_neg
@@ -405,24 +182,6 @@ my ($t0,$t1,$t2,$t3,$t4)=("%rcx","%rbp","%rbx","%rdx","%rax");
my ($poly1,$poly3)=($acc6,$acc7);
$code.=<<___;
################################################################################
# void ecp_nistz256_to_mont(
# uint64_t res[4],
# uint64_t in[4]);
.globl ecp_nistz256_to_mont
.type ecp_nistz256_to_mont,\@function,2
.align 32
ecp_nistz256_to_mont:
___
$code.=<<___ if ($addx);
mov \$0x80100, %ecx
and OPENSSL_ia32cap_P+8(%rip), %ecx
___
$code.=<<___;
lea .LRR(%rip), $b_org
jmp .Lmul_mont
.size ecp_nistz256_to_mont,.-ecp_nistz256_to_mont
################################################################################
# void ecp_nistz256_mul_mont(
# uint64_t res[4],
+19 -50
View File
@@ -525,8 +525,6 @@ void EC_GROUP_free(EC_GROUP *group) {
group->meth->group_finish(group);
}
ec_pre_comp_free(group->pre_comp);
EC_POINT_free(group->generator);
BN_free(&group->order);
BN_free(&group->cofactor);
@@ -547,8 +545,6 @@ int ec_group_copy(EC_GROUP *dest, const EC_GROUP *src) {
return 1;
}
ec_pre_comp_free(dest->pre_comp);
dest->pre_comp = ec_pre_comp_dup(src->pre_comp);
dest->mont_data = src->mont_data;
if (src->generator != NULL) {
@@ -617,12 +613,16 @@ const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) {
return group->generator;
}
const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group) {
assert(!BN_is_zero(&group->order));
return &group->order;
}
int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) {
if (!BN_copy(order, &group->order)) {
if (BN_copy(order, EC_GROUP_get0_order(group)) == NULL) {
return 0;
}
return !BN_is_zero(order);
return 1;
}
int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
@@ -645,21 +645,6 @@ unsigned EC_GROUP_get_degree(const EC_GROUP *group) {
return ec_GFp_simple_group_get_degree(group);
}
int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) {
if (group->meth->precompute_mult != NULL) {
return group->meth->precompute_mult(group, ctx);
}
return 1; /* nothing to do, so report success */
}
int EC_GROUP_have_precompute_mult(const EC_GROUP *group) {
if (group->pre_comp != NULL) {
return 1;
}
return 0;
}
EC_POINT *EC_POINT_new(const EC_GROUP *group) {
EC_POINT *ret;
@@ -856,39 +841,23 @@ int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) {
}
int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx) {
/* just a convenient interface to EC_POINTs_mul() */
const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx) {
/* Previously, this function set |r| to the point at infinity if there was
* nothing to multiply. But, nobody should be calling this function with
* nothing to multiply in the first place. */
if ((g_scalar == NULL && p_scalar == NULL) ||
((p == NULL) != (p_scalar == NULL))) {
OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
const EC_POINT *points[1];
const BIGNUM *scalars[1];
points[0] = point;
scalars[0] = p_scalar;
return EC_POINTs_mul(group, r, g_scalar, (point != NULL && p_scalar != NULL),
points, scalars, ctx);
}
int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
BN_CTX *ctx) {
if (group->meth != r->meth) {
if (group->meth != r->meth ||
(p != NULL && group->meth != p->meth)) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
size_t i;
for (i = 0; i < num; i++) {
if (points[i]->meth != r->meth) {
break;
}
}
if (i != num) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
return group->meth->mul(group, r, g_scalar, p, p_scalar, ctx);
}
int ec_point_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
+5
View File
@@ -329,6 +329,11 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const uint8_t **inp, long len) {
goto err;
}
if (BN_cmp(ret->priv_key, EC_GROUP_get0_order(ret->group)) >= 0) {
OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER);
goto err;
}
EC_POINT_free(ret->pub_key);
ret->pub_key = EC_POINT_new(ret->group);
if (ret->pub_key == NULL) {
+37 -58
View File
@@ -104,24 +104,18 @@ EC_KEY *EC_KEY_new_method(const ENGINE *engine) {
ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
ret->references = 1;
if (!CRYPTO_new_ex_data(&g_ex_data_class, ret, &ret->ex_data)) {
goto err1;
}
CRYPTO_new_ex_data(&ret->ex_data);
if (ret->ecdsa_meth && ret->ecdsa_meth->init && !ret->ecdsa_meth->init(ret)) {
goto err2;
CRYPTO_free_ex_data(&g_ex_data_class, ret, &ret->ex_data);
if (ret->ecdsa_meth) {
METHOD_unref(ret->ecdsa_meth);
}
OPENSSL_free(ret);
return NULL;
}
return ret;
err2:
CRYPTO_free_ex_data(&g_ex_data_class, ret, &ret->ex_data);
err1:
if (ret->ecdsa_meth) {
METHOD_unref(ret->ecdsa_meth);
}
OPENSSL_free(ret);
return NULL;
}
EC_KEY *EC_KEY_new_by_curve_name(int nid) {
@@ -249,7 +243,15 @@ int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group) {
/* TODO(fork): duplicating the group seems wasteful but see
* |EC_KEY_set_conv_form|. */
key->group = EC_GROUP_dup(group);
return (key->group == NULL) ? 0 : 1;
if (key->group == NULL) {
return 0;
}
/* XXX: |BN_cmp| is not constant time. */
if (key->priv_key != NULL &&
BN_cmp(key->priv_key, EC_GROUP_get0_order(group)) >= 0) {
return 0;
}
return 1;
}
const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key) {
@@ -257,6 +259,12 @@ const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key) {
}
int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) {
/* XXX: |BN_cmp| is not constant time. */
if (key->group != NULL &&
BN_cmp(priv_key, EC_GROUP_get0_order(key->group)) >= 0) {
OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER);
return 0;
}
BN_clear_free(key->priv_key);
key->priv_key = BN_dup(priv_key);
return (key->priv_key == NULL) ? 0 : 1;
@@ -286,17 +294,9 @@ void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform) {
key->conv_form = cform;
}
int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx) {
if (key->group == NULL) {
return 0;
}
return EC_GROUP_precompute_mult(key->group, ctx);
}
int EC_KEY_check_key(const EC_KEY *eckey) {
int ok = 0;
BN_CTX *ctx = NULL;
const BIGNUM *order = NULL;
EC_POINT *point = NULL;
if (!eckey || !eckey->group || !eckey->pub_key) {
@@ -310,10 +310,8 @@ int EC_KEY_check_key(const EC_KEY *eckey) {
}
ctx = BN_CTX_new();
point = EC_POINT_new(eckey->group);
if (ctx == NULL ||
point == NULL) {
if (ctx == NULL) {
goto err;
}
@@ -322,19 +320,11 @@ int EC_KEY_check_key(const EC_KEY *eckey) {
OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE);
goto err;
}
/* testing whether pub_key * order is the point at infinity */
/* TODO(fork): can this be skipped if the cofactor is one or if we're about
* to check the private key, below? */
order = &eckey->group->order;
if (BN_is_zero(order)) {
OPENSSL_PUT_ERROR(EC, EC_R_INVALID_GROUP_ORDER);
goto err;
}
if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) {
OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
goto err;
}
if (!EC_POINT_is_at_infinity(eckey->group, point)) {
if (eckey->group->meth->check_pub_key_order != NULL &&
!eckey->group->meth->check_pub_key_order(eckey->group, eckey->pub_key,
ctx)) {
OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER);
goto err;
}
@@ -342,11 +332,14 @@ int EC_KEY_check_key(const EC_KEY *eckey) {
* check if generator * priv_key == pub_key
*/
if (eckey->priv_key) {
if (BN_cmp(eckey->priv_key, order) >= 0) {
/* XXX: |BN_cmp| is not constant time. */
if (BN_cmp(eckey->priv_key, EC_GROUP_get0_order(eckey->group)) >= 0) {
OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER);
goto err;
}
if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, NULL, NULL, ctx)) {
point = EC_POINT_new(eckey->group);
if (point == NULL ||
!EC_POINT_mul(eckey->group, point, eckey->priv_key, NULL, NULL, ctx)) {
OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
goto err;
}
@@ -415,8 +408,7 @@ err:
int EC_KEY_generate_key(EC_KEY *eckey) {
int ok = 0;
BN_CTX *ctx = NULL;
BIGNUM *priv_key = NULL, *order = NULL;
BIGNUM *priv_key = NULL;
EC_POINT *pub_key = NULL;
if (!eckey || !eckey->group) {
@@ -424,14 +416,6 @@ int EC_KEY_generate_key(EC_KEY *eckey) {
return 0;
}
order = BN_new();
ctx = BN_CTX_new();
if (order == NULL ||
ctx == NULL) {
goto err;
}
if (eckey->priv_key == NULL) {
priv_key = BN_new();
if (priv_key == NULL) {
@@ -441,10 +425,7 @@ int EC_KEY_generate_key(EC_KEY *eckey) {
priv_key = eckey->priv_key;
}
if (!EC_GROUP_get_order(eckey->group, order, ctx)) {
goto err;
}
const BIGNUM *order = EC_GROUP_get0_order(eckey->group);
do {
if (!BN_rand_range(priv_key, order)) {
goto err;
@@ -460,7 +441,7 @@ int EC_KEY_generate_key(EC_KEY *eckey) {
pub_key = eckey->pub_key;
}
if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx)) {
if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, NULL)) {
goto err;
}
@@ -470,23 +451,21 @@ int EC_KEY_generate_key(EC_KEY *eckey) {
ok = 1;
err:
BN_free(order);
if (eckey->pub_key == NULL) {
EC_POINT_free(pub_key);
}
if (eckey->priv_key == NULL) {
BN_free(priv_key);
}
BN_CTX_free(ctx);
return ok;
}
int EC_KEY_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
int EC_KEY_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
CRYPTO_EX_dup *dup_func,
CRYPTO_EX_free *free_func) {
int index;
if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, new_func,
dup_func, free_func)) {
if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func,
free_func)) {
return -1;
}
return index;
+40 -18
View File
@@ -74,24 +74,6 @@
#include "internal.h"
const EC_METHOD *EC_GFp_mont_method(void) {
static const EC_METHOD ret = {ec_GFp_mont_group_init,
ec_GFp_mont_group_finish,
ec_GFp_mont_group_clear_finish,
ec_GFp_mont_group_copy,
ec_GFp_mont_group_set_curve,
ec_GFp_simple_point_get_affine_coordinates,
ec_wNAF_mul /* XXX: Not constant time. */,
ec_wNAF_precompute_mult,
ec_GFp_mont_field_mul,
ec_GFp_mont_field_sqr,
ec_GFp_mont_field_encode,
ec_GFp_mont_field_decode,
ec_GFp_mont_field_set_to_one};
return &ret;
}
int ec_GFp_mont_group_init(EC_GROUP *group) {
int ok;
@@ -256,3 +238,43 @@ int ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r,
}
return 1;
}
static int ec_GFp_mont_check_pub_key_order(const EC_GROUP *group,
const EC_POINT* pub_key,
BN_CTX *ctx) {
EC_POINT *point = EC_POINT_new(group);
int ret = 0;
if (point == NULL ||
!ec_wNAF_mul(group, point, NULL, pub_key, EC_GROUP_get0_order(group),
ctx) ||
!EC_POINT_is_at_infinity(group, point)) {
goto err;
}
ret = 1;
err:
EC_POINT_free(point);
return ret;
}
const EC_METHOD *EC_GFp_mont_method(void) {
static const EC_METHOD ret = {
ec_GFp_mont_group_init,
ec_GFp_mont_group_finish,
ec_GFp_mont_group_clear_finish,
ec_GFp_mont_group_copy,
ec_GFp_mont_group_set_curve,
ec_GFp_simple_point_get_affine_coordinates,
ec_wNAF_mul /* XXX: Not constant time. */,
ec_GFp_mont_check_pub_key_order,
ec_GFp_mont_field_mul,
ec_GFp_mont_field_sqr,
ec_GFp_mont_field_encode,
ec_GFp_mont_field_decode,
ec_GFp_mont_field_set_to_one,
};
return &ret;
}
+18 -16
View File
@@ -95,13 +95,22 @@ struct ec_method_st {
int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_POINT *,
BIGNUM *x, BIGNUM *y, BN_CTX *);
/* used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult,
* EC_POINT_have_precompute_mult
* (default implementations are used if the 'mul' pointer is 0): */
int (*mul)(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
BN_CTX *);
int (*precompute_mult)(EC_GROUP *group, BN_CTX *);
/* Computes |r = g_scalar*generator + p_scalar*p| if |g_scalar| and |p_scalar|
* are both non-null. Computes |r = g_scalar*generator| if |p_scalar| is null.
* Computes |r = p_scalar*p| if g_scalar is null. At least one of |g_scalar|
* and |p_scalar| must be non-null, and |p| must be non-null if |p_scalar| is
* non-null. */
int (*mul)(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx);
/* |check_pub_key_order| checks that the public key is in the proper subgroup
* by checking that |pub_key*group->order| is the point at infinity. This may
* be NULL for |EC_METHOD|s specialized for prime-order curves (i.e. with
* cofactor one), as this check is not necessary for such curves (See section
* A.3 of the NSA's "Suite B Implementer's Guide to FIPS 186-3
* (ECDSA)"). */
int (*check_pub_key_order)(const EC_GROUP *group, const EC_POINT *pub_key,
BN_CTX *ctx);
/* internal functions */
@@ -121,10 +130,6 @@ struct ec_method_st {
const EC_METHOD* EC_GFp_mont_method(void);
struct ec_pre_comp_st;
void ec_pre_comp_free(struct ec_pre_comp_st *pre_comp);
void *ec_pre_comp_dup(struct ec_pre_comp_st *pre_comp);
struct ec_group_st {
const EC_METHOD *meth;
@@ -133,7 +138,6 @@ struct ec_group_st {
int curve_name; /* optional NID for named curve */
struct ec_pre_comp_st *pre_comp;
const BN_MONT_CTX *mont_data; /* data for ECDSA inverse */
/* The following members are handled by the method functions,
@@ -170,10 +174,8 @@ int ec_group_copy(EC_GROUP *dest, const EC_GROUP *src);
* a built-in group. */
const BN_MONT_CTX *ec_group_get_mont_data(const EC_GROUP *group);
int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
BN_CTX *);
int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *);
int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx);
/* method functions in simple.c */
int ec_GFp_simple_group_init(EC_GROUP *);
+6 -32
View File
@@ -90,18 +90,10 @@ static size_t ec_GFp_simple_point2oct(const EC_GROUP *group,
}
if (EC_POINT_is_at_infinity(group, point)) {
/* encodes to a single 0 octet */
if (buf != NULL) {
if (len < 1) {
OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL);
return 0;
}
buf[0] = 0;
}
return 1;
OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
goto err;
}
/* ret := required output buffer length */
field_len = BN_num_bytes(&group->field);
ret =
@@ -117,7 +109,7 @@ static size_t ec_GFp_simple_point2oct(const EC_GROUP *group,
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL) {
return 0;
goto err;
}
}
@@ -193,24 +185,12 @@ static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
form = buf[0];
y_bit = form & 1;
form = form & ~1U;
if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED) &&
(form != POINT_CONVERSION_UNCOMPRESSED)) {
if ((form != POINT_CONVERSION_COMPRESSED &&
form != POINT_CONVERSION_UNCOMPRESSED) ||
(form == POINT_CONVERSION_UNCOMPRESSED && y_bit)) {
OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
return 0;
}
if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) {
OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
return 0;
}
if (form == 0) {
if (len != 1) {
OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
return 0;
}
return EC_POINT_set_to_infinity(group, point);
}
field_len = BN_num_bytes(&group->field);
enc_len =
@@ -261,12 +241,6 @@ static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
}
}
/* test required by X9.62 */
if (!EC_POINT_is_on_curve(group, point, ctx)) {
OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE);
goto err;
}
ret = 1;
err:
+23 -59
View File
@@ -106,7 +106,7 @@ static const felem_bytearray nistp224_curve_params[5] = {
* The reason for this is so that we can clock bits into four different
* locations when doing simple scalar multiplies against the base point,
* and then another four locations using the second 16 elements. */
static const felem gmul[2][16][3] = {
static const felem g_pre_comp[2][16][3] = {
{{{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
{{0x3280d6115c1d21, 0xc1d356c2112234, 0x7f321390b94a03, 0xb70e0cbd6bb4bf},
{0xd5819985007e34, 0x75a05a07476444, 0xfb4c22dfe6cd43, 0xbd376388b5f723},
@@ -937,8 +937,7 @@ static char get_bit(const felem_bytearray in, unsigned i) {
static void batch_mul(felem x_out, felem y_out, felem z_out,
const felem_bytearray scalars[],
const unsigned num_points, const u8 *g_scalar,
const int mixed, const felem pre_comp[][17][3],
const felem g_pre_comp[2][16][3]) {
const int mixed, const felem pre_comp[][17][3]) {
int i, skip;
unsigned num;
unsigned gen_mul = (g_scalar != NULL);
@@ -1122,12 +1121,16 @@ static void make_points_affine(size_t num, felem points[/*num*/][3],
(void (*)(void *, const void *))felem_contract);
}
/* Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL values
* Result is stored in r (r can equal one of the inputs). */
int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
const BIGNUM *scalar, size_t num,
const EC_POINT *points[],
const BIGNUM *scalars[], BN_CTX *ctx) {
const BIGNUM *g_scalar, const EC_POINT *p_,
const BIGNUM *p_scalar_, BN_CTX *ctx) {
/* TODO: This function used to take |points| and |scalars| as arrays of
* |num| elements. The code below should be simplified to work in terms of
* |p_| and |p_scalar_|. */
size_t num = p_ != NULL ? 1 : 0;
const EC_POINT **points = p_ != NULL ? &p_ : NULL;
BIGNUM const *const *scalars = p_ != NULL ? &p_scalar_ : NULL;
int ret = 0;
int j;
unsigned i;
@@ -1140,11 +1143,8 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
felem *tmp_felems = NULL;
felem_bytearray tmp;
unsigned num_bytes;
int have_pre_comp = 0;
size_t num_points = num;
felem x_in, y_in, z_in, x_out, y_out, z_out;
const felem(*g_pre_comp)[16][3] = NULL;
EC_POINT *generator = NULL;
const EC_POINT *p = NULL;
const BIGNUM *p_scalar = NULL;
@@ -1164,35 +1164,6 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
goto err;
}
if (scalar != NULL) {
/* try to use the standard precomputation */
g_pre_comp = &gmul[0];
generator = EC_POINT_new(group);
if (generator == NULL) {
goto err;
}
/* get the generator from precomputation */
if (!felem_to_BN(x, g_pre_comp[0][1][0]) ||
!felem_to_BN(y, g_pre_comp[0][1][1]) ||
!felem_to_BN(z, g_pre_comp[0][1][2])) {
OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
if (!ec_point_set_Jprojective_coordinates_GFp(group, generator, x, y, z,
ctx)) {
goto err;
}
if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) {
/* precomputation matches generator */
have_pre_comp = 1;
} else {
/* we don't have valid precomputation:
* treat the generator as a random point */
num_points = num_points + 1;
}
}
if (num_points > 0) {
if (num_points >= 3) {
/* unless we precompute multiples for just one or two points,
@@ -1200,7 +1171,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
mixed = 1;
}
secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray));
pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(felem));
pre_comp = OPENSSL_malloc(num_points * sizeof(felem[17][3]));
if (mixed) {
tmp_felems = OPENSSL_malloc((num_points * 17 + 1) * sizeof(felem));
}
@@ -1219,7 +1190,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
if (i == num) {
/* the generator */
p = EC_GROUP_get0_generator(group);
p_scalar = scalar;
p_scalar = g_scalar;
} else {
/* the i^th point */
p = points[i];
@@ -1227,7 +1198,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
}
if (p_scalar != NULL && p != NULL) {
/* reduce scalar to 0 <= scalar < 2^224 */
/* reduce g_scalar to 0 <= g_scalar < 2^224 */
if (BN_num_bits(p_scalar) > 224 || BN_is_negative(p_scalar)) {
/* this is an unusual input, and we don't guarantee
* constant-timeness */
@@ -1272,31 +1243,25 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
}
}
/* the scalar for the generator */
if (scalar != NULL && have_pre_comp) {
if (g_scalar != NULL) {
memset(g_secret, 0, sizeof(g_secret));
/* reduce scalar to 0 <= scalar < 2^224 */
if (BN_num_bits(scalar) > 224 || BN_is_negative(scalar)) {
/* reduce g_scalar to 0 <= g_scalar < 2^224 */
if (BN_num_bits(g_scalar) > 224 || BN_is_negative(g_scalar)) {
/* this is an unusual input, and we don't guarantee constant-timeness */
if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) {
if (!BN_nnmod(tmp_scalar, g_scalar, &group->order, ctx)) {
OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
num_bytes = BN_bn2bin(tmp_scalar, tmp);
} else {
num_bytes = BN_bn2bin(scalar, tmp);
num_bytes = BN_bn2bin(g_scalar, tmp);
}
flip_endian(g_secret, tmp, num_bytes);
/* do the multiplication with generator precomputation */
batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets,
num_points, g_secret, mixed, (const felem(*)[17][3])pre_comp,
g_pre_comp);
} else {
/* do the multiplication without generator precomputation */
batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets,
num_points, NULL, mixed, (const felem(*)[17][3])pre_comp, NULL);
}
batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets,
num_points, g_scalar != NULL ? g_secret : NULL, mixed,
(const felem(*)[17][3])pre_comp);
/* reduce the output to its unique minimal representation */
felem_contract(x_in, x_out);
@@ -1312,7 +1277,6 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
err:
BN_CTX_end(ctx);
EC_POINT_free(generator);
BN_CTX_free(new_ctx);
OPENSSL_free(secrets);
OPENSSL_free(pre_comp);
@@ -1328,7 +1292,7 @@ const EC_METHOD *EC_GFp_nistp224_method(void) {
ec_GFp_nistp224_group_set_curve,
ec_GFp_nistp224_point_get_affine_coordinates,
ec_GFp_nistp224_points_mul,
0 /* precompute_mult */,
0 /* check_pub_key_order */,
ec_GFp_simple_field_mul,
ec_GFp_simple_field_sqr,
0 /* field_encode */,
+24 -65
View File
@@ -1312,8 +1312,8 @@ static void point_add_small(smallfelem x3, smallfelem y3, smallfelem z3,
*
* Tables for other points have table[i] = iG for i in 0 .. 16. */
/* gmul is the table of precomputed base points */
static const smallfelem gmul[2][16][3] = {
/* g_pre_comp is the table of precomputed base points */
static const smallfelem g_pre_comp[2][16][3] = {
{{{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
{{0xf4a13945d898c296, 0x77037d812deb33a0, 0xf8bce6e563a440f2,
0x6b17d1f2e12c4247},
@@ -1505,8 +1505,7 @@ static char get_bit(const felem_bytearray in, int i) {
static void batch_mul(felem x_out, felem y_out, felem z_out,
const felem_bytearray scalars[],
const unsigned num_points, const u8 *g_scalar,
const int mixed, const smallfelem pre_comp[][17][3],
const smallfelem g_pre_comp[2][16][3]) {
const int mixed, const smallfelem pre_comp[][17][3]) {
int i, skip;
unsigned num, gen_mul = (g_scalar != NULL);
felem nq[3], ftmp;
@@ -1598,11 +1597,6 @@ static void batch_mul(felem x_out, felem y_out, felem z_out,
felem_assign(z_out, nq[2]);
}
/* Precomputation for the group generator. */
typedef struct {
smallfelem g_pre_comp[2][16][3];
} NISTP256_PRE_COMP;
/******************************************************************************/
/*
* OPENSSL EC_METHOD FUNCTIONS
@@ -1707,12 +1701,16 @@ static void make_points_affine(size_t num, smallfelem points[][3],
(void (*)(void *, const void *))smallfelem_assign);
}
/* Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL
* values Result is stored in r (r can equal one of the inputs). */
int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
const BIGNUM *scalar, size_t num,
const EC_POINT *points[],
const BIGNUM *scalars[], BN_CTX *ctx) {
const BIGNUM *g_scalar, const EC_POINT *p_,
const BIGNUM *p_scalar_, BN_CTX *ctx) {
/* TODO: This function used to take |points| and |scalars| as arrays of
* |num| elements. The code below should be simplified to work in terms of |p|
* and |p_scalar|. */
size_t num = p_ != NULL ? 1 : 0;
const EC_POINT **points = p_ != NULL ? &p_ : NULL;
BIGNUM const *const *scalars = p_ != NULL ? &p_scalar_ : NULL;
int ret = 0;
int j;
int mixed = 0;
@@ -1724,12 +1722,9 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
smallfelem *tmp_smallfelems = NULL;
felem_bytearray tmp;
unsigned i, num_bytes;
int have_pre_comp = 0;
size_t num_points = num;
smallfelem x_in, y_in, z_in;
felem x_out, y_out, z_out;
const smallfelem(*g_pre_comp)[16][3] = NULL;
EC_POINT *generator = NULL;
const EC_POINT *p = NULL;
const BIGNUM *p_scalar = NULL;
@@ -1748,34 +1743,6 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
goto err;
}
if (scalar != NULL) {
/* try to use the standard precomputation */
g_pre_comp = &gmul[0];
generator = EC_POINT_new(group);
if (generator == NULL) {
goto err;
}
/* get the generator from precomputation */
if (!smallfelem_to_BN(x, g_pre_comp[0][1][0]) ||
!smallfelem_to_BN(y, g_pre_comp[0][1][1]) ||
!smallfelem_to_BN(z, g_pre_comp[0][1][2])) {
OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
if (!ec_point_set_Jprojective_coordinates_GFp(group, generator, x, y, z,
ctx)) {
goto err;
}
if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) {
/* precomputation matches generator */
have_pre_comp = 1;
} else {
/* we don't have valid precomputation: treat the generator as a
* random point. */
num_points++;
}
}
if (num_points > 0) {
if (num_points >= 3) {
/* unless we precompute multiples for just one or two points,
@@ -1783,7 +1750,7 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
mixed = 1;
}
secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray));
pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(smallfelem));
pre_comp = OPENSSL_malloc(num_points * sizeof(smallfelem[17][3]));
if (mixed) {
tmp_smallfelems =
OPENSSL_malloc((num_points * 17 + 1) * sizeof(smallfelem));
@@ -1802,14 +1769,14 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
if (i == num) {
/* we didn't have a valid precomputation, so we pick the generator. */
p = EC_GROUP_get0_generator(group);
p_scalar = scalar;
p_scalar = g_scalar;
} else {
/* the i^th point */
p = points[i];
p_scalar = scalars[i];
}
if (p_scalar != NULL && p != NULL) {
/* reduce scalar to 0 <= scalar < 2^256 */
/* reduce g_scalar to 0 <= g_scalar < 2^256 */
if (BN_num_bits(p_scalar) > 256 || BN_is_negative(p_scalar)) {
/* this is an unusual input, and we don't guarantee
* constant-timeness. */
@@ -1851,32 +1818,25 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
}
}
/* the scalar for the generator */
if (scalar != NULL && have_pre_comp) {
if (g_scalar != NULL) {
memset(g_secret, 0, sizeof(g_secret));
/* reduce scalar to 0 <= scalar < 2^256 */
if (BN_num_bits(scalar) > 256 || BN_is_negative(scalar)) {
/* reduce g_scalar to 0 <= g_scalar < 2^256 */
if (BN_num_bits(g_scalar) > 256 || BN_is_negative(g_scalar)) {
/* this is an unusual input, and we don't guarantee
* constant-timeness. */
if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) {
if (!BN_nnmod(tmp_scalar, g_scalar, &group->order, ctx)) {
OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
num_bytes = BN_bn2bin(tmp_scalar, tmp);
} else {
num_bytes = BN_bn2bin(scalar, tmp);
num_bytes = BN_bn2bin(g_scalar, tmp);
}
flip_endian(g_secret, tmp, num_bytes);
/* do the multiplication with generator precomputation */
batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets,
num_points, g_secret, mixed, (const smallfelem(*)[17][3])pre_comp,
g_pre_comp);
} else {
/* do the multiplication without generator precomputation */
batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets,
num_points, NULL, mixed, (const smallfelem(*)[17][3])pre_comp,
NULL);
}
batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets,
num_points, g_scalar != NULL ? g_secret : NULL, mixed,
(const smallfelem(*)[17][3])pre_comp);
/* reduce the output to its unique minimal representation */
felem_contract(x_in, x_out);
@@ -1892,7 +1852,6 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
err:
BN_CTX_end(ctx);
EC_POINT_free(generator);
BN_CTX_free(new_ctx);
OPENSSL_free(secrets);
OPENSSL_free(pre_comp);
@@ -1908,7 +1867,7 @@ const EC_METHOD *EC_GFp_nistp256_method(void) {
ec_GFp_simple_group_copy, ec_GFp_nistp256_group_set_curve,
ec_GFp_nistp256_point_get_affine_coordinates,
ec_GFp_nistp256_points_mul,
0 /* precompute_mult */,
0 /* check_pub_key_order */,
ec_GFp_simple_field_mul, ec_GFp_simple_field_sqr,
0 /* field_encode */, 0 /* field_decode */, 0 /* field_set_to_one */
};
+205 -310
View File
@@ -22,6 +22,7 @@
#include <openssl/ec.h>
#include <assert.h>
#include <stdint.h>
#include <string.h>
@@ -37,18 +38,13 @@
#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
!defined(OPENSSL_SMALL)
#if BN_BITS2 != 64
#define TOBN(hi, lo) lo, hi
#else
#define TOBN(hi, lo) ((BN_ULONG)hi << 32 | lo)
#endif
#if defined(__GNUC__)
#define ALIGN32 __attribute((aligned(32)))
#define ALIGN(x) __attribute((aligned(x)))
#elif defined(_MSC_VER)
#define ALIGN32 __declspec(align(32))
#define ALIGN(x) __declspec(align(x))
#else
#define ALIGN32
#define ALIGN(x)
#endif
#define ALIGNPTR(p, N) ((uint8_t *)p + N - (size_t)p % N)
@@ -69,21 +65,6 @@ typedef P256_POINT_AFFINE PRECOMP256_ROW[64];
/* Functions implemented in assembly */
/* Modular mul by 2: res = 2*a mod P */
void ecp_nistz256_mul_by_2(BN_ULONG res[P256_LIMBS],
const BN_ULONG a[P256_LIMBS]);
/* Modular div by 2: res = a/2 mod P */
void ecp_nistz256_div_by_2(BN_ULONG res[P256_LIMBS],
const BN_ULONG a[P256_LIMBS]);
/* Modular mul by 3: res = 3*a mod P */
void ecp_nistz256_mul_by_3(BN_ULONG res[P256_LIMBS],
const BN_ULONG a[P256_LIMBS]);
/* Modular add: res = a+b mod P */
void ecp_nistz256_add(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS],
const BN_ULONG b[P256_LIMBS]);
/* Modular sub: res = a-b mod P */
void ecp_nistz256_sub(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS],
const BN_ULONG b[P256_LIMBS]);
/* Modular neg: res = -a mod P */
void ecp_nistz256_neg(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS]);
/* Montgomery mul: res = a*b*2^-256 mod P */
@@ -96,9 +77,6 @@ void ecp_nistz256_sqr_mont(BN_ULONG res[P256_LIMBS],
/* Convert a number from Montgomery domain, by multiplying with 1 */
void ecp_nistz256_from_mont(BN_ULONG res[P256_LIMBS],
const BN_ULONG in[P256_LIMBS]);
/* Convert a number to Montgomery domain, by multiplying with 2^512 mod P*/
void ecp_nistz256_to_mont(BN_ULONG res[P256_LIMBS],
const BN_ULONG in[P256_LIMBS]);
/* Functions that perform constant time access to the precomputed tables */
void ecp_nistz256_select_w5(P256_POINT *val, const P256_POINT *in_t, int index);
void ecp_nistz256_select_w7(P256_POINT_AFFINE *val,
@@ -153,48 +131,6 @@ static void copy_conditional(BN_ULONG dst[P256_LIMBS],
}
}
static BN_ULONG is_zero(BN_ULONG in) {
in |= (0 - in);
in = ~in;
in &= BN_MASK2;
in >>= BN_BITS2 - 1;
return in;
}
static BN_ULONG is_equal(const BN_ULONG a[P256_LIMBS],
const BN_ULONG b[P256_LIMBS]) {
BN_ULONG res;
res = a[0] ^ b[0];
res |= a[1] ^ b[1];
res |= a[2] ^ b[2];
res |= a[3] ^ b[3];
if (P256_LIMBS == 8) {
res |= a[4] ^ b[4];
res |= a[5] ^ b[5];
res |= a[6] ^ b[6];
res |= a[7] ^ b[7];
}
return is_zero(res);
}
static BN_ULONG is_one(const BN_ULONG a[P256_LIMBS]) {
BN_ULONG res;
res = a[0] ^ ONE[0];
res |= a[1] ^ ONE[1];
res |= a[2] ^ ONE[2];
res |= a[3] ^ ONE[3];
if (P256_LIMBS == 8) {
res |= a[4] ^ ONE[4];
res |= a[5] ^ ONE[5];
res |= a[6] ^ ONE[6];
}
return is_zero(res);
}
void ecp_nistz256_point_double(P256_POINT *r, const P256_POINT *a);
void ecp_nistz256_point_add(P256_POINT *r, const P256_POINT *a,
const P256_POINT *b);
@@ -296,113 +232,117 @@ static int ecp_nistz256_bignum_to_field_elem(BN_ULONG out[P256_LIMBS],
return 1;
}
/* r = sum(scalar[i]*point[i]) */
static void ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r,
const BIGNUM **scalar,
const EC_POINT **point, int num,
BN_CTX *ctx) {
/* r = p * p_scalar */
static int ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r,
const EC_POINT *p, const BIGNUM *p_scalar,
BN_CTX *ctx) {
assert(p != NULL);
assert(p_scalar != NULL);
static const unsigned kWindowSize = 5;
static const unsigned kMask = (1 << (5 /* kWindowSize */ + 1)) - 1;
void *table_storage = OPENSSL_malloc(num * 16 * sizeof(P256_POINT) + 64);
uint8_t(*p_str)[33] = OPENSSL_malloc(num * 33 * sizeof(uint8_t));
const BIGNUM **scalars = OPENSSL_malloc(num * sizeof(BIGNUM *));
/* A |P256_POINT| is (3 * 32) = 96 bytes, and the 64-byte alignment should
* add no more than 63 bytes of overhead. Thus, |table| should require
* ~1599 ((96 * 16) + 63) bytes of stack space. */
ALIGN(64) P256_POINT table[16];
uint8_t p_str[33];
if (table_storage == NULL ||
p_str == NULL ||
scalars == NULL) {
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
int ret = 0;
BN_CTX *new_ctx = NULL;
int ctx_started = 0;
if (BN_num_bits(p_scalar) > 256 || BN_is_negative(p_scalar)) {
if (ctx == NULL) {
new_ctx = BN_CTX_new();
if (new_ctx == NULL) {
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
ctx = new_ctx;
}
BN_CTX_start(ctx);
ctx_started = 1;
BIGNUM *mod = BN_CTX_get(ctx);
if (mod == NULL) {
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!BN_nnmod(mod, p_scalar, &group->order, ctx)) {
OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
p_scalar = mod;
}
int j;
for (j = 0; j < p_scalar->top * BN_BYTES; j += BN_BYTES) {
BN_ULONG d = p_scalar->d[j / BN_BYTES];
p_str[j + 0] = d & 0xff;
p_str[j + 1] = (d >> 8) & 0xff;
p_str[j + 2] = (d >> 16) & 0xff;
p_str[j + 3] = (d >>= 24) & 0xff;
if (BN_BYTES == 8) {
d >>= 8;
p_str[j + 4] = d & 0xff;
p_str[j + 5] = (d >> 8) & 0xff;
p_str[j + 6] = (d >> 16) & 0xff;
p_str[j + 7] = (d >> 24) & 0xff;
}
}
for (; j < 33; j++) {
p_str[j] = 0;
}
/* table[0] is implicitly (0,0,0) (the point at infinity), therefore it is
* not stored. All other values are actually stored with an offset of -1 in
* table. */
P256_POINT *row = table;
if (!ecp_nistz256_bignum_to_field_elem(row[1 - 1].X, &p->X) ||
!ecp_nistz256_bignum_to_field_elem(row[1 - 1].Y, &p->Y) ||
!ecp_nistz256_bignum_to_field_elem(row[1 - 1].Z, &p->Z)) {
OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE);
goto err;
}
P256_POINT(*table)[16] = (void *)ALIGNPTR(table_storage, 64);
int i;
for (i = 0; i < num; i++) {
P256_POINT *row = table[i];
if (BN_num_bits(scalar[i]) > 256 || BN_is_negative(scalar[i])) {
BIGNUM *mod = BN_CTX_get(ctx);
if (mod == NULL) {
goto err;
}
if (!BN_nnmod(mod, scalar[i], &group->order, ctx)) {
OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
scalars[i] = mod;
} else {
scalars[i] = scalar[i];
}
int j;
for (j = 0; j < scalars[i]->top * BN_BYTES; j += BN_BYTES) {
BN_ULONG d = scalars[i]->d[j / BN_BYTES];
p_str[i][j + 0] = d & 0xff;
p_str[i][j + 1] = (d >> 8) & 0xff;
p_str[i][j + 2] = (d >> 16) & 0xff;
p_str[i][j + 3] = (d >>= 24) & 0xff;
if (BN_BYTES == 8) {
d >>= 8;
p_str[i][j + 4] = d & 0xff;
p_str[i][j + 5] = (d >> 8) & 0xff;
p_str[i][j + 6] = (d >> 16) & 0xff;
p_str[i][j + 7] = (d >> 24) & 0xff;
}
}
for (; j < 33; j++) {
p_str[i][j] = 0;
}
/* table[0] is implicitly (0,0,0) (the point at infinity), therefore it is
* not stored. All other values are actually stored with an offset of -1 in
* table. */
if (!ecp_nistz256_bignum_to_field_elem(row[1 - 1].X, &point[i]->X) ||
!ecp_nistz256_bignum_to_field_elem(row[1 - 1].Y, &point[i]->Y) ||
!ecp_nistz256_bignum_to_field_elem(row[1 - 1].Z, &point[i]->Z)) {
OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE);
goto err;
}
ecp_nistz256_point_double(&row[2 - 1], &row[1 - 1]);
ecp_nistz256_point_add(&row[3 - 1], &row[2 - 1], &row[1 - 1]);
ecp_nistz256_point_double(&row[4 - 1], &row[2 - 1]);
ecp_nistz256_point_double(&row[6 - 1], &row[3 - 1]);
ecp_nistz256_point_double(&row[8 - 1], &row[4 - 1]);
ecp_nistz256_point_double(&row[12 - 1], &row[6 - 1]);
ecp_nistz256_point_add(&row[5 - 1], &row[4 - 1], &row[1 - 1]);
ecp_nistz256_point_add(&row[7 - 1], &row[6 - 1], &row[1 - 1]);
ecp_nistz256_point_add(&row[9 - 1], &row[8 - 1], &row[1 - 1]);
ecp_nistz256_point_add(&row[13 - 1], &row[12 - 1], &row[1 - 1]);
ecp_nistz256_point_double(&row[14 - 1], &row[7 - 1]);
ecp_nistz256_point_double(&row[10 - 1], &row[5 - 1]);
ecp_nistz256_point_add(&row[15 - 1], &row[14 - 1], &row[1 - 1]);
ecp_nistz256_point_add(&row[11 - 1], &row[10 - 1], &row[1 - 1]);
ecp_nistz256_point_add(&row[16 - 1], &row[15 - 1], &row[1 - 1]);
}
ecp_nistz256_point_double(&row[2 - 1], &row[1 - 1]);
ecp_nistz256_point_add(&row[3 - 1], &row[2 - 1], &row[1 - 1]);
ecp_nistz256_point_double(&row[4 - 1], &row[2 - 1]);
ecp_nistz256_point_double(&row[6 - 1], &row[3 - 1]);
ecp_nistz256_point_double(&row[8 - 1], &row[4 - 1]);
ecp_nistz256_point_double(&row[12 - 1], &row[6 - 1]);
ecp_nistz256_point_add(&row[5 - 1], &row[4 - 1], &row[1 - 1]);
ecp_nistz256_point_add(&row[7 - 1], &row[6 - 1], &row[1 - 1]);
ecp_nistz256_point_add(&row[9 - 1], &row[8 - 1], &row[1 - 1]);
ecp_nistz256_point_add(&row[13 - 1], &row[12 - 1], &row[1 - 1]);
ecp_nistz256_point_double(&row[14 - 1], &row[7 - 1]);
ecp_nistz256_point_double(&row[10 - 1], &row[5 - 1]);
ecp_nistz256_point_add(&row[15 - 1], &row[14 - 1], &row[1 - 1]);
ecp_nistz256_point_add(&row[11 - 1], &row[10 - 1], &row[1 - 1]);
ecp_nistz256_point_add(&row[16 - 1], &row[15 - 1], &row[1 - 1]);
BN_ULONG tmp[P256_LIMBS];
ALIGN32 P256_POINT h;
ALIGN(32) P256_POINT h;
unsigned index = 255;
unsigned wvalue = p_str[0][(index - 1) / 8];
unsigned wvalue = p_str[(index - 1) / 8];
wvalue = (wvalue >> ((index - 1) % 8)) & kMask;
ecp_nistz256_select_w5(r, table[0], booth_recode_w5(wvalue) >> 1);
ecp_nistz256_select_w5(r, table, booth_recode_w5(wvalue) >> 1);
while (index >= 5) {
for (i = (index == 255 ? 1 : 0); i < num; i++) {
if (index != 255) {
unsigned off = (index - 1) / 8;
wvalue = p_str[i][off] | p_str[i][off + 1] << 8;
wvalue = p_str[off] | p_str[off + 1] << 8;
wvalue = (wvalue >> ((index - 1) % 8)) & kMask;
wvalue = booth_recode_w5(wvalue);
ecp_nistz256_select_w5(&h, table[i], wvalue >> 1);
ecp_nistz256_select_w5(&h, table, wvalue >> 1);
ecp_nistz256_neg(tmp, h.Y);
copy_conditional(h.Y, tmp, (wvalue & 1));
@@ -420,217 +360,166 @@ static void ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r,
}
/* Final window */
for (i = 0; i < num; i++) {
wvalue = p_str[i][0];
wvalue = (wvalue << 1) & kMask;
wvalue = p_str[0];
wvalue = (wvalue << 1) & kMask;
wvalue = booth_recode_w5(wvalue);
wvalue = booth_recode_w5(wvalue);
ecp_nistz256_select_w5(&h, table[i], wvalue >> 1);
ecp_nistz256_select_w5(&h, table, wvalue >> 1);
ecp_nistz256_neg(tmp, h.Y);
copy_conditional(h.Y, tmp, wvalue & 1);
ecp_nistz256_neg(tmp, h.Y);
copy_conditional(h.Y, tmp, wvalue & 1);
ecp_nistz256_point_add(r, r, &h);
}
ecp_nistz256_point_add(r, r, &h);
ret = 1;
err:
OPENSSL_free(table_storage);
OPENSSL_free(p_str);
OPENSSL_free((BIGNUM**) scalars);
if (ctx_started) {
BN_CTX_end(ctx);
}
BN_CTX_free(new_ctx);
return ret;
}
/* Coordinates of G, for which we have precomputed tables */
const static BN_ULONG def_xG[P256_LIMBS] = {
TOBN(0x79e730d4, 0x18a9143c), TOBN(0x75ba95fc, 0x5fedb601),
TOBN(0x79fb732b, 0x77622510), TOBN(0x18905f76, 0xa53755c6),
};
const static BN_ULONG def_yG[P256_LIMBS] = {
TOBN(0xddf25357, 0xce95560a), TOBN(0x8b4ab8e4, 0xba19e45c),
TOBN(0xd2e88688, 0xdd21f325), TOBN(0x8571ff18, 0x25885d85)
};
/* ecp_nistz256_is_affine_G returns one if |generator| is the standard, P-256
* generator. */
static int ecp_nistz256_is_affine_G(const EC_POINT *generator) {
return (generator->X.top == P256_LIMBS) && (generator->Y.top == P256_LIMBS) &&
(generator->Z.top == (P256_LIMBS - P256_LIMBS / 8)) &&
is_equal(generator->X.d, def_xG) && is_equal(generator->Y.d, def_yG) &&
is_one(generator->Z.d);
}
/* r = scalar*G + sum(scalars[i]*points[i]) */
static int ecp_nistz256_points_mul(
const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num,
const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx) {
const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
const EC_POINT *p_, const BIGNUM *p_scalar, BN_CTX *ctx) {
assert((p_ != NULL) == (p_scalar != NULL));
static const unsigned kWindowSize = 7;
static const unsigned kMask = (1 << (7 /* kWindowSize */ + 1)) - 1;
int ret = 0, no_precomp_for_generator = 0, p_is_infinity = 0;
ALIGN32 union {
ALIGN(32) union {
P256_POINT p;
P256_POINT_AFFINE a;
} t, p;
if (scalar == NULL && num == 0) {
return EC_POINT_set_to_infinity(group, r);
}
int ret = 0;
BN_CTX *new_ctx = NULL;
int ctx_started = 0;
/* Need 256 bits for space for all coordinates. */
bn_wexpand(&r->X, P256_LIMBS);
bn_wexpand(&r->Y, P256_LIMBS);
bn_wexpand(&r->Z, P256_LIMBS);
if (bn_wexpand(&r->X, P256_LIMBS) == NULL ||
bn_wexpand(&r->Y, P256_LIMBS) == NULL ||
bn_wexpand(&r->Z, P256_LIMBS) == NULL) {
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
r->X.top = P256_LIMBS;
r->Y.top = P256_LIMBS;
r->Z.top = P256_LIMBS;
const EC_POINT *generator = NULL;
if (scalar) {
generator = EC_GROUP_get0_generator(group);
if (generator == NULL) {
OPENSSL_PUT_ERROR(EC, EC_R_UNDEFINED_GENERATOR);
goto err;
if (g_scalar != NULL) {
if (BN_num_bits(g_scalar) > 256 || BN_is_negative(g_scalar)) {
if (ctx == NULL) {
new_ctx = BN_CTX_new();
if (new_ctx == NULL) {
goto err;
}
ctx = new_ctx;
}
BN_CTX_start(ctx);
ctx_started = 1;
BIGNUM *tmp_scalar = BN_CTX_get(ctx);
if (tmp_scalar == NULL) {
goto err;
}
if (!BN_nnmod(tmp_scalar, g_scalar, &group->order, ctx)) {
OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
g_scalar = tmp_scalar;
}
if (ecp_nistz256_is_affine_G(generator)) {
if (BN_num_bits(scalar) > 256 || BN_is_negative(scalar)) {
BIGNUM *tmp_scalar = BN_CTX_get(ctx);
if (tmp_scalar == NULL) {
goto err;
}
uint8_t p_str[33] = {0};
int i;
for (i = 0; i < g_scalar->top * BN_BYTES; i += BN_BYTES) {
BN_ULONG d = g_scalar->d[i / BN_BYTES];
if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) {
OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
scalar = tmp_scalar;
p_str[i + 0] = d & 0xff;
p_str[i + 1] = (d >> 8) & 0xff;
p_str[i + 2] = (d >> 16) & 0xff;
p_str[i + 3] = (d >>= 24) & 0xff;
if (BN_BYTES == 8) {
d >>= 8;
p_str[i + 4] = d & 0xff;
p_str[i + 5] = (d >> 8) & 0xff;
p_str[i + 6] = (d >> 16) & 0xff;
p_str[i + 7] = (d >> 24) & 0xff;
}
}
uint8_t p_str[33] = {0};
int i;
for (i = 0; i < scalar->top * BN_BYTES; i += BN_BYTES) {
BN_ULONG d = scalar->d[i / BN_BYTES];
for (; i < (int) sizeof(p_str); i++) {
p_str[i] = 0;
}
p_str[i + 0] = d & 0xff;
p_str[i + 1] = (d >> 8) & 0xff;
p_str[i + 2] = (d >> 16) & 0xff;
p_str[i + 3] = (d >>= 24) & 0xff;
if (BN_BYTES == 8) {
d >>= 8;
p_str[i + 4] = d & 0xff;
p_str[i + 5] = (d >> 8) & 0xff;
p_str[i + 6] = (d >> 16) & 0xff;
p_str[i + 7] = (d >> 24) & 0xff;
}
}
/* First window */
unsigned wvalue = (p_str[0] << 1) & kMask;
unsigned index = kWindowSize;
for (; i < (int) sizeof(p_str); i++) {
p_str[i] = 0;
}
wvalue = booth_recode_w7(wvalue);
/* First window */
unsigned wvalue = (p_str[0] << 1) & kMask;
unsigned index = kWindowSize;
const PRECOMP256_ROW *const precomputed_table =
(const PRECOMP256_ROW *)ecp_nistz256_precomputed;
ecp_nistz256_select_w7(&p.a, precomputed_table[0], wvalue >> 1);
ecp_nistz256_neg(p.p.Z, p.p.Y);
copy_conditional(p.p.Y, p.p.Z, wvalue & 1);
memcpy(p.p.Z, ONE, sizeof(ONE));
for (i = 1; i < 37; i++) {
unsigned off = (index - 1) / 8;
wvalue = p_str[off] | p_str[off + 1] << 8;
wvalue = (wvalue >> ((index - 1) % 8)) & kMask;
index += kWindowSize;
wvalue = booth_recode_w7(wvalue);
const PRECOMP256_ROW *const precomputed_table =
(const PRECOMP256_ROW *)ecp_nistz256_precomputed;
ecp_nistz256_select_w7(&p.a, precomputed_table[0], wvalue >> 1);
ecp_nistz256_select_w7(&t.a, precomputed_table[i], wvalue >> 1);
ecp_nistz256_neg(p.p.Z, p.p.Y);
copy_conditional(p.p.Y, p.p.Z, wvalue & 1);
ecp_nistz256_neg(t.p.Z, t.a.Y);
copy_conditional(t.a.Y, t.p.Z, wvalue & 1);
memcpy(p.p.Z, ONE, sizeof(ONE));
for (i = 1; i < 37; i++) {
unsigned off = (index - 1) / 8;
wvalue = p_str[off] | p_str[off + 1] << 8;
wvalue = (wvalue >> ((index - 1) % 8)) & kMask;
index += kWindowSize;
wvalue = booth_recode_w7(wvalue);
ecp_nistz256_select_w7(&t.a, precomputed_table[i], wvalue >> 1);
ecp_nistz256_neg(t.p.Z, t.a.Y);
copy_conditional(t.a.Y, t.p.Z, wvalue & 1);
ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a);
}
} else {
p_is_infinity = 1;
no_precomp_for_generator = 1;
ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a);
}
} else {
p_is_infinity = 1;
}
if (no_precomp_for_generator) {
/* Without a precomputed table for the generator, it has to be handled like
* a normal point. */
const BIGNUM **new_scalars;
const EC_POINT **new_points;
/* Bound |num| so that all the possible overflows in the following can be
* excluded. */
if (0xffffff < num) {
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
return 0;
}
new_scalars = OPENSSL_malloc((num + 1) * sizeof(BIGNUM *));
if (new_scalars == NULL) {
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
return 0;
}
new_points = OPENSSL_malloc((num + 1) * sizeof(EC_POINT *));
if (new_points == NULL) {
OPENSSL_free((BIGNUM**) new_scalars);
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
return 0;
}
memcpy((BIGNUM**) new_scalars, scalars, num * sizeof(BIGNUM *));
new_scalars[num] = scalar;
memcpy((EC_POINT**) new_points, points, num * sizeof(EC_POINT *));
new_points[num] = generator;
scalars = new_scalars;
points = new_points;
num++;
}
if (num) {
const int p_is_infinity = g_scalar == NULL;
if (p_scalar != NULL) {
P256_POINT *out = &t.p;
if (p_is_infinity) {
out = &p.p;
}
ecp_nistz256_windowed_mul(group, out, scalars, points, num, ctx);
if (!ecp_nistz256_windowed_mul(group, out, p_, p_scalar, ctx)) {
goto err;
}
if (!p_is_infinity) {
ecp_nistz256_point_add(&p.p, &p.p, out);
}
}
if (no_precomp_for_generator) {
OPENSSL_free((BIGNUM **) scalars);
OPENSSL_free((EC_POINT **) points);
}
memcpy(r->X.d, p.p.X, sizeof(p.p.X));
memcpy(r->Y.d, p.p.Y, sizeof(p.p.Y));
memcpy(r->Z.d, p.p.Z, sizeof(p.p.Z));
/* Not constant-time, but we're only operating on the public output. */
bn_correct_top(&r->X);
bn_correct_top(&r->Y);
bn_correct_top(&r->Z);
r->Z_is_one = BN_is_one(&r->Z);
ret = 1;
err:
if (ctx_started) {
BN_CTX_end(ctx);
}
BN_CTX_free(new_ctx);
return ret;
}
@@ -659,7 +548,10 @@ static int ecp_nistz256_get_affine(const EC_GROUP *group, const EC_POINT *point,
ecp_nistz256_mul_mont(x_aff, z_inv2, point_x);
if (x != NULL) {
bn_wexpand(x, P256_LIMBS);
if (bn_wexpand(x, P256_LIMBS) == NULL) {
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
return 0;
}
x->top = P256_LIMBS;
ecp_nistz256_from_mont(x->d, x_aff);
bn_correct_top(x);
@@ -668,7 +560,10 @@ static int ecp_nistz256_get_affine(const EC_GROUP *group, const EC_POINT *point,
if (y != NULL) {
ecp_nistz256_mul_mont(z_inv3, z_inv3, z_inv2);
ecp_nistz256_mul_mont(y_aff, z_inv3, point_y);
bn_wexpand(y, P256_LIMBS);
if (bn_wexpand(y, P256_LIMBS) == NULL) {
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
return 0;
}
y->top = P256_LIMBS;
ecp_nistz256_from_mont(y->d, y_aff);
bn_correct_top(y);
@@ -686,7 +581,7 @@ const EC_METHOD *EC_GFp_nistz256_method(void) {
ec_GFp_mont_group_set_curve,
ecp_nistz256_get_affine,
ecp_nistz256_points_mul,
0, /* precompute_mult */
0 /* check_pub_key_order */,
ec_GFp_mont_field_mul,
ec_GFp_mont_field_sqr,
ec_GFp_mont_field_encode,
-19
View File
@@ -76,25 +76,6 @@
#include "internal.h"
const EC_METHOD *EC_GFp_simple_method(void) {
static const EC_METHOD ret = {ec_GFp_simple_group_init,
ec_GFp_simple_group_finish,
ec_GFp_simple_group_clear_finish,
ec_GFp_simple_group_copy,
ec_GFp_simple_group_set_curve,
ec_GFp_simple_point_get_affine_coordinates,
0 /* mul */,
0 /* precompute_mult */,
ec_GFp_simple_field_mul,
ec_GFp_simple_field_sqr,
0 /* field_encode */,
0 /* field_decode */,
0 /* field_set_to_one */};
return &ret;
}
/* Most method functions in this file are designed to work with non-trivial
* representations of field elements if necessary (see ecp_mont.c): while
* standard modular addition and subtraction are used, the field_mul and
+27 -426
View File
@@ -80,65 +80,8 @@
/* This file implements the wNAF-based interleaving multi-exponentation method
* (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp>);
* for multiplication with precomputation, we use wNAF splitting
* (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#fastexp>).
* */
/* structure for precomputed multiples of the generator */
typedef struct ec_pre_comp_st {
size_t blocksize; /* block size for wNAF splitting */
size_t numblocks; /* max. number of blocks for which we have precomputation */
size_t w; /* window size */
EC_POINT **points; /* array with pre-calculated multiples of generator:
* 'num' pointers to EC_POINT objects followed by a NULL */
size_t num; /* numblocks * 2^(w-1) */
CRYPTO_refcount_t references;
} EC_PRE_COMP;
static EC_PRE_COMP *ec_pre_comp_new(void) {
EC_PRE_COMP *ret = NULL;
ret = (EC_PRE_COMP *)OPENSSL_malloc(sizeof(EC_PRE_COMP));
if (!ret) {
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
return ret;
}
ret->blocksize = 8; /* default */
ret->numblocks = 0;
ret->w = 4; /* default */
ret->points = NULL;
ret->num = 0;
ret->references = 1;
return ret;
}
void *ec_pre_comp_dup(EC_PRE_COMP *pre_comp) {
if (pre_comp == NULL) {
return NULL;
}
CRYPTO_refcount_inc(&pre_comp->references);
return pre_comp;
}
void ec_pre_comp_free(EC_PRE_COMP *pre_comp) {
if (pre_comp == NULL ||
!CRYPTO_refcount_dec_and_test_zero(&pre_comp->references)) {
return;
}
if (pre_comp->points) {
EC_POINT **p;
for (p = pre_comp->points; *p != NULL; p++) {
EC_POINT_free(*p);
}
OPENSSL_free(pre_comp->points);
}
OPENSSL_free(pre_comp);
}
/* Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'.
* This is an array r[] of values that are either zero or odd with an
* absolute value less than 2^w satisfying
@@ -281,21 +224,12 @@ err:
? 2 \
: 1))
/* Compute
* \sum scalars[i]*points[i],
* also including
* scalar*generator
* in the addition if scalar != NULL
*/
int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
BN_CTX *ctx) {
int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx) {
BN_CTX *new_ctx = NULL;
const EC_POINT *generator = NULL;
EC_POINT *tmp = NULL;
size_t totalnum;
size_t blocksize = 0, numblocks = 0; /* for wNAF splitting */
size_t pre_points_per_block = 0;
size_t total_num;
size_t i, j;
int k;
int r_is_inverted = 0;
@@ -307,30 +241,9 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
size_t num_val;
EC_POINT **val = NULL; /* precomputation */
EC_POINT **v;
EC_POINT ***val_sub =
NULL; /* pointers to sub-arrays of 'val' or 'pre_comp->points' */
const EC_PRE_COMP *pre_comp = NULL;
int num_scalar = 0; /* flag: will be set to 1 if 'scalar' must be treated like
* other scalars,
* i.e. precomputation is not available */
EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' */
int ret = 0;
if (group->meth != r->meth) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
if ((scalar == NULL) && (num == 0)) {
return EC_POINT_set_to_infinity(group, r);
}
for (i = 0; i < num; i++) {
if (group->meth != points[i]->meth) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
}
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL) {
@@ -338,52 +251,31 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
}
}
if (scalar != NULL) {
/* TODO: This function used to take |points| and |scalars| as arrays of
* |num| elements. The code below should be simplified to work in terms of |p|
* and |p_scalar|. */
size_t num = p != NULL ? 1 : 0;
const EC_POINT **points = p != NULL ? &p : NULL;
const BIGNUM **scalars = p != NULL ? &p_scalar : NULL;
total_num = num;
if (g_scalar != NULL) {
generator = EC_GROUP_get0_generator(group);
if (generator == NULL) {
OPENSSL_PUT_ERROR(EC, EC_R_UNDEFINED_GENERATOR);
goto err;
}
/* look if we can use precomputed multiples of generator */
pre_comp = group->pre_comp;
if (pre_comp && pre_comp->numblocks &&
(EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) == 0)) {
blocksize = pre_comp->blocksize;
/* determine maximum number of blocks that wNAF splitting may yield
* (NB: maximum wNAF length is bit length plus one) */
numblocks = (BN_num_bits(scalar) / blocksize) + 1;
/* we cannot use more blocks than we have precomputation for */
if (numblocks > pre_comp->numblocks) {
numblocks = pre_comp->numblocks;
}
pre_points_per_block = (size_t)1 << (pre_comp->w - 1);
/* check that pre_comp looks sane */
if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block)) {
OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
} else {
/* can't use precomputation */
pre_comp = NULL;
numblocks = 1;
num_scalar = 1; /* treat 'scalar' like 'num'-th element of 'scalars' */
}
++total_num; /* treat 'g_scalar' like 'num'-th element of 'scalars' */
}
totalnum = num + numblocks;
wsize = OPENSSL_malloc(totalnum * sizeof wsize[0]);
wNAF_len = OPENSSL_malloc(totalnum * sizeof wNAF_len[0]);
wNAF = OPENSSL_malloc((totalnum + 1) *
wsize = OPENSSL_malloc(total_num * sizeof wsize[0]);
wNAF_len = OPENSSL_malloc(total_num * sizeof wNAF_len[0]);
wNAF = OPENSSL_malloc((total_num + 1) *
sizeof wNAF[0]); /* includes space for pivot */
val_sub = OPENSSL_malloc(totalnum * sizeof val_sub[0]);
val_sub = OPENSSL_malloc(total_num * sizeof val_sub[0]);
/* Ensure wNAF is initialised in case we end up going to err. */
if (wNAF) {
@@ -398,15 +290,15 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
/* num_val will be the total number of temporarily precomputed points */
num_val = 0;
for (i = 0; i < num + num_scalar; i++) {
for (i = 0; i < total_num; i++) {
size_t bits;
bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar);
bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(g_scalar);
wsize[i] = EC_window_bits_for_scalar_size(bits);
num_val += (size_t)1 << (wsize[i] - 1);
wNAF[i + 1] = NULL; /* make sure we always have a pivot */
wNAF[i] =
compute_wNAF((i < num ? scalars[i] : scalar), wsize[i], &wNAF_len[i]);
compute_wNAF((i < num ? scalars[i] : g_scalar), wsize[i], &wNAF_len[i]);
if (wNAF[i] == NULL) {
goto err;
}
@@ -415,110 +307,8 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
}
}
if (numblocks) {
/* we go here iff scalar != NULL */
if (pre_comp == NULL) {
if (num_scalar != 1) {
OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
/* we have already generated a wNAF for 'scalar' */
} else {
signed char *tmp_wNAF = NULL;
size_t tmp_len = 0;
if (num_scalar != 0) {
OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
/* use the window size for which we have precomputation */
wsize[num] = pre_comp->w;
tmp_wNAF = compute_wNAF(scalar, wsize[num], &tmp_len);
if (!tmp_wNAF) {
goto err;
}
if (tmp_len <= max_len) {
/* One of the other wNAFs is at least as long
* as the wNAF belonging to the generator,
* so wNAF splitting will not buy us anything. */
numblocks = 1; /* don't use wNAF splitting */
totalnum = num + numblocks;
wNAF[num] = tmp_wNAF;
wNAF[num + 1] = NULL;
wNAF_len[num] = tmp_len;
/* pre_comp->points starts with the points that we need here: */
val_sub[num] = pre_comp->points;
} else {
/* don't include tmp_wNAF directly into wNAF array
* - use wNAF splitting and include the blocks */
signed char *pp;
EC_POINT **tmp_points;
if (tmp_len < numblocks * blocksize) {
/* possibly we can do with fewer blocks than estimated */
numblocks = (tmp_len + blocksize - 1) / blocksize;
if (numblocks > pre_comp->numblocks) {
OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
OPENSSL_free(tmp_wNAF);
goto err;
}
totalnum = num + numblocks;
}
/* split wNAF in 'numblocks' parts */
pp = tmp_wNAF;
tmp_points = pre_comp->points;
for (i = num; i < totalnum; i++) {
if (i < totalnum - 1) {
wNAF_len[i] = blocksize;
if (tmp_len < blocksize) {
OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
OPENSSL_free(tmp_wNAF);
goto err;
}
tmp_len -= blocksize;
} else {
/* last block gets whatever is left
* (this could be more or less than 'blocksize'!) */
wNAF_len[i] = tmp_len;
}
wNAF[i + 1] = NULL;
wNAF[i] = OPENSSL_malloc(wNAF_len[i]);
if (wNAF[i] == NULL) {
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
OPENSSL_free(tmp_wNAF);
goto err;
}
memcpy(wNAF[i], pp, wNAF_len[i]);
if (wNAF_len[i] > max_len) {
max_len = wNAF_len[i];
}
if (*tmp_points == NULL) {
OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
OPENSSL_free(tmp_wNAF);
goto err;
}
val_sub[i] = tmp_points;
tmp_points += pre_points_per_block;
pp += blocksize;
}
OPENSSL_free(tmp_wNAF);
}
}
}
/* All points we precompute now go into a single array 'val'.
* 'val_sub[i]' is a pointer to the subarray for the i-th point,
* or to a subarray of 'pre_comp->points' if we already have precomputation.
*/
/* All points we precompute now go into a single array 'val'. 'val_sub[i]' is
* a pointer to the subarray for the i-th point. */
val = OPENSSL_malloc((num_val + 1) * sizeof val[0]);
if (val == NULL) {
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
@@ -528,7 +318,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
/* allocate points for precomputation */
v = val;
for (i = 0; i < num + num_scalar; i++) {
for (i = 0; i < total_num; i++) {
val_sub[i] = v;
for (j = 0; j < ((size_t)1 << (wsize[i] - 1)); j++) {
*v = EC_POINT_new(group);
@@ -553,7 +343,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
* val_sub[i][2] := 5 * points[i]
* ...
*/
for (i = 0; i < num + num_scalar; i++) {
for (i = 0; i < total_num; i++) {
if (i < num) {
if (!EC_POINT_copy(val_sub[i][0], points[i])) {
goto err;
@@ -587,7 +377,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
goto err;
}
for (i = 0; i < totalnum; i++) {
for (i = 0; i < total_num; i++) {
if (wNAF_len[i] > (size_t)k) {
int digit = wNAF[i][k];
int is_neg;
@@ -657,192 +447,3 @@ err:
OPENSSL_free(val_sub);
return ret;
}
/* ec_wNAF_precompute_mult()
* creates an EC_PRE_COMP object with preprecomputed multiples of the generator
* for use with wNAF splitting as implemented in ec_wNAF_mul().
*
* 'pre_comp->points' is an array of multiples of the generator
* of the following form:
* points[0] = generator;
* points[1] = 3 * generator;
* ...
* points[2^(w-1)-1] = (2^(w-1)-1) * generator;
* points[2^(w-1)] = 2^blocksize * generator;
* points[2^(w-1)+1] = 3 * 2^blocksize * generator;
* ...
* points[2^(w-1)*(numblocks-1)-1] = (2^(w-1)) * 2^(blocksize*(numblocks-2)) *
*generator
* points[2^(w-1)*(numblocks-1)] = 2^(blocksize*(numblocks-1)) *
*generator
* ...
* points[2^(w-1)*numblocks-1] = (2^(w-1)) * 2^(blocksize*(numblocks-1)) *
*generator
* points[2^(w-1)*numblocks] = NULL
*/
int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) {
const EC_POINT *generator;
EC_POINT *tmp_point = NULL, *base = NULL, **var;
BN_CTX *new_ctx = NULL;
BIGNUM *order;
size_t i, bits, w, pre_points_per_block, blocksize, numblocks, num;
EC_POINT **points = NULL;
EC_PRE_COMP *pre_comp;
int ret = 0;
/* if there is an old EC_PRE_COMP object, throw it away */
ec_pre_comp_free(group->pre_comp);
group->pre_comp = NULL;
generator = EC_GROUP_get0_generator(group);
if (generator == NULL) {
OPENSSL_PUT_ERROR(EC, EC_R_UNDEFINED_GENERATOR);
return 0;
}
pre_comp = ec_pre_comp_new();
if (pre_comp == NULL) {
return 0;
}
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL) {
goto err;
}
}
BN_CTX_start(ctx);
order = BN_CTX_get(ctx);
if (order == NULL) {
goto err;
}
if (!EC_GROUP_get_order(group, order, ctx)) {
goto err;
}
if (BN_is_zero(order)) {
OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_ORDER);
goto err;
}
bits = BN_num_bits(order);
/* The following parameters mean we precompute (approximately)
* one point per bit.
*
* TBD: The combination 8, 4 is perfect for 160 bits; for other
* bit lengths, other parameter combinations might provide better
* efficiency.
*/
blocksize = 8;
w = 4;
if (EC_window_bits_for_scalar_size(bits) > w) {
/* let's not make the window too small ... */
w = EC_window_bits_for_scalar_size(bits);
}
numblocks = (bits + blocksize - 1) /
blocksize; /* max. number of blocks to use for wNAF splitting */
pre_points_per_block = (size_t)1 << (w - 1);
num = pre_points_per_block *
numblocks; /* number of points to compute and store */
points = OPENSSL_malloc(sizeof(EC_POINT *) * (num + 1));
if (!points) {
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
var = points;
var[num] = NULL; /* pivot */
for (i = 0; i < num; i++) {
if ((var[i] = EC_POINT_new(group)) == NULL) {
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
}
if (!(tmp_point = EC_POINT_new(group)) || !(base = EC_POINT_new(group))) {
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EC_POINT_copy(base, generator)) {
goto err;
}
/* do the precomputation */
for (i = 0; i < numblocks; i++) {
size_t j;
if (!EC_POINT_dbl(group, tmp_point, base, ctx)) {
goto err;
}
if (!EC_POINT_copy(*var++, base)) {
goto err;
}
for (j = 1; j < pre_points_per_block; j++, var++) {
/* calculate odd multiples of the current base point */
if (!EC_POINT_add(group, *var, tmp_point, *(var - 1), ctx)) {
goto err;
}
}
if (i < numblocks - 1) {
/* get the next base (multiply current one by 2^blocksize) */
size_t k;
if (blocksize <= 2) {
OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
if (!EC_POINT_dbl(group, base, tmp_point, ctx)) {
goto err;
}
for (k = 2; k < blocksize; k++) {
if (!EC_POINT_dbl(group, base, base, ctx)) {
goto err;
}
}
}
}
if (!EC_POINTs_make_affine(group, num, points, ctx)) {
goto err;
}
pre_comp->blocksize = blocksize;
pre_comp->numblocks = numblocks;
pre_comp->w = w;
pre_comp->points = points;
points = NULL;
pre_comp->num = num;
group->pre_comp = pre_comp;
pre_comp = NULL;
ret = 1;
err:
if (ctx != NULL) {
BN_CTX_end(ctx);
}
BN_CTX_free(new_ctx);
ec_pre_comp_free(pre_comp);
if (points) {
EC_POINT **p;
for (p = points; *p != NULL; p++) {
EC_POINT_free(*p);
}
OPENSSL_free(points);
}
EC_POINT_free(tmp_point);
EC_POINT_free(base);
return ret;
}
+14 -25
View File
@@ -143,7 +143,7 @@ int ECDSA_do_verify(const uint8_t *digest, size_t digest_len,
const ECDSA_SIG *sig, EC_KEY *eckey) {
int ret = 0;
BN_CTX *ctx;
BIGNUM *order, *u1, *u2, *m, *X;
BIGNUM *u1, *u2, *m, *X;
EC_POINT *point = NULL;
const EC_GROUP *group;
const EC_POINT *pub_key;
@@ -167,21 +167,16 @@ int ECDSA_do_verify(const uint8_t *digest, size_t digest_len,
return 0;
}
BN_CTX_start(ctx);
order = BN_CTX_get(ctx);
u1 = BN_CTX_get(ctx);
u2 = BN_CTX_get(ctx);
m = BN_CTX_get(ctx);
X = BN_CTX_get(ctx);
if (order == NULL || u1 == NULL || u2 == NULL || m == NULL || X == NULL) {
if (u1 == NULL || u2 == NULL || m == NULL || X == NULL) {
OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
goto err;
}
if (!EC_GROUP_get_order(group, order, ctx)) {
OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
goto err;
}
const BIGNUM *order = EC_GROUP_get0_order(group);
if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) ||
BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) {
@@ -229,7 +224,7 @@ int ECDSA_do_verify(const uint8_t *digest, size_t digest_len,
ret = (BN_ucmp(u1, sig->r) == 0);
err:
BN_CTX_end(ctx);
BN_CTX_end(ctx);
BN_CTX_free(ctx);
EC_POINT_free(point);
return ret;
@@ -239,7 +234,7 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
BIGNUM **rp, const uint8_t *digest,
size_t digest_len) {
BN_CTX *ctx = NULL;
BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL;
BIGNUM *k = NULL, *r = NULL, *X = NULL;
EC_POINT *tmp_point = NULL;
const EC_GROUP *group;
int ret = 0;
@@ -260,9 +255,8 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
k = BN_new(); /* this value is later returned in *kinvp */
r = BN_new(); /* this value is later returned in *rp */
order = BN_new();
X = BN_new();
if (!k || !r || !order || !X) {
if (k == NULL || r == NULL || X == NULL) {
OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -271,10 +265,8 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
goto err;
}
if (!EC_GROUP_get_order(group, order, ctx)) {
OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
goto err;
}
const BIGNUM *order = EC_GROUP_get0_order(group);
do {
/* If possible, we'll include the private key and message digest in the k
@@ -360,7 +352,6 @@ err:
if (ctx_in == NULL) {
BN_CTX_free(ctx);
}
BN_free(order);
EC_POINT_free(tmp_point);
BN_clear_free(X);
return ret;
@@ -374,7 +365,7 @@ ECDSA_SIG *ECDSA_do_sign_ex(const uint8_t *digest, size_t digest_len,
const BIGNUM *in_kinv, const BIGNUM *in_r,
EC_KEY *eckey) {
int ok = 0;
BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL, *order = NULL;
BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL;
const BIGNUM *ckinv;
BN_CTX *ctx = NULL;
const EC_GROUP *group;
@@ -401,16 +392,15 @@ ECDSA_SIG *ECDSA_do_sign_ex(const uint8_t *digest, size_t digest_len,
}
s = ret->s;
if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL ||
(tmp = BN_new()) == NULL || (m = BN_new()) == NULL) {
if ((ctx = BN_CTX_new()) == NULL ||
(tmp = BN_new()) == NULL ||
(m = BN_new()) == NULL) {
OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EC_GROUP_get_order(group, order, ctx)) {
OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
goto err;
}
const BIGNUM *order = EC_GROUP_get0_order(group);
if (!digest_to_bn(m, digest, digest_len, order)) {
goto err;
}
@@ -464,7 +454,6 @@ err:
BN_CTX_free(ctx);
BN_clear_free(m);
BN_clear_free(tmp);
BN_free(order);
BN_clear_free(kinv);
return ret;
}
+1 -11
View File
@@ -78,17 +78,7 @@ size_t ECDSA_size(const EC_KEY *key) {
return 0;
}
BIGNUM *order = BN_new();
if (order == NULL) {
return 0;
}
if (!EC_GROUP_get_order(group, order, NULL)) {
BN_clear_free(order);
return 0;
}
group_order_size = BN_num_bytes(order);
BN_clear_free(order);
group_order_size = BN_num_bytes(EC_GROUP_get0_order(group));
}
return ECDSA_SIG_max_len(group_order_size);
+4 -8
View File
@@ -176,12 +176,8 @@ static bool TestBuiltin(FILE *out) {
fprintf(out, " failed\n");
return false;
}
ScopedBIGNUM order(BN_new());
if (!order || !EC_GROUP_get_order(group.get(), order.get(), NULL)) {
fprintf(out, " failed\n");
return false;
}
if (BN_num_bits(order.get()) < 160) {
const BIGNUM *order = EC_GROUP_get0_order(group.get());
if (BN_num_bits(order) < 160) {
// Too small to test.
fprintf(out, " skipped\n");
continue;
@@ -261,7 +257,7 @@ static bool TestBuiltin(FILE *out) {
signature.data(), signature.size()));
if (!ecdsa_sig ||
!TestTamperedSig(out, kEncodedApi, digest, 20, ecdsa_sig.get(),
eckey.get(), order.get())) {
eckey.get(), order)) {
fprintf(out, " failed\n");
return false;
}
@@ -300,7 +296,7 @@ static bool TestBuiltin(FILE *out) {
fflush(out);
// Verify a tampered signature.
if (!TestTamperedSig(out, kRawApi, digest, 20, ecdsa_sig.get(), eckey.get(),
order.get())) {
order)) {
fprintf(out, " failed\n");
return false;
}
+141 -179
View File
@@ -7,138 +7,111 @@ SSL,105,BAD_DH_P_LENGTH
SSL,106,BAD_DIGEST_LENGTH
SSL,107,BAD_ECC_CERT
SSL,108,BAD_ECPOINT
SSL,109,BAD_HANDSHAKE_LENGTH
SSL,110,BAD_HANDSHAKE_RECORD
SSL,111,BAD_HELLO_REQUEST
SSL,112,BAD_LENGTH
SSL,113,BAD_PACKET_LENGTH
SSL,114,BAD_RSA_ENCRYPT
SSL,115,BAD_SIGNATURE
SSL,116,BAD_SRTP_MKI_VALUE
SSL,117,BAD_SRTP_PROTECTION_PROFILE_LIST
SSL,118,BAD_SSL_FILETYPE
SSL,119,BAD_WRITE_RETRY
SSL,120,BIO_NOT_SET
SSL,121,BN_LIB
SSL,272,BUFFER_TOO_SMALL
SSL,122,CANNOT_SERIALIZE_PUBLIC_KEY
SSL,123,CA_DN_LENGTH_MISMATCH
SSL,124,CA_DN_TOO_LONG
SSL,125,CCS_RECEIVED_EARLY
SSL,126,CERTIFICATE_VERIFY_FAILED
SSL,127,CERT_CB_ERROR
SSL,128,CERT_LENGTH_MISMATCH
SSL,129,CHANNEL_ID_NOT_P256
SSL,130,CHANNEL_ID_SIGNATURE_INVALID
SSL,131,CIPHER_CODE_WRONG_LENGTH
SSL,132,CIPHER_OR_HASH_UNAVAILABLE
SSL,133,CLIENTHELLO_PARSE_FAILED
SSL,134,CLIENTHELLO_TLSEXT
SSL,135,CONNECTION_REJECTED
SSL,136,CONNECTION_TYPE_NOT_SET
SSL,137,COOKIE_MISMATCH
SSL,284,CUSTOM_EXTENSION_CONTENTS_TOO_LARGE
SSL,285,CUSTOM_EXTENSION_ERROR
SSL,138,D2I_ECDSA_SIG
SSL,139,DATA_BETWEEN_CCS_AND_FINISHED
SSL,140,DATA_LENGTH_TOO_LONG
SSL,141,DECODE_ERROR
SSL,142,DECRYPTION_FAILED
SSL,143,DECRYPTION_FAILED_OR_BAD_RECORD_MAC
SSL,144,DH_PUBLIC_VALUE_LENGTH_IS_WRONG
SSL,287,DH_P_TOO_LONG
SSL,145,DIGEST_CHECK_FAILED
SSL,146,DTLS_MESSAGE_TOO_BIG
SSL,147,ECC_CERT_NOT_FOR_SIGNING
SSL,148,EMPTY_SRTP_PROTECTION_PROFILE_LIST
SSL,276,EMS_STATE_INCONSISTENT
SSL,149,ENCRYPTED_LENGTH_TOO_LONG
SSL,281,ERROR_ADDING_EXTENSION
SSL,150,ERROR_IN_RECEIVED_CIPHER_LIST
SSL,282,ERROR_PARSING_EXTENSION
SSL,151,EVP_DIGESTSIGNFINAL_FAILED
SSL,152,EVP_DIGESTSIGNINIT_FAILED
SSL,153,EXCESSIVE_MESSAGE_SIZE
SSL,154,EXTRA_DATA_IN_MESSAGE
SSL,271,FRAGMENT_MISMATCH
SSL,155,GOT_A_FIN_BEFORE_A_CCS
SSL,156,GOT_CHANNEL_ID_BEFORE_A_CCS
SSL,157,GOT_NEXT_PROTO_BEFORE_A_CCS
SSL,158,GOT_NEXT_PROTO_WITHOUT_EXTENSION
SSL,159,HANDSHAKE_FAILURE_ON_CLIENT_HELLO
SSL,160,HANDSHAKE_RECORD_BEFORE_CCS
SSL,161,HTTPS_PROXY_REQUEST
SSL,162,HTTP_REQUEST
SSL,163,INAPPROPRIATE_FALLBACK
SSL,164,INVALID_COMMAND
SSL,165,INVALID_MESSAGE
SSL,166,INVALID_SSL_SESSION
SSL,167,INVALID_TICKET_KEYS_LENGTH
SSL,168,LENGTH_MISMATCH
SSL,169,LIBRARY_HAS_NO_CIPHERS
SSL,170,MISSING_DH_KEY
SSL,171,MISSING_ECDSA_SIGNING_CERT
SSL,283,MISSING_EXTENSION
SSL,172,MISSING_RSA_CERTIFICATE
SSL,173,MISSING_RSA_ENCRYPTING_CERT
SSL,174,MISSING_RSA_SIGNING_CERT
SSL,175,MISSING_TMP_DH_KEY
SSL,176,MISSING_TMP_ECDH_KEY
SSL,177,MIXED_SPECIAL_OPERATOR_WITH_GROUPS
SSL,178,MTU_TOO_SMALL
SSL,286,NEGOTIATED_BOTH_NPN_AND_ALPN
SSL,179,NESTED_GROUP
SSL,180,NO_CERTIFICATES_RETURNED
SSL,181,NO_CERTIFICATE_ASSIGNED
SSL,182,NO_CERTIFICATE_SET
SSL,183,NO_CIPHERS_AVAILABLE
SSL,184,NO_CIPHERS_PASSED
SSL,185,NO_CIPHERS_SPECIFIED
SSL,186,NO_CIPHER_MATCH
SSL,187,NO_COMPRESSION_SPECIFIED
SSL,188,NO_METHOD_SPECIFIED
SSL,189,NO_P256_SUPPORT
SSL,190,NO_PRIVATE_KEY_ASSIGNED
SSL,191,NO_RENEGOTIATION
SSL,192,NO_REQUIRED_DIGEST
SSL,193,NO_SHARED_CIPHER
SSL,194,NO_SHARED_SIGATURE_ALGORITHMS
SSL,195,NO_SRTP_PROFILES
SSL,196,NULL_SSL_CTX
SSL,197,NULL_SSL_METHOD_PASSED
SSL,198,OLD_SESSION_CIPHER_NOT_RETURNED
SSL,273,OLD_SESSION_VERSION_NOT_RETURNED
SSL,274,OUTPUT_ALIASES_INPUT
SSL,199,PACKET_LENGTH_TOO_LONG
SSL,200,PARSE_TLSEXT
SSL,201,PATH_TOO_LONG
SSL,202,PEER_DID_NOT_RETURN_A_CERTIFICATE
SSL,203,PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE
SSL,204,PROTOCOL_IS_SHUTDOWN
SSL,205,PSK_IDENTITY_NOT_FOUND
SSL,206,PSK_NO_CLIENT_CB
SSL,207,PSK_NO_SERVER_CB
SSL,208,READ_BIO_NOT_SET
SSL,209,READ_TIMEOUT_EXPIRED
SSL,210,RECORD_LENGTH_MISMATCH
SSL,211,RECORD_TOO_LARGE
SSL,212,RENEGOTIATE_EXT_TOO_LONG
SSL,213,RENEGOTIATION_ENCODING_ERR
SSL,214,RENEGOTIATION_MISMATCH
SSL,215,REQUIRED_CIPHER_MISSING
SSL,275,RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION
SSL,277,RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION
SSL,216,SCSV_RECEIVED_WHEN_RENEGOTIATING
SSL,217,SERVERHELLO_TLSEXT
SSL,218,SESSION_ID_CONTEXT_UNINITIALIZED
SSL,219,SESSION_MAY_NOT_BE_CREATED
SSL,220,SIGNATURE_ALGORITHMS_ERROR
SSL,280,SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER
SSL,221,SRTP_COULD_NOT_ALLOCATE_PROFILES
SSL,222,SRTP_PROTECTION_PROFILE_LIST_TOO_LONG
SSL,223,SRTP_UNKNOWN_PROTECTION_PROFILE
SSL,224,SSL3_EXT_INVALID_SERVERNAME
SSL,225,SSL3_EXT_INVALID_SERVERNAME_TYPE
SSL,109,BAD_HANDSHAKE_RECORD
SSL,110,BAD_HELLO_REQUEST
SSL,111,BAD_LENGTH
SSL,112,BAD_PACKET_LENGTH
SSL,113,BAD_RSA_ENCRYPT
SSL,114,BAD_SIGNATURE
SSL,115,BAD_SRTP_MKI_VALUE
SSL,116,BAD_SRTP_PROTECTION_PROFILE_LIST
SSL,117,BAD_SSL_FILETYPE
SSL,118,BAD_WRITE_RETRY
SSL,119,BIO_NOT_SET
SSL,120,BN_LIB
SSL,121,BUFFER_TOO_SMALL
SSL,122,CA_DN_LENGTH_MISMATCH
SSL,123,CA_DN_TOO_LONG
SSL,124,CCS_RECEIVED_EARLY
SSL,125,CERTIFICATE_VERIFY_FAILED
SSL,126,CERT_CB_ERROR
SSL,127,CERT_LENGTH_MISMATCH
SSL,128,CHANNEL_ID_NOT_P256
SSL,129,CHANNEL_ID_SIGNATURE_INVALID
SSL,130,CIPHER_OR_HASH_UNAVAILABLE
SSL,131,CLIENTHELLO_PARSE_FAILED
SSL,132,CLIENTHELLO_TLSEXT
SSL,133,CONNECTION_REJECTED
SSL,134,CONNECTION_TYPE_NOT_SET
SSL,135,CUSTOM_EXTENSION_ERROR
SSL,136,DATA_LENGTH_TOO_LONG
SSL,137,DECODE_ERROR
SSL,138,DECRYPTION_FAILED
SSL,139,DECRYPTION_FAILED_OR_BAD_RECORD_MAC
SSL,140,DH_PUBLIC_VALUE_LENGTH_IS_WRONG
SSL,141,DH_P_TOO_LONG
SSL,142,DIGEST_CHECK_FAILED
SSL,143,DTLS_MESSAGE_TOO_BIG
SSL,144,ECC_CERT_NOT_FOR_SIGNING
SSL,145,EMS_STATE_INCONSISTENT
SSL,146,ENCRYPTED_LENGTH_TOO_LONG
SSL,147,ERROR_ADDING_EXTENSION
SSL,148,ERROR_IN_RECEIVED_CIPHER_LIST
SSL,149,ERROR_PARSING_EXTENSION
SSL,150,EXCESSIVE_MESSAGE_SIZE
SSL,151,EXTRA_DATA_IN_MESSAGE
SSL,152,FRAGMENT_MISMATCH
SSL,153,GOT_NEXT_PROTO_WITHOUT_EXTENSION
SSL,154,HANDSHAKE_FAILURE_ON_CLIENT_HELLO
SSL,155,HTTPS_PROXY_REQUEST
SSL,156,HTTP_REQUEST
SSL,157,INAPPROPRIATE_FALLBACK
SSL,158,INVALID_COMMAND
SSL,159,INVALID_MESSAGE
SSL,160,INVALID_SSL_SESSION
SSL,161,INVALID_TICKET_KEYS_LENGTH
SSL,162,LENGTH_MISMATCH
SSL,163,LIBRARY_HAS_NO_CIPHERS
SSL,164,MISSING_EXTENSION
SSL,165,MISSING_RSA_CERTIFICATE
SSL,166,MISSING_TMP_DH_KEY
SSL,167,MISSING_TMP_ECDH_KEY
SSL,168,MIXED_SPECIAL_OPERATOR_WITH_GROUPS
SSL,169,MTU_TOO_SMALL
SSL,170,NEGOTIATED_BOTH_NPN_AND_ALPN
SSL,171,NESTED_GROUP
SSL,172,NO_CERTIFICATES_RETURNED
SSL,173,NO_CERTIFICATE_ASSIGNED
SSL,174,NO_CERTIFICATE_SET
SSL,175,NO_CIPHERS_AVAILABLE
SSL,176,NO_CIPHERS_PASSED
SSL,177,NO_CIPHER_MATCH
SSL,178,NO_COMPRESSION_SPECIFIED
SSL,179,NO_METHOD_SPECIFIED
SSL,180,NO_P256_SUPPORT
SSL,181,NO_PRIVATE_KEY_ASSIGNED
SSL,182,NO_RENEGOTIATION
SSL,183,NO_REQUIRED_DIGEST
SSL,184,NO_SHARED_CIPHER
SSL,185,NULL_SSL_CTX
SSL,186,NULL_SSL_METHOD_PASSED
SSL,187,OLD_SESSION_CIPHER_NOT_RETURNED
SSL,188,OLD_SESSION_VERSION_NOT_RETURNED
SSL,189,OUTPUT_ALIASES_INPUT
SSL,190,PARSE_TLSEXT
SSL,191,PATH_TOO_LONG
SSL,192,PEER_DID_NOT_RETURN_A_CERTIFICATE
SSL,193,PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE
SSL,194,PROTOCOL_IS_SHUTDOWN
SSL,195,PSK_IDENTITY_NOT_FOUND
SSL,196,PSK_NO_CLIENT_CB
SSL,197,PSK_NO_SERVER_CB
SSL,198,READ_TIMEOUT_EXPIRED
SSL,199,RECORD_LENGTH_MISMATCH
SSL,200,RECORD_TOO_LARGE
SSL,201,RENEGOTIATION_ENCODING_ERR
SSL,202,RENEGOTIATION_MISMATCH
SSL,203,REQUIRED_CIPHER_MISSING
SSL,204,RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION
SSL,205,RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION
SSL,206,SCSV_RECEIVED_WHEN_RENEGOTIATING
SSL,207,SERVERHELLO_TLSEXT
SSL,208,SESSION_ID_CONTEXT_UNINITIALIZED
SSL,209,SESSION_MAY_NOT_BE_CREATED
SSL,210,SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER
SSL,211,SRTP_COULD_NOT_ALLOCATE_PROFILES
SSL,212,SRTP_UNKNOWN_PROTECTION_PROFILE
SSL,213,SSL3_EXT_INVALID_SERVERNAME
SSL,1042,SSLV3_ALERT_BAD_CERTIFICATE
SSL,1020,SSLV3_ALERT_BAD_RECORD_MAC
SSL,1045,SSLV3_ALERT_CERTIFICATE_EXPIRED
@@ -151,12 +124,9 @@ SSL,1047,SSLV3_ALERT_ILLEGAL_PARAMETER
SSL,1041,SSLV3_ALERT_NO_CERTIFICATE
SSL,1010,SSLV3_ALERT_UNEXPECTED_MESSAGE
SSL,1043,SSLV3_ALERT_UNSUPPORTED_CERTIFICATE
SSL,226,SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION
SSL,227,SSL_HANDSHAKE_FAILURE
SSL,228,SSL_SESSION_ID_CALLBACK_FAILED
SSL,229,SSL_SESSION_ID_CONFLICT
SSL,230,SSL_SESSION_ID_CONTEXT_TOO_LONG
SSL,231,SSL_SESSION_ID_HAS_BAD_LENGTH
SSL,214,SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION
SSL,215,SSL_HANDSHAKE_FAILURE
SSL,216,SSL_SESSION_ID_CONTEXT_TOO_LONG
SSL,1049,TLSV1_ALERT_ACCESS_DENIED
SSL,1050,TLSV1_ALERT_DECODE_ERROR
SSL,1021,TLSV1_ALERT_DECRYPTION_FAILED
@@ -175,44 +145,36 @@ SSL,1113,TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE
SSL,1111,TLSV1_CERTIFICATE_UNOBTAINABLE
SSL,1112,TLSV1_UNRECOGNIZED_NAME
SSL,1110,TLSV1_UNSUPPORTED_EXTENSION
SSL,232,TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER
SSL,233,TLS_ILLEGAL_EXPORTER_LABEL
SSL,234,TLS_INVALID_ECPOINTFORMAT_LIST
SSL,235,TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST
SSL,236,TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG
SSL,237,TOO_MANY_EMPTY_FRAGMENTS
SSL,278,TOO_MANY_WARNING_ALERTS
SSL,238,UNABLE_TO_FIND_ECDH_PARAMETERS
SSL,239,UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS
SSL,279,UNEXPECTED_EXTENSION
SSL,240,UNEXPECTED_GROUP_CLOSE
SSL,241,UNEXPECTED_MESSAGE
SSL,242,UNEXPECTED_OPERATOR_IN_GROUP
SSL,243,UNEXPECTED_RECORD
SSL,244,UNINITIALIZED
SSL,245,UNKNOWN_ALERT_TYPE
SSL,246,UNKNOWN_CERTIFICATE_TYPE
SSL,247,UNKNOWN_CIPHER_RETURNED
SSL,248,UNKNOWN_CIPHER_TYPE
SSL,249,UNKNOWN_DIGEST
SSL,250,UNKNOWN_KEY_EXCHANGE_TYPE
SSL,251,UNKNOWN_PROTOCOL
SSL,252,UNKNOWN_SSL_VERSION
SSL,253,UNKNOWN_STATE
SSL,254,UNPROCESSED_HANDSHAKE_DATA
SSL,255,UNSAFE_LEGACY_RENEGOTIATION_DISABLED
SSL,256,UNSUPPORTED_CIPHER
SSL,257,UNSUPPORTED_COMPRESSION_ALGORITHM
SSL,258,UNSUPPORTED_ELLIPTIC_CURVE
SSL,259,UNSUPPORTED_PROTOCOL
SSL,260,UNSUPPORTED_SSL_VERSION
SSL,261,USE_SRTP_NOT_NEGOTIATED
SSL,262,WRONG_CERTIFICATE_TYPE
SSL,263,WRONG_CIPHER_RETURNED
SSL,264,WRONG_CURVE
SSL,265,WRONG_MESSAGE_TYPE
SSL,266,WRONG_SIGNATURE_TYPE
SSL,267,WRONG_SSL_VERSION
SSL,268,WRONG_VERSION_NUMBER
SSL,269,X509_LIB
SSL,270,X509_VERIFICATION_SETUP_PROBLEMS
SSL,217,TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST
SSL,218,TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG
SSL,219,TOO_MANY_EMPTY_FRAGMENTS
SSL,220,TOO_MANY_WARNING_ALERTS
SSL,221,UNABLE_TO_FIND_ECDH_PARAMETERS
SSL,222,UNEXPECTED_EXTENSION
SSL,223,UNEXPECTED_MESSAGE
SSL,224,UNEXPECTED_OPERATOR_IN_GROUP
SSL,225,UNEXPECTED_RECORD
SSL,226,UNINITIALIZED
SSL,227,UNKNOWN_ALERT_TYPE
SSL,228,UNKNOWN_CERTIFICATE_TYPE
SSL,229,UNKNOWN_CIPHER_RETURNED
SSL,230,UNKNOWN_CIPHER_TYPE
SSL,231,UNKNOWN_DIGEST
SSL,232,UNKNOWN_KEY_EXCHANGE_TYPE
SSL,233,UNKNOWN_PROTOCOL
SSL,234,UNKNOWN_SSL_VERSION
SSL,235,UNKNOWN_STATE
SSL,236,UNSAFE_LEGACY_RENEGOTIATION_DISABLED
SSL,237,UNSUPPORTED_CIPHER
SSL,238,UNSUPPORTED_COMPRESSION_ALGORITHM
SSL,239,UNSUPPORTED_ELLIPTIC_CURVE
SSL,240,UNSUPPORTED_PROTOCOL
SSL,241,WRONG_CERTIFICATE_TYPE
SSL,242,WRONG_CIPHER_RETURNED
SSL,243,WRONG_CURVE
SSL,244,WRONG_MESSAGE_TYPE
SSL,245,WRONG_SIGNATURE_TYPE
SSL,246,WRONG_SSL_VERSION
SSL,247,WRONG_VERSION_NUMBER
SSL,248,X509_LIB
SSL,249,X509_VERIFICATION_SETUP_PROBLEMS
+24 -29
View File
@@ -60,7 +60,6 @@
#include <string.h>
#include <openssl/bio.h>
#include <openssl/dh.h>
#include <openssl/dsa.h>
#include <openssl/ec.h>
#include <openssl/err.h>
@@ -73,10 +72,6 @@
#include "../internal.h"
extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD ec_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meth;
EVP_PKEY *EVP_PKEY_new(void) {
EVP_PKEY *ret;
@@ -235,15 +230,22 @@ int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key) {
return EVP_PKEY_assign(pkey, EVP_PKEY_RSA, key);
}
RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey) {
RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) {
if (pkey->type != EVP_PKEY_RSA) {
OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_RSA_KEY);
return NULL;
}
RSA_up_ref(pkey->pkey.rsa);
return pkey->pkey.rsa;
}
RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey) {
RSA *rsa = EVP_PKEY_get0_RSA(pkey);
if (rsa != NULL) {
RSA_up_ref(rsa);
}
return rsa;
}
int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) {
if (EVP_PKEY_assign_DSA(pkey, key)) {
DSA_up_ref(key);
@@ -256,15 +258,22 @@ int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key) {
return EVP_PKEY_assign(pkey, EVP_PKEY_DSA, key);
}
DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey) {
DSA *EVP_PKEY_get0_DSA(EVP_PKEY *pkey) {
if (pkey->type != EVP_PKEY_DSA) {
OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_DSA_KEY);
return NULL;
}
DSA_up_ref(pkey->pkey.dsa);
return pkey->pkey.dsa;
}
DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey) {
DSA *dsa = EVP_PKEY_get0_DSA(pkey);
if (dsa != NULL) {
DSA_up_ref(dsa);
}
return dsa;
}
int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) {
if (EVP_PKEY_assign_EC_KEY(pkey, key)) {
EC_KEY_up_ref(key);
@@ -277,34 +286,20 @@ int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) {
return EVP_PKEY_assign(pkey, EVP_PKEY_EC, key);
}
EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) {
EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey) {
if (pkey->type != EVP_PKEY_EC) {
OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_EC_KEY_KEY);
return NULL;
}
EC_KEY_up_ref(pkey->pkey.ec);
return pkey->pkey.ec;
}
int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key) {
if (EVP_PKEY_assign_DH(pkey, key)) {
DH_up_ref(key);
return 1;
EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) {
EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey);
if (ec_key != NULL) {
EC_KEY_up_ref(ec_key);
}
return 0;
}
int EVP_PKEY_assign_DH(EVP_PKEY *pkey, DH *key) {
return EVP_PKEY_assign(pkey, EVP_PKEY_DH, key);
}
DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey) {
if (pkey->type != EVP_PKEY_DH) {
OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_DH_KEY);
return NULL;
}
DH_up_ref(pkey->pkey.dh);
return pkey->pkey.dh;
return ec_key;
}
int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) {
-3
View File
@@ -66,9 +66,6 @@
#include "internal.h"
extern const EVP_PKEY_METHOD rsa_pkey_meth;
extern const EVP_PKEY_METHOD ec_pkey_meth;
static const EVP_PKEY_METHOD *const evp_methods[] = {
&rsa_pkey_meth,
&ec_pkey_meth,
+215 -36
View File
@@ -16,6 +16,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <utility>
#include <vector>
#include <openssl/bytestring.h>
@@ -233,6 +234,85 @@ static const uint8_t kExamplePSSCert[] = {
0x8c, 0x16,
};
// kBadPSSCert is an example RSA-PSS certificate with bad parameters.
static const uint8_t kBadPSSCert[] = {
0x30, 0x82, 0x03, 0x76, 0x30, 0x82, 0x02, 0x3a, 0xa0, 0x03, 0x02, 0x01,
0x02, 0x02, 0x09, 0x00, 0xd7, 0x30, 0x64, 0xbc, 0x9f, 0x12, 0xfe, 0xc3,
0x30, 0x3e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
0x0a, 0x30, 0x31, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48,
0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09,
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06,
0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa2, 0x04,
0x02, 0x02, 0x00, 0xde, 0x30, 0x27, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03,
0x55, 0x04, 0x03, 0x0c, 0x1c, 0x54, 0x65, 0x73, 0x74, 0x20, 0x49, 0x6e,
0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x50, 0x53, 0x53, 0x20, 0x63, 0x65,
0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30, 0x1e, 0x17,
0x0d, 0x31, 0x35, 0x31, 0x31, 0x30, 0x34, 0x31, 0x36, 0x30, 0x32, 0x33,
0x35, 0x5a, 0x17, 0x0d, 0x31, 0x35, 0x31, 0x32, 0x30, 0x34, 0x31, 0x36,
0x30, 0x32, 0x33, 0x35, 0x5a, 0x30, 0x27, 0x31, 0x25, 0x30, 0x23, 0x06,
0x03, 0x55, 0x04, 0x03, 0x0c, 0x1c, 0x54, 0x65, 0x73, 0x74, 0x20, 0x49,
0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x50, 0x53, 0x53, 0x20, 0x63,
0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30, 0x82,
0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82,
0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc4, 0xda, 0x33, 0xb5, 0x87,
0xa9, 0x50, 0x80, 0x18, 0x02, 0x00, 0xfb, 0x32, 0xf5, 0x29, 0x6b, 0xef,
0x01, 0x24, 0xeb, 0x86, 0x5a, 0xbe, 0xd5, 0xe3, 0xdd, 0x3b, 0xbc, 0x2c,
0xad, 0x65, 0xf6, 0x2a, 0x26, 0x28, 0x4d, 0x8a, 0xc9, 0x61, 0x39, 0xf1,
0x84, 0xb9, 0xe7, 0xd3, 0x0a, 0xc7, 0xa8, 0x0a, 0x6d, 0xef, 0xd9, 0xcb,
0x20, 0x11, 0xbb, 0x71, 0xf4, 0xa1, 0xc9, 0x9a, 0x85, 0x1c, 0xe6, 0x3f,
0x23, 0x39, 0x58, 0x3c, 0xc5, 0x6d, 0xfa, 0x03, 0xe8, 0xdb, 0xdd, 0xe0,
0xc3, 0xde, 0x85, 0x76, 0xce, 0x49, 0x06, 0xc8, 0xe1, 0x8e, 0x4c, 0x86,
0x9c, 0xec, 0xab, 0xf4, 0xe5, 0x27, 0xb4, 0x5a, 0xaf, 0xc4, 0x36, 0xd3,
0x20, 0x81, 0x54, 0xee, 0x8f, 0x48, 0x77, 0x10, 0xf8, 0x79, 0xd6, 0xaa,
0x8d, 0x1b, 0xfe, 0x7d, 0xe8, 0x15, 0x13, 0xe0, 0x7b, 0xf6, 0x90, 0xe4,
0xe2, 0xcd, 0x2e, 0x8e, 0xc9, 0x3a, 0x75, 0x42, 0xed, 0x0a, 0x0f, 0x51,
0xb2, 0xdd, 0x2e, 0x70, 0x61, 0x68, 0xd7, 0xd9, 0xab, 0xf9, 0xbe, 0xe4,
0x75, 0xb7, 0xe7, 0xf2, 0x96, 0x7b, 0xd9, 0x93, 0x43, 0x24, 0xfb, 0x9e,
0x55, 0xda, 0xd4, 0x01, 0x6c, 0x3d, 0xa2, 0x59, 0x7a, 0xd5, 0x47, 0x18,
0x7e, 0x4e, 0xf9, 0x5d, 0xda, 0xcb, 0x93, 0xa2, 0x65, 0x2f, 0x8d, 0x46,
0xad, 0x81, 0xdc, 0xf0, 0xa9, 0x5f, 0x5d, 0xfe, 0x37, 0x80, 0x64, 0x2a,
0x41, 0xfa, 0xe9, 0x1e, 0x48, 0x38, 0x22, 0x1d, 0x9c, 0x23, 0xa5, 0xad,
0xda, 0x78, 0x45, 0x18, 0x0c, 0xeb, 0x95, 0xca, 0x2b, 0xcc, 0xb9, 0x62,
0x40, 0x85, 0x09, 0x44, 0x88, 0x4c, 0xf2, 0x1e, 0x08, 0x80, 0x37, 0xe9,
0x06, 0x96, 0x8f, 0x75, 0x54, 0x0b, 0xa9, 0x2d, 0xa9, 0x15, 0xb5, 0xda,
0xe5, 0xe4, 0x23, 0xaa, 0x2c, 0x89, 0xc1, 0xa9, 0x36, 0xbc, 0x9f, 0x02,
0x03, 0x01, 0x00, 0x01, 0xa3, 0x50, 0x30, 0x4e, 0x30, 0x1d, 0x06, 0x03,
0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x2b, 0x75, 0xf3, 0x43, 0x78,
0xa0, 0x65, 0x2d, 0xe4, 0xb6, 0xf3, 0x07, 0x04, 0x38, 0x21, 0xaf, 0xb6,
0xe1, 0x5f, 0x7b, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
0x30, 0x16, 0x80, 0x14, 0x2b, 0x75, 0xf3, 0x43, 0x78, 0xa0, 0x65, 0x2d,
0xe4, 0xb6, 0xf3, 0x07, 0x04, 0x38, 0x21, 0xaf, 0xb6, 0xe1, 0x5f, 0x7b,
0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01,
0x01, 0xff, 0x30, 0x31, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x01, 0x0a, 0x30, 0x24, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60,
0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x0d, 0x30, 0x0b,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0xa2,
0x04, 0x02, 0x02, 0x00, 0xde, 0x03, 0x82, 0x01, 0x01, 0x00, 0x08, 0xc1,
0xb6, 0x6f, 0x74, 0x94, 0x6c, 0x60, 0x75, 0xd8, 0xdc, 0xe1, 0x7b, 0xbf,
0x9d, 0xb5, 0xd7, 0x14, 0x75, 0x6c, 0xdb, 0x35, 0x5c, 0x1e, 0xff, 0xe6,
0xa8, 0xe6, 0x68, 0x42, 0x41, 0x81, 0xf6, 0xbf, 0xc1, 0x56, 0x02, 0xdb,
0xc6, 0x11, 0xeb, 0x15, 0x9d, 0xa9, 0x1c, 0x61, 0x25, 0x6d, 0x46, 0x0f,
0x7e, 0x27, 0xdd, 0x4b, 0xdc, 0xed, 0x07, 0xbd, 0xde, 0xd5, 0xde, 0x09,
0xf8, 0xfd, 0xbd, 0xa3, 0x4c, 0x81, 0xa9, 0xf7, 0x78, 0xff, 0x01, 0x80,
0x73, 0xf2, 0x40, 0xf2, 0xa8, 0x27, 0xe8, 0x00, 0x04, 0x3b, 0xf5, 0xe7,
0xa6, 0x58, 0x45, 0x79, 0x34, 0x49, 0x42, 0xd2, 0xd9, 0x56, 0x5e, 0xf9,
0x0a, 0x41, 0xd7, 0x81, 0x41, 0x94, 0x77, 0x78, 0x7e, 0x00, 0x3b, 0xca,
0xb5, 0xc0, 0x6e, 0x5b, 0xd7, 0x52, 0x52, 0x77, 0x1a, 0x52, 0xb8, 0x0d,
0x29, 0x1f, 0x2e, 0xfe, 0x1f, 0xf6, 0xb0, 0xc1, 0xb7, 0xf1, 0x15, 0x98,
0x0f, 0x30, 0x5d, 0x74, 0x2f, 0xfa, 0xe9, 0x84, 0xda, 0xde, 0xbe, 0xca,
0x91, 0x55, 0x1f, 0x5b, 0xbc, 0xaa, 0x45, 0x07, 0xc4, 0x2e, 0x21, 0x8a,
0x75, 0xc9, 0xbe, 0x6e, 0x39, 0x53, 0x10, 0xcb, 0x2f, 0x4b, 0xe1, 0x21,
0x1e, 0xea, 0x7d, 0x0b, 0x36, 0xe9, 0xa0, 0x2c, 0x76, 0x17, 0x1f, 0x69,
0x34, 0xfb, 0x45, 0x63, 0x7c, 0x84, 0x39, 0xb4, 0x21, 0x98, 0xbd, 0x49,
0xca, 0x80, 0x91, 0x5a, 0xa0, 0x44, 0xef, 0x91, 0xb3, 0x14, 0xf6, 0xd1,
0x6a, 0x2b, 0xb1, 0xe5, 0x4a, 0x44, 0x92, 0x7b, 0x3e, 0x8b, 0x7b, 0x6b,
0x90, 0x6b, 0x2c, 0x67, 0x3b, 0x0e, 0xb9, 0x5a, 0x87, 0x35, 0x33, 0x59,
0x94, 0x2f, 0x7e, 0xf6, 0x13, 0xc7, 0x22, 0x87, 0x3d, 0x50, 0xc9, 0x80,
0x40, 0xda, 0x35, 0xbc, 0x62, 0x16, 0xdc, 0xd5, 0x95, 0xa1, 0xe1, 0x9b,
0x68, 0x9f,
};
// kExampleRSAKeyPKCS8 is kExampleRSAKeyDER encoded in a PKCS #8
// PrivateKeyInfo.
static const uint8_t kExampleRSAKeyPKCS8[] = {
@@ -342,6 +422,22 @@ static const uint8_t kExampleBadECKeyDER2[] = {
0x07,
};
// kInvalidPrivateKey is an invalid private key. See
// https://rt.openssl.org/Ticket/Display.html?id=4131.
static const uint8_t kInvalidPrivateKey[] = {
0x30, 0x39, 0x02, 0x01, 0x02, 0x30, 0x09, 0x06, 0x01, 0x38, 0x08,
0x04, 0x69, 0x30, 0x30, 0x80, 0x30, 0x19, 0x01, 0x02, 0x9f, 0xf8,
0x8b, 0x29, 0x80, 0x30, 0xb0, 0x1b, 0x06, 0x09, 0x22, 0xbe, 0x08,
0x04, 0xe9, 0x30, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x3a, 0x01, 0x80,
0x09, 0x30, 0x80, 0x06, 0x01, 0x02, 0x30, 0x80, 0x30, 0x01, 0x3b,
0x02, 0x00, 0x00, 0x04, 0x20, 0x30, 0x82, 0x04, 0xe9, 0x30, 0xc3,
0xe8, 0x30, 0x01, 0x05, 0x30, 0x80, 0x30, 0x01, 0x3b, 0x01, 0x04,
0x02, 0x02, 0xff, 0x00, 0x30, 0x29, 0x02, 0x11, 0x03, 0x29, 0x29,
0x02, 0x00, 0x99, 0x30, 0x80, 0x06, 0x21, 0x02, 0x24, 0x04, 0xe8,
0x30, 0x01, 0x01, 0x04, 0x30, 0x80, 0x1b, 0x06, 0x09, 0x2a, 0x86,
0x48, 0x30, 0x01, 0xaa, 0x02, 0x86, 0xc0, 0x30, 0xdf, 0xe9, 0x80,
};
static ScopedEVP_PKEY LoadExampleRSAKey() {
ScopedRSA rsa(RSA_private_key_from_bytes(kExampleRSAKeyDER,
sizeof(kExampleRSAKeyDER)));
@@ -477,16 +573,52 @@ static bool TestEVP_DigestSignAlgorithm(void) {
return true;
}
static bool TestEVP_DigestVerifyInitFromAlgorithm(void) {
CBS cert, cert_body, tbs_cert, algorithm, signature;
CBS_init(&cert, kExamplePSSCert, sizeof(kExamplePSSCert));
if (!CBS_get_asn1(&cert, &cert_body, CBS_ASN1_SEQUENCE) ||
CBS_len(&cert) != 0 ||
static bool ParseCertificate(CBS *out_tbs_cert,
ScopedEVP_PKEY *out_pubkey,
ScopedX509_ALGOR *out_algor,
CBS *out_signature,
const CBS *in_) {
CBS in = *in_;
CBS cert_body, tbs_cert, algorithm, signature;
if (!CBS_get_asn1(&in, &cert_body, CBS_ASN1_SEQUENCE) ||
CBS_len(&in) != 0 ||
!CBS_get_any_asn1_element(&cert_body, &tbs_cert, NULL, NULL) ||
!CBS_get_asn1_element(&cert_body, &algorithm, CBS_ASN1_SEQUENCE) ||
!CBS_get_asn1(&cert_body, &signature, CBS_ASN1_BITSTRING) ||
CBS_len(&cert_body) != 0) {
fprintf(stderr, "Failed to parse certificate\n");
return false;
}
CBS tbs_cert_copy = tbs_cert;
CBS tbs_cert_body, discard, spki;
if (!CBS_get_asn1(&tbs_cert_copy, &tbs_cert_body, CBS_ASN1_SEQUENCE) ||
CBS_len(&tbs_cert_copy) != 0 ||
!CBS_get_optional_asn1(
&tbs_cert_body, &discard, NULL,
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) ||
!CBS_get_asn1(&tbs_cert_body, &discard /* serialNumber */,
CBS_ASN1_INTEGER) ||
!CBS_get_asn1(&tbs_cert_body, &discard /* signature */,
CBS_ASN1_SEQUENCE) ||
!CBS_get_any_asn1_element(&tbs_cert_body, &discard /* issuer */,
NULL, NULL) ||
!CBS_get_asn1(&tbs_cert_body, &discard /* validity */,
CBS_ASN1_SEQUENCE) ||
!CBS_get_any_asn1_element(&tbs_cert_body, &discard /* subject */,
NULL, NULL) ||
!CBS_get_asn1_element(&tbs_cert_body, &spki, CBS_ASN1_SEQUENCE)) {
return false;
}
const uint8_t *derp = CBS_data(&spki);
ScopedEVP_PKEY pubkey(d2i_PUBKEY(NULL, &derp, CBS_len(&spki)));
if (!pubkey || derp != CBS_data(&spki) + CBS_len(&spki)) {
return false;
}
derp = CBS_data(&algorithm);
ScopedX509_ALGOR algor(d2i_X509_ALGOR(NULL, &derp, CBS_len(&algorithm)));
if (!algor || derp != CBS_data(&algorithm) + CBS_len(&algorithm)) {
return false;
}
@@ -494,21 +626,28 @@ static bool TestEVP_DigestVerifyInitFromAlgorithm(void) {
// leading phase byte is just a zero.
uint8_t padding;
if (!CBS_get_u8(&signature, &padding) || padding != 0) {
fprintf(stderr, "Invalid signature padding\n");
return false;
}
const uint8_t *derp = CBS_data(&algorithm);
ScopedX509_ALGOR algor(d2i_X509_ALGOR(NULL, &derp, CBS_len(&algorithm)));
if (!algor || derp != CBS_data(&algorithm) + CBS_len(&algorithm)) {
fprintf(stderr, "Failed to parse algorithm\n");
*out_tbs_cert = tbs_cert;
*out_pubkey = std::move(pubkey);
*out_algor = std::move(algor);
*out_signature = signature;
return true;
}
static bool TestEVP_DigestVerifyInitFromAlgorithm(void) {
CBS in, tbs_cert, signature;
ScopedEVP_PKEY pkey;
ScopedX509_ALGOR algor;
CBS_init(&in, kExamplePSSCert, sizeof(kExamplePSSCert));
if (!ParseCertificate(&tbs_cert, &pkey, &algor, &signature, &in)) {
fprintf(stderr, "Failed to parse certificate\n");
return false;
}
ScopedEVP_PKEY pkey = LoadExampleRSAKey();
ScopedEVP_MD_CTX md_ctx;
if (!pkey ||
!EVP_DigestVerifyInitFromAlgorithm(md_ctx.get(), algor.get(),
if (!EVP_DigestVerifyInitFromAlgorithm(md_ctx.get(), algor.get(),
pkey.get()) ||
!EVP_DigestVerifyUpdate(md_ctx.get(), CBS_data(&tbs_cert),
CBS_len(&tbs_cert)) ||
@@ -519,8 +658,28 @@ static bool TestEVP_DigestVerifyInitFromAlgorithm(void) {
return true;
}
static bool Testd2i_AutoPrivateKey(const uint8_t *input, size_t input_len,
int expected_id) {
static bool TestBadPSSParameters(void) {
CBS in, tbs_cert, signature;
ScopedEVP_PKEY pkey;
ScopedX509_ALGOR algor;
CBS_init(&in, kBadPSSCert, sizeof(kBadPSSCert));
if (!ParseCertificate(&tbs_cert, &pkey, &algor, &signature, &in)) {
fprintf(stderr, "Failed to parse certificate\n");
return false;
}
ScopedEVP_MD_CTX md_ctx;
if (EVP_DigestVerifyInitFromAlgorithm(md_ctx.get(), algor.get(),
pkey.get())) {
fprintf(stderr, "Unexpectedly processed bad signature parameters\n");
return false;
}
ERR_clear_error();
return true;
}
static bool TestValidPrivateKey(const uint8_t *input, size_t input_len,
int expected_id) {
const uint8_t *p = input;
ScopedEVP_PKEY pkey(d2i_AutoPrivateKey(NULL, &p, input_len));
if (!pkey || p != input + input_len) {
@@ -536,6 +695,42 @@ static bool Testd2i_AutoPrivateKey(const uint8_t *input, size_t input_len,
return true;
}
static bool Testd2i_AutoPrivateKey() {
if (!TestValidPrivateKey(kExampleRSAKeyDER, sizeof(kExampleRSAKeyDER),
EVP_PKEY_RSA)) {
fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyDER) failed\n");
return false;
}
if (!TestValidPrivateKey(kExampleRSAKeyPKCS8, sizeof(kExampleRSAKeyPKCS8),
EVP_PKEY_RSA)) {
fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyPKCS8) failed\n");
return false;
}
if (!TestValidPrivateKey(kExampleECKeyDER, sizeof(kExampleECKeyDER),
EVP_PKEY_EC)) {
fprintf(stderr, "d2i_AutoPrivateKey(kExampleECKeyDER) failed\n");
return false;
}
if (!TestValidPrivateKey(kExampleDSAKeyDER, sizeof(kExampleDSAKeyDER),
EVP_PKEY_DSA)) {
fprintf(stderr, "d2i_AutoPrivateKey(kExampleDSAKeyDER) failed\n");
return false;
}
const uint8_t *p = kInvalidPrivateKey;
ScopedEVP_PKEY pkey(d2i_AutoPrivateKey(NULL, &p, sizeof(kInvalidPrivateKey)));
if (pkey) {
fprintf(stderr, "Parsed invalid private key\n");
return false;
}
ERR_clear_error();
return true;
}
// TestEVP_PKCS82PKEY tests loading a bad key in PKCS8 format.
static bool TestEVP_PKCS82PKEY(void) {
const uint8_t *derp = kExampleBadECKeyDER;
@@ -641,30 +836,14 @@ int main(void) {
return 1;
}
if (!Testd2i_AutoPrivateKey(kExampleRSAKeyDER, sizeof(kExampleRSAKeyDER),
EVP_PKEY_RSA)) {
fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyDER) failed\n");
if (!TestBadPSSParameters()) {
fprintf(stderr, "TestBadPSSParameters failed\n");
ERR_print_errors_fp(stderr);
return 1;
}
if (!Testd2i_AutoPrivateKey(kExampleRSAKeyPKCS8, sizeof(kExampleRSAKeyPKCS8),
EVP_PKEY_RSA)) {
fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyPKCS8) failed\n");
ERR_print_errors_fp(stderr);
return 1;
}
if (!Testd2i_AutoPrivateKey(kExampleECKeyDER, sizeof(kExampleECKeyDER),
EVP_PKEY_EC)) {
fprintf(stderr, "d2i_AutoPrivateKey(kExampleECKeyDER) failed\n");
ERR_print_errors_fp(stderr);
return 1;
}
if (!Testd2i_AutoPrivateKey(kExampleDSAKeyDER, sizeof(kExampleDSAKeyDER),
EVP_PKEY_DSA)) {
fprintf(stderr, "d2i_AutoPrivateKey(kExampleDSAKeyDER) failed\n");
if (!Testd2i_AutoPrivateKey()) {
fprintf(stderr, "Testd2i_AutoPrivateKey failed\n");
ERR_print_errors_fp(stderr);
return 1;
}
+7
View File
@@ -263,6 +263,13 @@ struct evp_pkey_method_st {
int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2);
} /* EVP_PKEY_METHOD */;
extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD ec_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meth;
extern const EVP_PKEY_METHOD rsa_pkey_meth;
extern const EVP_PKEY_METHOD ec_pkey_meth;
#if defined(__cplusplus)
} /* extern C */
+5 -19
View File
@@ -337,23 +337,12 @@ static int int_ec_size(const EVP_PKEY *pkey) {
}
static int ec_bits(const EVP_PKEY *pkey) {
BIGNUM *order = BN_new();
const EC_GROUP *group;
int ret;
if (!order) {
const EC_GROUP *group = EC_KEY_get0_group(pkey->pkey.ec);
if (group == NULL) {
ERR_clear_error();
return 0;
}
group = EC_KEY_get0_group(pkey->pkey.ec);
if (!EC_GROUP_get_order(group, order, NULL)) {
ERR_clear_error();
return 0;
}
ret = BN_num_bits(order);
BN_free(order);
return ret;
return BN_num_bits(EC_GROUP_get0_order(group));
}
static int ec_missing_parameters(const EVP_PKEY *pkey) {
@@ -387,7 +376,6 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
const char *ecstr;
size_t buf_len = 0, i;
int ret = 0, reason = ERR_R_BIO_LIB;
BIGNUM *order = NULL;
BN_CTX *ctx = NULL;
const EC_GROUP *group;
const EC_POINT *public_key;
@@ -458,9 +446,8 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
if (!BIO_indent(bp, off, 128)) {
goto err;
}
order = BN_new();
if (order == NULL || !EC_GROUP_get_order(group, order, NULL) ||
BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) {
const BIGNUM *order = EC_GROUP_get0_order(group);
if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) {
goto err;
}
@@ -482,7 +469,6 @@ err:
OPENSSL_PUT_ERROR(EVP, reason);
}
OPENSSL_free(pub_key_bytes);
BN_free(order);
BN_CTX_free(ctx);
OPENSSL_free(buffer);
return ret;
+1 -1
View File
@@ -303,7 +303,7 @@ static X509_ALGOR *rsa_mgf1_decode(X509_ALGOR *alg) {
const uint8_t *p;
int plen;
if (alg == NULL ||
if (alg == NULL || alg->parameter == NULL ||
OBJ_obj2nid(alg->algorithm) != NID_mgf1 ||
alg->parameter->type != V_ASN1_SEQUENCE) {
return NULL;
+14 -34
View File
@@ -124,14 +124,12 @@
struct crypto_ex_data_func_st {
long argl; /* Arbitary long */
void *argp; /* Arbitary void pointer */
CRYPTO_EX_new *new_func;
CRYPTO_EX_free *free_func;
CRYPTO_EX_dup *dup_func;
};
int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class, int *out_index,
long argl, void *argp, CRYPTO_EX_new *new_func,
CRYPTO_EX_dup *dup_func,
long argl, void *argp, CRYPTO_EX_dup *dup_func,
CRYPTO_EX_free *free_func) {
CRYPTO_EX_DATA_FUNCS *funcs;
int ret = 0;
@@ -144,7 +142,6 @@ int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class, int *out_index,
funcs->argl = argl;
funcs->argp = argp;
funcs->new_func = new_func;
funcs->dup_func = dup_func;
funcs->free_func = free_func;
@@ -230,46 +227,24 @@ static int get_func_pointers(STACK_OF(CRYPTO_EX_DATA_FUNCS) **out,
return 1;
}
int CRYPTO_new_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, void *obj,
CRYPTO_EX_DATA *ad) {
STACK_OF(CRYPTO_EX_DATA_FUNCS) *func_pointers;
size_t i;
void CRYPTO_new_ex_data(CRYPTO_EX_DATA *ad) {
ad->sk = NULL;
if (!get_func_pointers(&func_pointers, ex_data_class)) {
return 0;
}
for (i = 0; i < sk_CRYPTO_EX_DATA_FUNCS_num(func_pointers); i++) {
CRYPTO_EX_DATA_FUNCS *func_pointer =
sk_CRYPTO_EX_DATA_FUNCS_value(func_pointers, i);
if (func_pointer->new_func) {
func_pointer->new_func(obj, NULL, ad, i + ex_data_class->num_reserved,
func_pointer->argl, func_pointer->argp);
}
}
sk_CRYPTO_EX_DATA_FUNCS_free(func_pointers);
return 1;
}
int CRYPTO_dup_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, CRYPTO_EX_DATA *to,
const CRYPTO_EX_DATA *from) {
STACK_OF(CRYPTO_EX_DATA_FUNCS) *func_pointers;
size_t i;
if (!from->sk) {
if (from->sk == NULL) {
/* In this case, |from| is blank, which is also the initial state of |to|,
* so there's nothing to do. */
return 1;
}
STACK_OF(CRYPTO_EX_DATA_FUNCS) *func_pointers;
if (!get_func_pointers(&func_pointers, ex_data_class)) {
return 0;
}
size_t i;
for (i = 0; i < sk_CRYPTO_EX_DATA_FUNCS_num(func_pointers); i++) {
CRYPTO_EX_DATA_FUNCS *func_pointer =
sk_CRYPTO_EX_DATA_FUNCS_value(func_pointers, i);
@@ -288,13 +263,18 @@ int CRYPTO_dup_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, CRYPTO_EX_DATA *to,
void CRYPTO_free_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, void *obj,
CRYPTO_EX_DATA *ad) {
STACK_OF(CRYPTO_EX_DATA_FUNCS) *func_pointers;
size_t i;
if (!get_func_pointers(&func_pointers, ex_data_class)) {
if (ad->sk == NULL) {
/* Nothing to do. */
return;
}
STACK_OF(CRYPTO_EX_DATA_FUNCS) *func_pointers;
if (!get_func_pointers(&func_pointers, ex_data_class)) {
/* TODO(davidben): This leaks memory on malloc error. */
return;
}
size_t i;
for (i = 0; i < sk_CRYPTO_EX_DATA_FUNCS_num(func_pointers); i++) {
CRYPTO_EX_DATA_FUNCS *func_pointer =
sk_CRYPTO_EX_DATA_FUNCS_value(func_pointers, i);
-17
View File
@@ -1,17 +0,0 @@
/* 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. */
/* This header is linked to under the names of several headers that have been
* removed. It's possible to put a #error in here in order to catch that an
* clean up older code. */
+3 -19
View File
@@ -168,18 +168,6 @@ extern "C" {
#endif
#if defined(_MSC_VER)
#define OPENSSL_U64(x) x##UI64
#else
#if defined(OPENSSL_64_BIT)
#define OPENSSL_U64(x) x##UL
#else
#define OPENSSL_U64(x) x##ULL
#endif
#endif /* defined(_MSC_VER) */
#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || defined(OPENSSL_ARM) || \
defined(OPENSSL_AARCH64)
/* OPENSSL_cpuid_setup initializes OPENSSL_ia32cap_P. */
@@ -509,8 +497,7 @@ typedef struct {
* zero otherwise. */
OPENSSL_EXPORT int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class,
int *out_index, long argl,
void *argp, CRYPTO_EX_new *new_func,
CRYPTO_EX_dup *dup_func,
void *argp, CRYPTO_EX_dup *dup_func,
CRYPTO_EX_free *free_func);
/* CRYPTO_set_ex_data sets an extra data pointer on a given object. Each class
@@ -522,11 +509,8 @@ OPENSSL_EXPORT int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int index, void *val);
* function. */
OPENSSL_EXPORT void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int index);
/* CRYPTO_new_ex_data initialises a newly allocated |CRYPTO_EX_DATA| which is
* embedded inside of |obj| which is of class |ex_data_class|. Returns one on
* success and zero otherwise. */
OPENSSL_EXPORT int CRYPTO_new_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class,
void *obj, CRYPTO_EX_DATA *ad);
/* CRYPTO_new_ex_data initialises a newly allocated |CRYPTO_EX_DATA|. */
OPENSSL_EXPORT void CRYPTO_new_ex_data(CRYPTO_EX_DATA *ad);
/* CRYPTO_dup_ex_data duplicates |from| into a freshly allocated
* |CRYPTO_EX_DATA|, |to|. Both of which are inside objects of the given
+6 -4
View File
@@ -84,13 +84,13 @@ void md4_block_data_order(uint32_t *state, const uint8_t *data, size_t num);
do { \
uint32_t ll; \
ll = (c)->h[0]; \
(void) HOST_l2c(ll, (s)); \
HOST_l2c(ll, (s)); \
ll = (c)->h[1]; \
(void) HOST_l2c(ll, (s)); \
HOST_l2c(ll, (s)); \
ll = (c)->h[2]; \
(void) HOST_l2c(ll, (s)); \
HOST_l2c(ll, (s)); \
ll = (c)->h[3]; \
(void) HOST_l2c(ll, (s)); \
HOST_l2c(ll, (s)); \
} while (0)
#define HASH_BLOCK_DATA_ORDER md4_block_data_order
@@ -103,6 +103,8 @@ void md4_block_data_order(uint32_t *state, const uint8_t *data, size_t num);
#define G(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
#define H(b, c, d) ((b) ^ (c) ^ (d))
#define ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n))))
#define R0(a, b, c, d, k, s, t) \
{ \
a += ((k) + (t)+F((b), (c), (d))); \
+6 -4
View File
@@ -106,13 +106,13 @@ void md5_block_data_order(uint32_t *state, const uint8_t *data, size_t num);
do { \
uint32_t ll; \
ll = (c)->h[0]; \
(void) HOST_l2c(ll, (s)); \
HOST_l2c(ll, (s)); \
ll = (c)->h[1]; \
(void) HOST_l2c(ll, (s)); \
HOST_l2c(ll, (s)); \
ll = (c)->h[2]; \
(void) HOST_l2c(ll, (s)); \
HOST_l2c(ll, (s)); \
ll = (c)->h[3]; \
(void) HOST_l2c(ll, (s)); \
HOST_l2c(ll, (s)); \
} while (0)
#define HASH_BLOCK_DATA_ORDER md5_block_data_order
@@ -127,6 +127,8 @@ void md5_block_data_order(uint32_t *state, const uint8_t *data, size_t num);
#define H(b,c,d) ((b) ^ (c) ^ (d))
#define I(b,c,d) (((~(d)) | (b)) ^ (c))
#define ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n))))
#define R0(a,b,c,d,k,s,t) { \
a+=((k)+(t)+F((b),(c),(d))); \
a=ROTATE(a,s); \
+1 -1
View File
@@ -140,7 +140,7 @@ $code=<<___;
.text
.code 32
#ifdef __APPLE__
#ifdef __clang__
#define ldrplb ldrbpl
#define ldrneb ldrbne
#endif
+6 -7
View File
@@ -55,7 +55,6 @@
#include <openssl/cpu.h>
#include "internal.h"
#include "../internal.h"
#if !defined(OPENSSL_NO_ASM) && \
@@ -76,7 +75,7 @@
#define REDUCE1BIT(V) \
do { \
if (sizeof(size_t) == 8) { \
uint64_t T = OPENSSL_U64(0xe100000000000000) & (0 - (V.lo & 1)); \
uint64_t T = UINT64_C(0xe100000000000000) & (0 - (V.lo & 1)); \
V.lo = (V.hi << 63) | (V.lo >> 1); \
V.hi = (V.hi >> 1) ^ T; \
} else { \
@@ -586,7 +585,7 @@ int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const uint8_t *aad, size_t len) {
}
alen += len;
if (alen > (OPENSSL_U64(1) << 61) || (sizeof(len) == 8 && alen < len)) {
if (alen > (UINT64_C(1) << 61) || (sizeof(len) == 8 && alen < len)) {
return 0;
}
ctx->len.u[0] = alen;
@@ -653,7 +652,7 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const void *key,
#endif
mlen += len;
if (mlen > ((OPENSSL_U64(1) << 36) - 32) ||
if (mlen > ((UINT64_C(1) << 36) - 32) ||
(sizeof(len) == 8 && mlen < len)) {
return 0;
}
@@ -813,7 +812,7 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const void *key,
#endif
mlen += len;
if (mlen > ((OPENSSL_U64(1) << 36) - 32) ||
if (mlen > ((UINT64_C(1) << 36) - 32) ||
(sizeof(len) == 8 && mlen < len)) {
return 0;
}
@@ -978,7 +977,7 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const void *key,
#endif
mlen += len;
if (mlen > ((OPENSSL_U64(1) << 36) - 32) ||
if (mlen > ((UINT64_C(1) << 36) - 32) ||
(sizeof(len) == 8 && mlen < len)) {
return 0;
}
@@ -1087,7 +1086,7 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, const void *key,
#endif
mlen += len;
if (mlen > ((OPENSSL_U64(1) << 36) - 32) ||
if (mlen > ((UINT64_C(1) << 36) - 32) ||
(sizeof(len) == 8 && mlen < len)) {
return 0;
}
+14 -4
View File
@@ -773,13 +773,14 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth,
goto err;
}
if (OBJ_cbs2nid(&contents_type) != NID_pkcs7_data) {
if (OBJ_cbs2nid(&contents_type) != NID_pkcs7_data ||
CBS_len(&ai) > LONG_MAX) {
OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
inp = CBS_data(&ai);
algor = d2i_X509_ALGOR(NULL, &inp, CBS_len(&ai));
algor = d2i_X509_ALGOR(NULL, &inp, (long)CBS_len(&ai));
if (algor == NULL) {
goto err;
}
@@ -822,9 +823,14 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth,
goto err;
}
if (CBS_len(&wrapped_contents) > LONG_MAX) {
OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
/* encrypted isn't actually an X.509 signature, but it has the same
* structure as one and so |X509_SIG| is reused to store it. */
encrypted = d2i_X509_SIG(NULL, &inp, CBS_len(&wrapped_contents));
encrypted = d2i_X509_SIG(NULL, &inp, (long)CBS_len(&wrapped_contents));
if (encrypted == NULL) {
OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
@@ -861,8 +867,12 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth,
}
if (OBJ_cbs2nid(&cert_type) == NID_x509Certificate) {
if (CBS_len(&cert) > LONG_MAX) {
OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
const uint8_t *inp = CBS_data(&cert);
X509 *x509 = d2i_X509(NULL, &inp, CBS_len(&cert));
X509 *x509 = d2i_X509(NULL, &inp, (long)CBS_len(&cert));
if (!x509) {
OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
+6 -1
View File
@@ -192,7 +192,12 @@ int RAND_pseudo_bytes(uint8_t *buf, size_t len) {
return RAND_bytes(buf, len);
}
void RAND_seed(const void *buf, int num) {}
void RAND_seed(const void *buf, int num) {
/* OpenSSH calls |RAND_seed| before jailing on the assumption that any needed
* file descriptors etc will be opened. */
uint8_t unused;
RAND_bytes(&unused, sizeof(unused));
}
int RAND_load_file(const char *path, long num) {
if (num < 0) { /* read the "whole file" */
+9 -5
View File
@@ -83,11 +83,15 @@ static void init_once(void) {
int flags = fcntl(fd, F_GETFD);
if (flags == -1) {
abort();
}
flags |= FD_CLOEXEC;
if (fcntl(fd, F_SETFD, flags) == -1) {
abort();
/* Native Client doesn't implement |fcntl|. */
if (errno != ENOSYS) {
abort();
}
} else {
flags |= FD_CLOEXEC;
if (fcntl(fd, F_SETFD, flags) == -1) {
abort();
}
}
urandom_fd = fd;
}
-2
View File
@@ -5,7 +5,6 @@ if (${ARCH} STREQUAL "x86_64")
RC4_ARCH_SOURCES
rc4-x86_64.${ASM_EXT}
rc4-md5-x86_64.${ASM_EXT}
)
endif()
@@ -27,5 +26,4 @@ add_library(
)
perlasm(rc4-x86_64.${ASM_EXT} asm/rc4-x86_64.pl)
perlasm(rc4-md5-x86_64.${ASM_EXT} asm/rc4-md5-x86_64.pl)
perlasm(rc4-586.${ASM_EXT} asm/rc4-586.pl)
-632
View File
@@ -1,632 +0,0 @@
#!/usr/bin/env perl
#
# ====================================================================
# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
# project. The module is, however, dual licensed under OpenSSL and
# CRYPTOGAMS licenses depending on where you obtain it. For further
# details see http://www.openssl.org/~appro/cryptogams/.
# ====================================================================
# June 2011
#
# This is RC4+MD5 "stitch" implementation. The idea, as spelled in
# http://download.intel.com/design/intarch/papers/323686.pdf, is that
# since both algorithms exhibit instruction-level parallelism, ILP,
# below theoretical maximum, interleaving them would allow to utilize
# processor resources better and achieve better performance. RC4
# instruction sequence is virtually identical to rc4-x86_64.pl, which
# is heavily based on submission by Maxim Perminov, Maxim Locktyukhin
# and Jim Guilford of Intel. MD5 is fresh implementation aiming to
# minimize register usage, which was used as "main thread" with RC4
# weaved into it, one RC4 round per one MD5 round. In addition to the
# stiched subroutine the script can generate standalone replacement
# md5_block_asm_data_order and RC4. Below are performance numbers in
# cycles per processed byte, less is better, for these the standalone
# subroutines, sum of them, and stitched one:
#
# RC4 MD5 RC4+MD5 stitch gain
# Opteron 6.5(*) 5.4 11.9 7.0 +70%(*)
# Core2 6.5 5.8 12.3 7.7 +60%
# Westmere 4.3 5.2 9.5 7.0 +36%
# Sandy Bridge 4.2 5.5 9.7 6.8 +43%
# Atom 9.3 6.5 15.8 11.1 +42%
#
# (*) rc4-x86_64.pl delivers 5.3 on Opteron, so real improvement
# is +53%...
my ($rc4,$md5)=(1,1); # what to generate?
my $D="#" if (!$md5); # if set to "#", MD5 is stitched into RC4(),
# but its result is discarded. Idea here is
# to be able to use 'openssl speed rc4' for
# benchmarking the stitched subroutine...
my $flavour = shift;
my $output = shift;
if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
my $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
$0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate;
( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
( $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";
*STDOUT=*OUT;
my ($dat,$in0,$out,$ctx,$inp,$len, $func,$nargs);
if ($rc4 && !$md5) {
($dat,$len,$in0,$out) = ("%rdi","%rsi","%rdx","%rcx");
$func="RC4"; $nargs=4;
} elsif ($md5 && !$rc4) {
($ctx,$inp,$len) = ("%rdi","%rsi","%rdx");
$func="md5_block_asm_data_order"; $nargs=3;
} else {
($dat,$in0,$out,$ctx,$inp,$len) = ("%rdi","%rsi","%rdx","%rcx","%r8","%r9");
$func="rc4_md5_enc"; $nargs=6;
# void rc4_md5_enc(
# RC4_KEY *key, #
# const void *in0, # RC4 input
# void *out, # RC4 output
# MD5_CTX *ctx, #
# const void *inp, # MD5 input
# size_t len); # number of 64-byte blocks
}
my @K=( 0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,
0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,
0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be,
0x6b901122,0xfd987193,0xa679438e,0x49b40821,
0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa,
0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,
0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,
0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a,
0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c,
0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70,
0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,
0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,
0xf4292244,0x432aff97,0xab9423a7,0xfc93a039,
0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1,
0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1,
0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391 );
my @V=("%r8d","%r9d","%r10d","%r11d"); # MD5 registers
my $tmp="%r12d";
my @XX=("%rbp","%rsi"); # RC4 registers
my @TX=("%rax","%rbx");
my $YY="%rcx";
my $TY="%rdx";
my $MOD=32; # 16, 32 or 64
$code.=<<___;
.text
.align 16
.globl $func
.type $func,\@function,$nargs
$func:
cmp \$0,$len
je .Labort
push %rbx
push %rbp
push %r12
push %r13
push %r14
push %r15
sub \$40,%rsp
.Lbody:
___
if ($rc4) {
$code.=<<___;
$D#md5# mov $ctx,%r11 # reassign arguments
mov $len,%r12
mov $in0,%r13
mov $out,%r14
$D#md5# mov $inp,%r15
___
$ctx="%r11" if ($md5); # reassign arguments
$len="%r12";
$in0="%r13";
$out="%r14";
$inp="%r15" if ($md5);
$inp=$in0 if (!$md5);
$code.=<<___;
xor $XX[0],$XX[0]
xor $YY,$YY
lea 8($dat),$dat
mov -8($dat),$XX[0]#b
mov -4($dat),$YY#b
inc $XX[0]#b
sub $in0,$out
movl ($dat,$XX[0],4),$TX[0]#d
___
$code.=<<___ if (!$md5);
xor $TX[1],$TX[1]
test \$-128,$len
jz .Loop1
sub $XX[0],$TX[1]
and \$`$MOD-1`,$TX[1]
jz .Loop${MOD}_is_hot
sub $TX[1],$len
.Loop${MOD}_warmup:
add $TX[0]#b,$YY#b
movl ($dat,$YY,4),$TY#d
movl $TX[0]#d,($dat,$YY,4)
movl $TY#d,($dat,$XX[0],4)
add $TY#b,$TX[0]#b
inc $XX[0]#b
movl ($dat,$TX[0],4),$TY#d
movl ($dat,$XX[0],4),$TX[0]#d
xorb ($in0),$TY#b
movb $TY#b,($out,$in0)
lea 1($in0),$in0
dec $TX[1]
jnz .Loop${MOD}_warmup
mov $YY,$TX[1]
xor $YY,$YY
mov $TX[1]#b,$YY#b
.Loop${MOD}_is_hot:
mov $len,32(%rsp) # save original $len
shr \$6,$len # number of 64-byte blocks
___
if ($D && !$md5) { # stitch in dummy MD5
$md5=1;
$ctx="%r11";
$inp="%r15";
$code.=<<___;
mov %rsp,$ctx
mov $in0,$inp
___
}
}
$code.=<<___;
#rc4# add $TX[0]#b,$YY#b
#rc4# lea ($dat,$XX[0],4),$XX[1]
shl \$6,$len
add $inp,$len # pointer to the end of input
mov $len,16(%rsp)
#md5# mov $ctx,24(%rsp) # save pointer to MD5_CTX
#md5# mov 0*4($ctx),$V[0] # load current hash value from MD5_CTX
#md5# mov 1*4($ctx),$V[1]
#md5# mov 2*4($ctx),$V[2]
#md5# mov 3*4($ctx),$V[3]
jmp .Loop
.align 16
.Loop:
#md5# mov $V[0],0*4(%rsp) # put aside current hash value
#md5# mov $V[1],1*4(%rsp)
#md5# mov $V[2],2*4(%rsp)
#md5# mov $V[3],$tmp # forward reference
#md5# mov $V[3],3*4(%rsp)
___
sub R0 {
my ($i,$a,$b,$c,$d)=@_;
my @rot0=(7,12,17,22);
my $j=$i%16;
my $k=$i%$MOD;
my $xmm="%xmm".($j&1);
$code.=" movdqu ($in0),%xmm2\n" if ($rc4 && $j==15);
$code.=" add \$$MOD,$XX[0]#b\n" if ($rc4 && $j==15 && $k==$MOD-1);
$code.=" pxor $xmm,$xmm\n" if ($rc4 && $j<=1);
$code.=<<___;
#rc4# movl ($dat,$YY,4),$TY#d
#md5# xor $c,$tmp
#rc4# movl $TX[0]#d,($dat,$YY,4)
#md5# and $b,$tmp
#md5# add 4*`$j`($inp),$a
#rc4# add $TY#b,$TX[0]#b
#rc4# movl `4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d
#md5# add \$$K[$i],$a
#md5# xor $d,$tmp
#rc4# movz $TX[0]#b,$TX[0]#d
#rc4# movl $TY#d,4*$k($XX[1])
#md5# add $tmp,$a
#rc4# add $TX[1]#b,$YY#b
#md5# rol \$$rot0[$j%4],$a
#md5# mov `$j==15?"$b":"$c"`,$tmp # forward reference
#rc4# pinsrw \$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n
#md5# add $b,$a
___
$code.=<<___ if ($rc4 && $j==15 && $k==$MOD-1);
mov $YY,$XX[1]
xor $YY,$YY # keyword to partial register
mov $XX[1]#b,$YY#b
lea ($dat,$XX[0],4),$XX[1]
___
$code.=<<___ if ($rc4 && $j==15);
psllq \$8,%xmm1
pxor %xmm0,%xmm2
pxor %xmm1,%xmm2
___
}
sub R1 {
my ($i,$a,$b,$c,$d)=@_;
my @rot1=(5,9,14,20);
my $j=$i%16;
my $k=$i%$MOD;
my $xmm="%xmm".($j&1);
$code.=" movdqu 16($in0),%xmm3\n" if ($rc4 && $j==15);
$code.=" add \$$MOD,$XX[0]#b\n" if ($rc4 && $j==15 && $k==$MOD-1);
$code.=" pxor $xmm,$xmm\n" if ($rc4 && $j<=1);
$code.=<<___;
#rc4# movl ($dat,$YY,4),$TY#d
#md5# xor $b,$tmp
#rc4# movl $TX[0]#d,($dat,$YY,4)
#md5# and $d,$tmp
#md5# add 4*`((1+5*$j)%16)`($inp),$a
#rc4# add $TY#b,$TX[0]#b
#rc4# movl `4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d
#md5# add \$$K[$i],$a
#md5# xor $c,$tmp
#rc4# movz $TX[0]#b,$TX[0]#d
#rc4# movl $TY#d,4*$k($XX[1])
#md5# add $tmp,$a
#rc4# add $TX[1]#b,$YY#b
#md5# rol \$$rot1[$j%4],$a
#md5# mov `$j==15?"$c":"$b"`,$tmp # forward reference
#rc4# pinsrw \$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n
#md5# add $b,$a
___
$code.=<<___ if ($rc4 && $j==15 && $k==$MOD-1);
mov $YY,$XX[1]
xor $YY,$YY # keyword to partial register
mov $XX[1]#b,$YY#b
lea ($dat,$XX[0],4),$XX[1]
___
$code.=<<___ if ($rc4 && $j==15);
psllq \$8,%xmm1
pxor %xmm0,%xmm3
pxor %xmm1,%xmm3
___
}
sub R2 {
my ($i,$a,$b,$c,$d)=@_;
my @rot2=(4,11,16,23);
my $j=$i%16;
my $k=$i%$MOD;
my $xmm="%xmm".($j&1);
$code.=" movdqu 32($in0),%xmm4\n" if ($rc4 && $j==15);
$code.=" add \$$MOD,$XX[0]#b\n" if ($rc4 && $j==15 && $k==$MOD-1);
$code.=" pxor $xmm,$xmm\n" if ($rc4 && $j<=1);
$code.=<<___;
#rc4# movl ($dat,$YY,4),$TY#d
#md5# xor $c,$tmp
#rc4# movl $TX[0]#d,($dat,$YY,4)
#md5# xor $b,$tmp
#md5# add 4*`((5+3*$j)%16)`($inp),$a
#rc4# add $TY#b,$TX[0]#b
#rc4# movl `4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d
#md5# add \$$K[$i],$a
#rc4# movz $TX[0]#b,$TX[0]#d
#md5# add $tmp,$a
#rc4# movl $TY#d,4*$k($XX[1])
#rc4# add $TX[1]#b,$YY#b
#md5# rol \$$rot2[$j%4],$a
#md5# mov `$j==15?"\\\$-1":"$c"`,$tmp # forward reference
#rc4# pinsrw \$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n
#md5# add $b,$a
___
$code.=<<___ if ($rc4 && $j==15 && $k==$MOD-1);
mov $YY,$XX[1]
xor $YY,$YY # keyword to partial register
mov $XX[1]#b,$YY#b
lea ($dat,$XX[0],4),$XX[1]
___
$code.=<<___ if ($rc4 && $j==15);
psllq \$8,%xmm1
pxor %xmm0,%xmm4
pxor %xmm1,%xmm4
___
}
sub R3 {
my ($i,$a,$b,$c,$d)=@_;
my @rot3=(6,10,15,21);
my $j=$i%16;
my $k=$i%$MOD;
my $xmm="%xmm".($j&1);
$code.=" movdqu 48($in0),%xmm5\n" if ($rc4 && $j==15);
$code.=" add \$$MOD,$XX[0]#b\n" if ($rc4 && $j==15 && $k==$MOD-1);
$code.=" pxor $xmm,$xmm\n" if ($rc4 && $j<=1);
$code.=<<___;
#rc4# movl ($dat,$YY,4),$TY#d
#md5# xor $d,$tmp
#rc4# movl $TX[0]#d,($dat,$YY,4)
#md5# or $b,$tmp
#md5# add 4*`((7*$j)%16)`($inp),$a
#rc4# add $TY#b,$TX[0]#b
#rc4# movl `4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d
#md5# add \$$K[$i],$a
#rc4# movz $TX[0]#b,$TX[0]#d
#md5# xor $c,$tmp
#rc4# movl $TY#d,4*$k($XX[1])
#md5# add $tmp,$a
#rc4# add $TX[1]#b,$YY#b
#md5# rol \$$rot3[$j%4],$a
#md5# mov \$-1,$tmp # forward reference
#rc4# pinsrw \$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n
#md5# add $b,$a
___
$code.=<<___ if ($rc4 && $j==15);
mov $XX[0],$XX[1]
xor $XX[0],$XX[0] # keyword to partial register
mov $XX[1]#b,$XX[0]#b
mov $YY,$XX[1]
xor $YY,$YY # keyword to partial register
mov $XX[1]#b,$YY#b
lea ($dat,$XX[0],4),$XX[1]
psllq \$8,%xmm1
pxor %xmm0,%xmm5
pxor %xmm1,%xmm5
___
}
my $i=0;
for(;$i<16;$i++) { R0($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); }
for(;$i<32;$i++) { R1($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); }
for(;$i<48;$i++) { R2($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); }
for(;$i<64;$i++) { R3($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); }
$code.=<<___;
#md5# add 0*4(%rsp),$V[0] # accumulate hash value
#md5# add 1*4(%rsp),$V[1]
#md5# add 2*4(%rsp),$V[2]
#md5# add 3*4(%rsp),$V[3]
#rc4# movdqu %xmm2,($out,$in0) # write RC4 output
#rc4# movdqu %xmm3,16($out,$in0)
#rc4# movdqu %xmm4,32($out,$in0)
#rc4# movdqu %xmm5,48($out,$in0)
#md5# lea 64($inp),$inp
#rc4# lea 64($in0),$in0
cmp 16(%rsp),$inp # are we done?
jb .Loop
#md5# mov 24(%rsp),$len # restore pointer to MD5_CTX
#rc4# sub $TX[0]#b,$YY#b # correct $YY
#md5# mov $V[0],0*4($len) # write MD5_CTX
#md5# mov $V[1],1*4($len)
#md5# mov $V[2],2*4($len)
#md5# mov $V[3],3*4($len)
___
$code.=<<___ if ($rc4 && (!$md5 || $D));
mov 32(%rsp),$len # restore original $len
and \$63,$len # remaining bytes
jnz .Loop1
jmp .Ldone
.align 16
.Loop1:
add $TX[0]#b,$YY#b
movl ($dat,$YY,4),$TY#d
movl $TX[0]#d,($dat,$YY,4)
movl $TY#d,($dat,$XX[0],4)
add $TY#b,$TX[0]#b
inc $XX[0]#b
movl ($dat,$TX[0],4),$TY#d
movl ($dat,$XX[0],4),$TX[0]#d
xorb ($in0),$TY#b
movb $TY#b,($out,$in0)
lea 1($in0),$in0
dec $len
jnz .Loop1
.Ldone:
___
$code.=<<___;
#rc4# sub \$1,$XX[0]#b
#rc4# movl $XX[0]#d,-8($dat)
#rc4# movl $YY#d,-4($dat)
mov 40(%rsp),%r15
mov 48(%rsp),%r14
mov 56(%rsp),%r13
mov 64(%rsp),%r12
mov 72(%rsp),%rbp
mov 80(%rsp),%rbx
lea 88(%rsp),%rsp
.Lepilogue:
.Labort:
ret
.size $func,.-$func
___
if ($rc4 && $D) { # sole purpose of this section is to provide
# option to use the generated module as drop-in
# replacement for rc4-x86_64.pl for debugging
# and testing purposes...
my ($idx,$ido)=("%r8","%r9");
my ($dat,$len,$inp)=("%rdi","%rsi","%rdx");
$code.=<<___;
.globl RC4_set_key
.type RC4_set_key,\@function,3
.align 16
RC4_set_key:
lea 8($dat),$dat
lea ($inp,$len),$inp
neg $len
mov $len,%rcx
xor %eax,%eax
xor $ido,$ido
xor %r10,%r10
xor %r11,%r11
jmp .Lw1stloop
.align 16
.Lw1stloop:
mov %eax,($dat,%rax,4)
add \$1,%al
jnc .Lw1stloop
xor $ido,$ido
xor $idx,$idx
.align 16
.Lw2ndloop:
mov ($dat,$ido,4),%r10d
add ($inp,$len,1),$idx#b
add %r10b,$idx#b
add \$1,$len
mov ($dat,$idx,4),%r11d
cmovz %rcx,$len
mov %r10d,($dat,$idx,4)
mov %r11d,($dat,$ido,4)
add \$1,$ido#b
jnc .Lw2ndloop
xor %eax,%eax
mov %eax,-8($dat)
mov %eax,-4($dat)
ret
.size RC4_set_key,.-RC4_set_key
.globl RC4_options
.type RC4_options,\@abi-omnipotent
.align 16
RC4_options:
lea .Lopts(%rip),%rax
ret
.align 64
.Lopts:
.asciz "rc4(64x,int)"
.align 64
.size RC4_options,.-RC4_options
___
}
# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
# CONTEXT *context,DISPATCHER_CONTEXT *disp)
if ($win64) {
my $rec="%rcx";
my $frame="%rdx";
my $context="%r8";
my $disp="%r9";
$code.=<<___;
.extern __imp_RtlVirtualUnwind
.type se_handler,\@abi-omnipotent
.align 16
se_handler:
push %rsi
push %rdi
push %rbx
push %rbp
push %r12
push %r13
push %r14
push %r15
pushfq
sub \$64,%rsp
mov 120($context),%rax # pull context->Rax
mov 248($context),%rbx # pull context->Rip
lea .Lbody(%rip),%r10
cmp %r10,%rbx # context->Rip<.Lbody
jb .Lin_prologue
mov 152($context),%rax # pull context->Rsp
lea .Lepilogue(%rip),%r10
cmp %r10,%rbx # context->Rip>=.Lepilogue
jae .Lin_prologue
mov 40(%rax),%r15
mov 48(%rax),%r14
mov 56(%rax),%r13
mov 64(%rax),%r12
mov 72(%rax),%rbp
mov 80(%rax),%rbx
lea 88(%rax),%rax
mov %rbx,144($context) # restore context->Rbx
mov %rbp,160($context) # restore context->Rbp
mov %r12,216($context) # restore context->R12
mov %r13,224($context) # restore context->R12
mov %r14,232($context) # restore context->R14
mov %r15,240($context) # restore context->R15
.Lin_prologue:
mov 8(%rax),%rdi
mov 16(%rax),%rsi
mov %rax,152($context) # restore context->Rsp
mov %rsi,168($context) # restore context->Rsi
mov %rdi,176($context) # restore context->Rdi
mov 40($disp),%rdi # disp->ContextRecord
mov $context,%rsi # context
mov \$154,%ecx # sizeof(CONTEXT)
.long 0xa548f3fc # cld; rep movsq
mov $disp,%rsi
xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER
mov 8(%rsi),%rdx # arg2, disp->ImageBase
mov 0(%rsi),%r8 # arg3, disp->ControlPc
mov 16(%rsi),%r9 # arg4, disp->FunctionEntry
mov 40(%rsi),%r10 # disp->ContextRecord
lea 56(%rsi),%r11 # &disp->HandlerData
lea 24(%rsi),%r12 # &disp->EstablisherFrame
mov %r10,32(%rsp) # arg5
mov %r11,40(%rsp) # arg6
mov %r12,48(%rsp) # arg7
mov %rcx,56(%rsp) # arg8, (NULL)
call *__imp_RtlVirtualUnwind(%rip)
mov \$1,%eax # ExceptionContinueSearch
add \$64,%rsp
popfq
pop %r15
pop %r14
pop %r13
pop %r12
pop %rbp
pop %rbx
pop %rdi
pop %rsi
ret
.size se_handler,.-se_handler
.section .pdata
.align 4
.rva .LSEH_begin_$func
.rva .LSEH_end_$func
.rva .LSEH_info_$func
.section .xdata
.align 8
.LSEH_info_$func:
.byte 9,0,0,0
.rva se_handler
___
}
sub reg_part {
my ($reg,$conv)=@_;
if ($reg =~ /%r[0-9]+/) { $reg .= $conv; }
elsif ($conv eq "b") { $reg =~ s/%[er]([^x]+)x?/%$1l/; }
elsif ($conv eq "w") { $reg =~ s/%[er](.+)/%$1/; }
elsif ($conv eq "d") { $reg =~ s/%[er](.+)/%e$1/; }
return $reg;
}
$code =~ s/(%[a-z0-9]+)#([bwd])/reg_part($1,$2)/gem;
$code =~ s/\`([^\`]*)\`/eval $1/gem;
$code =~ s/pinsrw\s+\$0,/movd /gm;
$code =~ s/#md5#//gm if ($md5);
$code =~ s/#rc4#//gm if ($rc4);
print $code;
close STDOUT;
+22 -43
View File
@@ -56,6 +56,7 @@
#include <openssl/rsa.h>
#include <assert.h>
#include <limits.h>
#include <string.h>
#include <openssl/digest.h>
@@ -65,6 +66,7 @@
#include <openssl/sha.h>
#include "internal.h"
#include "../internal.h"
/* TODO(fork): don't the check functions have to be constant time? */
@@ -191,51 +193,30 @@ int RSA_padding_add_PKCS1_type_2(uint8_t *to, unsigned tlen,
return 1;
}
/* constant_time_byte_eq returns 1 if |x| == |y| and 0 otherwise. */
static int constant_time_byte_eq(unsigned char a, unsigned char b) {
unsigned char z = ~(a ^ b);
z &= z >> 4;
z &= z >> 2;
z &= z >> 1;
return z;
}
/* constant_time_select returns |x| if |v| is 1 and |y| if |v| is 0.
* Its behavior is undefined if |v| takes any other value. */
static int constant_time_select(int v, int x, int y) {
return ((~(v - 1)) & x) | ((v - 1) & y);
}
/* constant_time_le returns 1 if |x| <= |y| and 0 otherwise.
* |x| and |y| must be positive. */
static int constant_time_le(int x, int y) {
return ((x - y - 1) >> (sizeof(int) * 8 - 1)) & 1;
}
int RSA_message_index_PKCS1_type_2(const uint8_t *from, size_t from_len,
size_t *out_index) {
size_t i;
int first_byte_is_zero, second_byte_is_two, looking_for_index;
int valid_index, zero_index = 0;
unsigned first_byte_is_zero, second_byte_is_two, looking_for_index;
unsigned valid_index, zero_index = 0;
/* PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography
* Standard", section 7.2.2. */
if (from_len < RSA_PKCS1_PADDING_SIZE) {
if (from_len < RSA_PKCS1_PADDING_SIZE || from_len > UINT_MAX) {
/* |from| is zero-padded to the size of the RSA modulus, a public value, so
* this can be rejected in non-constant time. */
* this can be rejected in non-constant time. This logic also requires
* |from_len| fit in an |unsigned|. */
*out_index = 0;
return 0;
}
first_byte_is_zero = constant_time_byte_eq(from[0], 0);
second_byte_is_two = constant_time_byte_eq(from[1], 2);
first_byte_is_zero = constant_time_eq(from[0], 0);
second_byte_is_two = constant_time_eq(from[1], 2);
looking_for_index = 1;
looking_for_index = ~0u;
for (i = 2; i < from_len; i++) {
int equals0 = constant_time_byte_eq(from[i], 0);
zero_index =
constant_time_select(looking_for_index & equals0, i, zero_index);
unsigned equals0 = constant_time_is_zero(from[i]);
zero_index = constant_time_select(looking_for_index & equals0, (unsigned)i,
zero_index);
looking_for_index = constant_time_select(equals0, 0, looking_for_index);
}
@@ -247,13 +228,13 @@ int RSA_message_index_PKCS1_type_2(const uint8_t *from, size_t from_len,
valid_index &= ~looking_for_index;
/* PS must be at least 8 bytes long, and it starts two bytes into |from|. */
valid_index &= constant_time_le(2 + 8, zero_index);
valid_index &= constant_time_ge(zero_index, 2 + 8);
/* Skip the zero byte. */
zero_index++;
*out_index = constant_time_select(valid_index, zero_index, 0);
return valid_index;
return constant_time_select(valid_index, 1, 0);
}
int RSA_padding_check_PKCS1_type_2(uint8_t *to, unsigned tlen,
@@ -421,10 +402,9 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen,
const uint8_t *from, unsigned flen,
const uint8_t *param, unsigned plen,
const EVP_MD *md, const EVP_MD *mgf1md) {
unsigned i, dblen, mlen = -1, mdlen;
unsigned i, dblen, mlen = -1, mdlen, bad, looking_for_one_byte, one_index = 0;
const uint8_t *maskeddb, *maskedseed;
uint8_t *db = NULL, seed[EVP_MAX_MD_SIZE], phash[EVP_MAX_MD_SIZE];
int bad, looking_for_one_byte, one_index = 0;
if (md == NULL) {
md = EVP_sha1();
@@ -472,15 +452,14 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen,
goto err;
}
bad = CRYPTO_memcmp(db, phash, mdlen);
bad |= from[0];
bad = ~constant_time_is_zero(CRYPTO_memcmp(db, phash, mdlen));
bad |= ~constant_time_is_zero(from[0]);
looking_for_one_byte = 1;
looking_for_one_byte = ~0u;
for (i = mdlen; i < dblen; i++) {
int equals1 = constant_time_byte_eq(db[i], 1);
int equals0 = constant_time_byte_eq(db[i], 0);
one_index =
constant_time_select(looking_for_one_byte & equals1, i, one_index);
unsigned equals1 = constant_time_eq(db[i], 1);
unsigned equals0 = constant_time_eq(db[i], 0);
one_index = constant_time_select(looking_for_one_byte & equals1, i, one_index);
looking_for_one_byte =
constant_time_select(equals1, 0, looking_for_one_byte);
bad |= looking_for_one_byte & ~equals0;
+4 -10
View File
@@ -96,13 +96,7 @@ RSA *RSA_new_method(const ENGINE *engine) {
rsa->references = 1;
rsa->flags = rsa->meth->flags;
CRYPTO_MUTEX_init(&rsa->lock);
if (!CRYPTO_new_ex_data(&g_ex_data_class, rsa, &rsa->ex_data)) {
CRYPTO_MUTEX_cleanup(&rsa->lock);
METHOD_unref(rsa->meth);
OPENSSL_free(rsa);
return NULL;
}
CRYPTO_new_ex_data(&rsa->ex_data);
if (rsa->meth->init && !rsa->meth->init(rsa)) {
CRYPTO_free_ex_data(&g_ex_data_class, rsa, &rsa->ex_data);
@@ -308,11 +302,11 @@ int RSA_supports_digest(const RSA *rsa, const EVP_MD *md) {
return 1;
}
int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
int index;
if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, new_func,
dup_func, free_func)) {
if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func,
free_func)) {
return -1;
}
return index;
+1 -1
View File
@@ -636,7 +636,7 @@ static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) {
BIGNUM *p = NULL, *q = NULL;
/* Make sure BN_mod_inverse in Montgomery intialization uses the
* BN_FLG_CONSTTIME flag (unless RSA_FLAG_NO_CONSTTIME is set) */
* BN_FLG_CONSTTIME flag. */
BN_init(&local_p);
p = &local_p;
BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
+1 -3
View File
@@ -121,9 +121,7 @@ for (@ARGV) { $xmm=1 if (/-DOPENSSL_IA32_SSE2/); }
# In upstream, this is controlled by shelling out to the compiler to check
# versions, but BoringSSL is intended to be used with pre-generated perlasm
# output, so this isn't useful anyway.
#
# TODO(davidben): Enable this after testing. $ymm goes up to 1.
$ymm = 0;
$ymm = 1;
$ymm = 0 unless ($xmm);
+4 -2
View File
@@ -96,8 +96,10 @@ die "can't locate x86_64-xlate.pl";
# versions, but BoringSSL is intended to be used with pre-generated perlasm
# output, so this isn't useful anyway.
#
# TODO(davidben): Enable this after testing. $avx goes up to 2.
$avx = 0;
# TODO(davidben): Enable AVX2 code after testing by setting $avx to 2. Is it
# necessary to disable AVX2 code when SHA Extensions code is disabled? Upstream
# did not tie them together until after $shaext was added.
$avx = 1;
# TODO(davidben): Consider enabling the Intel SHA Extensions code once it's
# been tested.
+2 -2
View File
@@ -72,8 +72,8 @@ for (@ARGV) { $xmm=1 if (/-DOPENSSL_IA32_SSE2/); }
# versions, but BoringSSL is intended to be used with pre-generated perlasm
# output, so this isn't useful anyway.
#
# TODO(davidben): Enable this after testing. $avx goes up to 2.
$avx = 0;
# TODO(davidben): Enable AVX2 code after testing by setting $avx to 2.
$avx = 1;
$avx = 0 unless ($xmm);
+4 -2
View File
@@ -113,8 +113,10 @@ die "can't locate x86_64-xlate.pl";
# versions, but BoringSSL is intended to be used with pre-generated perlasm
# output, so this isn't useful anyway.
#
# TODO(davidben): Enable this after testing. $avx goes up to 2.
$avx = 0;
# TODO(davidben): Enable AVX2 code after testing by setting $avx to 2. Is it
# necessary to disable AVX2 code when SHA Extensions code is disabled? Upstream
# did not tie them together until after $shaext was added.
$avx = 1;
# TODO(davidben): Consider enabling the Intel SHA Extensions code once it's
# been tested.
+6 -5
View File
@@ -102,21 +102,22 @@ uint8_t *SHA1(const uint8_t *data, size_t len, uint8_t *out) {
do { \
uint32_t ll; \
ll = (c)->h[0]; \
(void) HOST_l2c(ll, (s)); \
HOST_l2c(ll, (s)); \
ll = (c)->h[1]; \
(void) HOST_l2c(ll, (s)); \
HOST_l2c(ll, (s)); \
ll = (c)->h[2]; \
(void) HOST_l2c(ll, (s)); \
HOST_l2c(ll, (s)); \
ll = (c)->h[3]; \
(void) HOST_l2c(ll, (s)); \
HOST_l2c(ll, (s)); \
ll = (c)->h[4]; \
(void) HOST_l2c(ll, (s)); \
HOST_l2c(ll, (s)); \
} while (0)
#define HASH_UPDATE SHA1_Update
#define HASH_TRANSFORM SHA1_Transform
#define HASH_FINAL SHA1_Final
#define HASH_BLOCK_DATA_ORDER sha1_block_data_order
#define ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n))))
#define Xupdate(a, ix, ia, ib, ic, id) \
((a) = (ia ^ ib ^ ic ^ id), ix = (a) = ROTATE((a), 1))
+5 -3
View File
@@ -155,13 +155,13 @@ int SHA224_Final(uint8_t *md, SHA256_CTX *ctx) {
case SHA224_DIGEST_LENGTH: \
for (nn = 0; nn < SHA224_DIGEST_LENGTH / 4; nn++) { \
ll = (c)->h[nn]; \
(void) HOST_l2c(ll, (s)); \
HOST_l2c(ll, (s)); \
} \
break; \
case SHA256_DIGEST_LENGTH: \
for (nn = 0; nn < SHA256_DIGEST_LENGTH / 4; nn++) { \
ll = (c)->h[nn]; \
(void) HOST_l2c(ll, (s)); \
HOST_l2c(ll, (s)); \
} \
break; \
default: \
@@ -170,7 +170,7 @@ int SHA224_Final(uint8_t *md, SHA256_CTX *ctx) {
} \
for (nn = 0; nn < (c)->md_len / 4; nn++) { \
ll = (c)->h[nn]; \
(void) HOST_l2c(ll, (s)); \
HOST_l2c(ll, (s)); \
} \
break; \
} \
@@ -204,6 +204,8 @@ static const uint32_t K256[64] = {
0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL};
#define ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n))))
/* FIPS specification refers to right rotations, while our ROTATE macro
* is left one. This is why you might notice that rotation coefficients
* differ from those observed in FIPS document by 32-N... */
+89 -77
View File
@@ -60,8 +60,6 @@
#include <openssl/mem.h>
#include "../internal.h"
/* IMPLEMENTATION NOTES.
*
@@ -87,14 +85,14 @@
#endif
int SHA384_Init(SHA512_CTX *sha) {
sha->h[0] = OPENSSL_U64(0xcbbb9d5dc1059ed8);
sha->h[1] = OPENSSL_U64(0x629a292a367cd507);
sha->h[2] = OPENSSL_U64(0x9159015a3070dd17);
sha->h[3] = OPENSSL_U64(0x152fecd8f70e5939);
sha->h[4] = OPENSSL_U64(0x67332667ffc00b31);
sha->h[5] = OPENSSL_U64(0x8eb44a8768581511);
sha->h[6] = OPENSSL_U64(0xdb0c2e0d64f98fa7);
sha->h[7] = OPENSSL_U64(0x47b5481dbefa4fa4);
sha->h[0] = UINT64_C(0xcbbb9d5dc1059ed8);
sha->h[1] = UINT64_C(0x629a292a367cd507);
sha->h[2] = UINT64_C(0x9159015a3070dd17);
sha->h[3] = UINT64_C(0x152fecd8f70e5939);
sha->h[4] = UINT64_C(0x67332667ffc00b31);
sha->h[5] = UINT64_C(0x8eb44a8768581511);
sha->h[6] = UINT64_C(0xdb0c2e0d64f98fa7);
sha->h[7] = UINT64_C(0x47b5481dbefa4fa4);
sha->Nl = 0;
sha->Nh = 0;
@@ -105,14 +103,14 @@ int SHA384_Init(SHA512_CTX *sha) {
int SHA512_Init(SHA512_CTX *sha) {
sha->h[0] = OPENSSL_U64(0x6a09e667f3bcc908);
sha->h[1] = OPENSSL_U64(0xbb67ae8584caa73b);
sha->h[2] = OPENSSL_U64(0x3c6ef372fe94f82b);
sha->h[3] = OPENSSL_U64(0xa54ff53a5f1d36f1);
sha->h[4] = OPENSSL_U64(0x510e527fade682d1);
sha->h[5] = OPENSSL_U64(0x9b05688c2b3e6c1f);
sha->h[6] = OPENSSL_U64(0x1f83d9abfb41bd6b);
sha->h[7] = OPENSSL_U64(0x5be0cd19137e2179);
sha->h[0] = UINT64_C(0x6a09e667f3bcc908);
sha->h[1] = UINT64_C(0xbb67ae8584caa73b);
sha->h[2] = UINT64_C(0x3c6ef372fe94f82b);
sha->h[3] = UINT64_C(0xa54ff53a5f1d36f1);
sha->h[4] = UINT64_C(0x510e527fade682d1);
sha->h[5] = UINT64_C(0x9b05688c2b3e6c1f);
sha->h[6] = UINT64_C(0x1f83d9abfb41bd6b);
sha->h[7] = UINT64_C(0x5be0cd19137e2179);
sha->Nl = 0;
sha->Nh = 0;
@@ -185,7 +183,7 @@ int SHA512_Update(SHA512_CTX *c, const void *in_data, size_t len) {
return 1;
}
l = (c->Nl + (((uint64_t)len) << 3)) & OPENSSL_U64(0xffffffffffffffff);
l = (c->Nl + (((uint64_t)len) << 3)) & UINT64_C(0xffffffffffffffff);
if (l < c->Nl) {
c->Nh++;
}
@@ -316,77 +314,91 @@ int SHA512_Final(uint8_t *md, SHA512_CTX *sha) {
#ifndef SHA512_ASM
static const uint64_t K512[80] = {
0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f,
0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019,
0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242,
0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3,
0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x2de92c6f592b0275,
0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f,
0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc,
0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6,
0x92722c851482353b, 0xa2bfe8a14cf10364, 0xa81a664bbc423001,
0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99,
0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb,
0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc,
0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915,
0xc67178f2e372532b, 0xca273eceea26619c, 0xd186b8c721c0c207,
0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba,
0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
0x5fcb6fab3ad6faec, 0x6c44198c4a475817};
UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd),
UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc),
UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019),
UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118),
UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe),
UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2),
UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1),
UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694),
UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3),
UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65),
UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483),
UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5),
UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210),
UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4),
UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725),
UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70),
UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926),
UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df),
UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8),
UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b),
UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001),
UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30),
UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910),
UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8),
UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53),
UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8),
UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb),
UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3),
UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60),
UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec),
UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9),
UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b),
UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207),
UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178),
UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6),
UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b),
UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493),
UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c),
UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a),
UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817),
};
#if defined(__GNUC__) && __GNUC__ >= 2 && !defined(OPENSSL_NO_ASM)
#if defined(__x86_64) || defined(__x86_64__)
#define ROTR(a, n) \
({ \
uint64_t ret; \
asm("rorq %1,%0" : "=r"(ret) : "J"(n), "0"(a) : "cc"); \
ret; \
#define ROTR(a, n) \
({ \
uint64_t ret; \
__asm__("rorq %1, %0" : "=r"(ret) : "J"(n), "0"(a) : "cc"); \
ret; \
})
#define PULL64(x) \
({ \
uint64_t ret = *((const uint64_t *)(&(x))); \
asm("bswapq %0" : "=r"(ret) : "0"(ret)); \
ret; \
#define PULL64(x) \
({ \
uint64_t ret = *((const uint64_t *)(&(x))); \
__asm__("bswapq %0" : "=r"(ret) : "0"(ret)); \
ret; \
})
#elif(defined(__i386) || defined(__i386__))
#define PULL64(x) \
({ \
const unsigned int *p = (const unsigned int *)(&(x)); \
unsigned int hi = p[0], lo = p[1]; \
asm("bswapl %0; bswapl %1;" : "=r"(lo), "=r"(hi) : "0"(lo), "1"(hi)); \
((uint64_t)hi) << 32 | lo; \
#define PULL64(x) \
({ \
const unsigned int *p = (const unsigned int *)(&(x)); \
unsigned int hi = p[0], lo = p[1]; \
__asm__("bswapl %0; bswapl %1;" : "=r"(lo), "=r"(hi) : "0"(lo), "1"(hi)); \
((uint64_t)hi) << 32 | lo; \
})
#elif(defined(_ARCH_PPC) && defined(__64BIT__)) || defined(_ARCH_PPC64)
#define ROTR(a, n) \
({ \
uint64_t ret; \
asm("rotrdi %0,%1,%2" : "=r"(ret) : "r"(a), "K"(n)); \
ret; \
#define ROTR(a, n) \
({ \
uint64_t ret; \
__asm__("rotrdi %0, %1, %2" : "=r"(ret) : "r"(a), "K"(n)); \
ret; \
})
#elif defined(__aarch64__)
#define ROTR(a, n) \
({ \
uint64_t ret; \
asm("ror %0,%1,%2" : "=r"(ret) : "r"(a), "I"(n)); \
ret; \
#define ROTR(a, n) \
({ \
uint64_t ret; \
__asm__("ror %0, %1, %2" : "=r"(ret) : "r"(a), "I"(n)); \
ret; \
})
#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define PULL64(x) \
({ \
uint64_t ret; \
asm("rev %0,%1" : "=r"(ret) : "r"(*((const uint64_t *)(&(x))))); \
ret; \
#define PULL64(x) \
({ \
uint64_t ret; \
__asm__("rev %0, %1" : "=r"(ret) : "r"(*((const uint64_t *)(&(x))))); \
ret; \
})
#endif
#endif
+2
View File
@@ -21,6 +21,7 @@
#include <memory>
#include <openssl/aead.h>
#include <openssl/asn1.h>
#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/cmac.h>
@@ -95,6 +96,7 @@ class ScopedOpenSSLContext {
T ctx_;
};
using ScopedASN1_TYPE = ScopedOpenSSLType<ASN1_TYPE, ASN1_TYPE_free>;
using ScopedBIO = ScopedOpenSSLType<BIO, BIO_vfree>;
using ScopedBIGNUM = ScopedOpenSSLType<BIGNUM, BN_free>;
using ScopedBN_CTX = ScopedOpenSSLType<BN_CTX, BN_CTX_free>;
+6 -1
View File
@@ -17,6 +17,7 @@
#if !defined(OPENSSL_WINDOWS) && !defined(OPENSSL_NO_THREADS)
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -74,7 +75,11 @@ void CRYPTO_STATIC_MUTEX_unlock(struct CRYPTO_STATIC_MUTEX *lock) {
}
void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)) {
pthread_once(once, init);
if (pthread_once(once, init) != 0) {
fprintf(stderr,
"pthread_once failed. Did you link against a threading library?\n");
abort();
}
}
static pthread_mutex_t g_destructors_lock = PTHREAD_MUTEX_INITIALIZER;
+1 -1
View File
@@ -98,7 +98,7 @@ static void free_dir(X509_LOOKUP *lu);
static int add_cert_dir(BY_DIR *ctx,const char *dir,int type);
static int get_cert_by_subject(X509_LOOKUP *xl,int type,X509_NAME *name,
X509_OBJECT *ret);
X509_LOOKUP_METHOD x509_dir_lookup=
static X509_LOOKUP_METHOD x509_dir_lookup=
{
"Load certs from files in a directory",
new_dir, /* new */
+1 -1
View File
@@ -68,7 +68,7 @@
static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
long argl, char **ret);
X509_LOOKUP_METHOD x509_file_lookup=
static X509_LOOKUP_METHOD x509_file_lookup=
{
"Load file into cache",
NULL, /* new */
+9 -2
View File
@@ -15,6 +15,7 @@
#include <openssl/x509.h>
#include <assert.h>
#include <limits.h>
#include <openssl/bytestring.h>
#include <openssl/err.h>
@@ -114,8 +115,11 @@ int PKCS7_get_certificates(STACK_OF(X509) *out_certs, CBS *cbs) {
goto err;
}
if (CBS_len(&cert) > LONG_MAX) {
goto err;
}
inp = CBS_data(&cert);
x509 = d2i_X509(NULL, &inp, CBS_len(&cert));
x509 = d2i_X509(NULL, &inp, (long)CBS_len(&cert));
if (!x509) {
goto err;
}
@@ -181,8 +185,11 @@ int PKCS7_get_CRLs(STACK_OF(X509_CRL) *out_crls, CBS *cbs) {
goto err;
}
if (CBS_len(&crl_data) > LONG_MAX) {
goto err;
}
inp = CBS_data(&crl_data);
crl = d2i_X509_CRL(NULL, &inp, CBS_len(&crl_data));
crl = d2i_X509_CRL(NULL, &inp, (long)CBS_len(&crl_data));
if (!crl) {
goto err;
}
+4 -14
View File
@@ -141,7 +141,6 @@ static int check_crl_chain(X509_STORE_CTX *ctx,
STACK_OF(X509) *crl_path);
static int internal_verify(X509_STORE_CTX *ctx);
const char X509_version[]="X.509";
static int null_callback(int ok, X509_STORE_CTX *e)
@@ -2093,14 +2092,14 @@ X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer,
return NULL;
}
int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
{
/* This function is (usually) called only once, by
* SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c). */
int index;
if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp,
new_func, dup_func, free_func))
dup_func, free_func))
{
return -1;
}
@@ -2267,19 +2266,13 @@ 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->cert=x509;
ctx->untrusted=chain;
if(!CRYPTO_new_ex_data(&g_ex_data_class, ctx,
&ctx->ex_data))
{
goto err;
}
ex_data_allocated = 1;
CRYPTO_new_ex_data(&ctx->ex_data);
ctx->param = X509_VERIFY_PARAM_new();
if (!ctx->param)
@@ -2363,10 +2356,7 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
return 1;
err:
if (ex_data_allocated)
{
CRYPTO_free_ex_data(&g_ex_data_class, ctx, &ctx->ex_data);
}
CRYPTO_free_ex_data(&g_ex_data_class, ctx, &ctx->ex_data);
if (ctx->param != NULL)
{
X509_VERIFY_PARAM_free(ctx->param);
+1 -1
View File
@@ -120,7 +120,7 @@ ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL)
* to the external form.
*/
const ASN1_EXTERN_FUNCS x509_name_ff = {
static const ASN1_EXTERN_FUNCS x509_name_ff = {
NULL,
x509_name_ex_new,
x509_name_ex_free,
+3 -3
View File
@@ -104,7 +104,7 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
ret->akid = NULL;
ret->aux = NULL;
ret->crldp = NULL;
CRYPTO_new_ex_data(&g_ex_data_class, ret, &ret->ex_data);
CRYPTO_new_ex_data(&ret->ex_data);
break;
case ASN1_OP_D2I_POST:
@@ -146,12 +146,12 @@ X509 *X509_up_ref(X509 *x)
return x;
}
int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
{
int index;
if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp,
new_func, dup_func, free_func))
dup_func, free_func))
{
return -1;
}
+11 -11
View File
@@ -55,17 +55,17 @@
/* This file contains a table of "standard" extensions */
extern X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku;
extern X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info, v3_sinfo;
extern X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id;
extern X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate;
extern X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld, v3_freshest_crl;
extern X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, v3_ocsp_acutoff;
extern X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc;
extern X509V3_EXT_METHOD v3_crl_hold, v3_pci;
extern X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints;
extern X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp;
extern X509V3_EXT_METHOD v3_addr, v3_asid;
extern const X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku;
extern const X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info, v3_sinfo;
extern const X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id;
extern const X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate;
extern const X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld, v3_freshest_crl;
extern const X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, v3_ocsp_acutoff;
extern const X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc;
extern const X509V3_EXT_METHOD v3_crl_hold, v3_pci;
extern const X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints;
extern const X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp;
extern const X509V3_EXT_METHOD v3_addr, v3_asid;
/* This table will be searched using OBJ_bsearch so it *must* kept in
* order of the ext_nid values.
+1 -9
View File
@@ -62,6 +62,7 @@
#pragma warning(pop)
#endif
#include "internal.h"
#include "../macros.h"
@@ -80,15 +81,6 @@ void CAST_ecb_encrypt(const uint8_t *in, uint8_t *out, const CAST_KEY *ks,
l2n(d[1], out);
}
extern const uint32_t CAST_S_table0[256];
extern const uint32_t CAST_S_table1[256];
extern const uint32_t CAST_S_table2[256];
extern const uint32_t CAST_S_table3[256];
extern const uint32_t CAST_S_table4[256];
extern const uint32_t CAST_S_table5[256];
extern const uint32_t CAST_S_table6[256];
extern const uint32_t CAST_S_table7[256];
#if defined(OPENSSL_WINDOWS) && defined(_MSC_VER)
#define ROTL(a, n) (_lrotl(a, n))
#else
+3
View File
@@ -56,6 +56,9 @@
#include <openssl/base.h>
#include "internal.h"
const uint32_t CAST_S_table0[256] = {
0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3,
0x6003e540, 0xcf9fc949, 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675,
+81
View File
@@ -0,0 +1,81 @@
/* 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.] */
#ifndef OPENSSL_HEADER_CAST_INTERNAL_H
#define OPENSSL_HEADER_CAST_INTERNAL_H
#include <openssl/base.h>
#if defined(__cplusplus)
extern "C" {
#endif
extern const uint32_t CAST_S_table0[256];
extern const uint32_t CAST_S_table1[256];
extern const uint32_t CAST_S_table2[256];
extern const uint32_t CAST_S_table3[256];
extern const uint32_t CAST_S_table4[256];
extern const uint32_t CAST_S_table5[256];
extern const uint32_t CAST_S_table6[256];
extern const uint32_t CAST_S_table7[256];
#if defined(__cplusplus)
} /* extern C */
#endif
#endif /* OPENSSL_HEADER_CAST_INTERNAL_H */
+23 -61
View File
@@ -56,12 +56,6 @@
#include "../crypto/modes/internal.h"
#if defined(OPENSSL_X86_64) || defined(OPENSSL_X86) || defined(OPENSSL_AARCH64)
#define STRICT_ALIGNMENT 0
#else
#define STRICT_ALIGNMENT 1
#endif
typedef struct xts128_context {
void *key1, *key2;
block128_f block1, block2;
@@ -70,10 +64,6 @@ typedef struct xts128_context {
static size_t CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx,
const uint8_t iv[16], const uint8_t *inp,
uint8_t *out, size_t len, int enc) {
const union {
long one;
char little;
} is_endian = {1};
union {
uint64_t u[2];
uint32_t d[4];
@@ -90,22 +80,22 @@ static size_t CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx,
if (!enc && (len % 16)) len -= 16;
while (len >= 16) {
#if defined(STRICT_ALIGNMENT)
#if STRICT_ALIGNMENT
memcpy(scratch.c, inp, 16);
scratch.u[0] ^= tweak.u[0];
scratch.u[1] ^= tweak.u[1];
#else
scratch.u[0] = ((unint64_t *)inp)[0] ^ tweak.u[0];
scratch.u[1] = ((unint64_t *)inp)[1] ^ tweak.u[1];
scratch.u[0] = ((uint64_t *)inp)[0] ^ tweak.u[0];
scratch.u[1] = ((uint64_t *)inp)[1] ^ tweak.u[1];
#endif
(*ctx->block1)(scratch.c, scratch.c, ctx->key1);
#if defined(STRICT_ALIGNMENT)
#if STRICT_ALIGNMENT
scratch.u[0] ^= tweak.u[0];
scratch.u[1] ^= tweak.u[1];
memcpy(out, scratch.c, 16);
#else
((unint64_t *)out)[0] = scratch.u[0] ^= tweak.u[0];
((unint64_t *)out)[1] = scratch.u[1] ^= tweak.u[1];
((uint64_t *)out)[0] = scratch.u[0] ^= tweak.u[0];
((uint64_t *)out)[1] = scratch.u[1] ^= tweak.u[1];
#endif
inp += 16;
out += 16;
@@ -113,26 +103,12 @@ static size_t CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx,
if (len == 0) return 1;
if (is_endian.little) {
unsigned int carry, res;
unsigned int carry, res;
res = 0x87 & (((int)tweak.d[3]) >> 31);
carry = (unsigned int)(tweak.u[0] >> 63);
tweak.u[0] = (tweak.u[0] << 1) ^ res;
tweak.u[1] = (tweak.u[1] << 1) | carry;
} else {
size_t c;
for (c = 0, i = 0; i < 16; ++i) {
/*
* + substitutes for |, because c is 1 bit
*/
c += ((size_t)tweak.c[i]) << 1;
tweak.c[i] = (uint8_t)c;
c = c >> 8;
}
tweak.c[0] ^= (uint8_t)(0x87 & (0 - c));
}
res = 0x87 & (((int)tweak.d[3]) >> 31);
carry = (unsigned int)(tweak.u[0] >> 63);
tweak.u[0] = (tweak.u[0] << 1) ^ res;
tweak.u[1] = (tweak.u[1] << 1) | carry;
}
if (enc) {
for (i = 0; i < len; ++i) {
@@ -152,33 +128,19 @@ static size_t CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx,
uint8_t c[16];
} tweak1;
if (is_endian.little) {
unsigned int carry, res;
unsigned int carry, res;
res = 0x87 & (((int)tweak.d[3]) >> 31);
carry = (unsigned int)(tweak.u[0] >> 63);
tweak1.u[0] = (tweak.u[0] << 1) ^ res;
tweak1.u[1] = (tweak.u[1] << 1) | carry;
} else {
size_t c;
for (c = 0, i = 0; i < 16; ++i) {
/*
* + substitutes for |, because c is 1 bit
*/
c += ((size_t)tweak.c[i]) << 1;
tweak1.c[i] = (uint8_t)c;
c = c >> 8;
}
tweak1.c[0] ^= (uint8_t)(0x87 & (0 - c));
}
#if defined(STRICT_ALIGNMENT)
res = 0x87 & (((int)tweak.d[3]) >> 31);
carry = (unsigned int)(tweak.u[0] >> 63);
tweak1.u[0] = (tweak.u[0] << 1) ^ res;
tweak1.u[1] = (tweak.u[1] << 1) | carry;
#if STRICT_ALIGNMENT
memcpy(scratch.c, inp, 16);
scratch.u[0] ^= tweak1.u[0];
scratch.u[1] ^= tweak1.u[1];
#else
scratch.u[0] = ((unint64_t *)inp)[0] ^ tweak1.u[0];
scratch.u[1] = ((unint64_t *)inp)[1] ^ tweak1.u[1];
scratch.u[0] = ((uint64_t *)inp)[0] ^ tweak1.u[0];
scratch.u[1] = ((uint64_t *)inp)[1] ^ tweak1.u[1];
#endif
(*ctx->block1)(scratch.c, scratch.c, ctx->key1);
scratch.u[0] ^= tweak1.u[0];
@@ -192,13 +154,13 @@ static size_t CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx,
scratch.u[0] ^= tweak.u[0];
scratch.u[1] ^= tweak.u[1];
(*ctx->block1)(scratch.c, scratch.c, ctx->key1);
#if defined(STRICT_ALIGNMENT)
#if STRICT_ALIGNMENT
scratch.u[0] ^= tweak.u[0];
scratch.u[1] ^= tweak.u[1];
memcpy(out, scratch.c, 16);
#else
((unint64_t *)out)[0] = scratch.u[0] ^ tweak.u[0];
((unint64_t *)out)[1] = scratch.u[1] ^ tweak.u[1];
((uint64_t *)out)[0] = scratch.u[0] ^ tweak.u[0];
((uint64_t *)out)[1] = scratch.u[1] ^ tweak.u[1];
#endif
}
@@ -286,7 +248,7 @@ static int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) {
}
static const EVP_CIPHER aes_256_xts = {
NID_aes_256_xts, 1 /* block_size */, 32 /* key_size */,
NID_aes_256_xts, 1 /* block_size */, 64 /* key_size (2 AES keys) */,
16 /* iv_len */, sizeof(EVP_AES_XTS_CTX),
EVP_CIPH_XTS_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_ALWAYS_CALL_INIT |
EVP_CIPH_CTRL_INIT | EVP_CIPH_CUSTOM_COPY,
+12 -12
View File
@@ -98,23 +98,15 @@ OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_gcm(void);
/* EVP_aead_aes_256_gcm is AES-256 in Galois Counter Mode. */
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_gcm(void);
/* EVP_aead_chacha20_poly1305 is the AEAD built from ChaCha20 and
* Poly1305 as described in RFC 7539. */
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305(void);
/* EVP_aead_chacha20_poly1305_old is an AEAD built from ChaCha20 and
* Poly1305 that is used in the experimental ChaCha20-Poly1305 TLS cipher
* suites. */
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305_old(void);
/* EVP_aead_chacha20_poly1305 is currently an alias for
* |EVP_aead_chacha20_poly1305_old|. In the future, the RFC 7539 version will
* take this name. */
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305(void);
/* EVP_aead_chacha20_poly1305_rfc7539 is the AEAD built from ChaCha20 and
* Poly1305 as described in RFC 7539.
*
* WARNING: this function is not ready yet. It will be renamed in the future to
* drop the _rfc7539 suffix. */
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305_rfc7539(void);
/* EVP_aead_aes_128_key_wrap is AES-128 Key Wrap mode. This should never be
* used except to interoperate with existing systems that use this mode.
*
@@ -339,6 +331,14 @@ OPENSSL_EXPORT int EVP_AEAD_CTX_get_iv(const EVP_AEAD_CTX *ctx,
const uint8_t **out_iv, size_t *out_len);
/* Deprecated functions. */
/* EVP_aead_chacha20_poly1305_rfc7539 calls |EVP_aead_chacha20_poly1305|.
*
* TODO(davidben): Remove this. */
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305_rfc7539(void);
#if defined(__cplusplus)
} /* extern C */
#endif
+3
View File
@@ -85,6 +85,9 @@ extern "C" {
#define V_ASN1_ANY -4 /* used in ASN1 template code */
#define V_ASN1_NEG 0x100 /* negative flag */
/* No supported universal tags may exceed this value, to avoid ambiguity with
* V_ASN1_NEG. */
#define V_ASN1_MAX_UNIVERSAL 0xff
#define V_ASN1_UNDEF -1
#define V_ASN1_EOC 0
+1 -5
View File
@@ -836,11 +836,7 @@ struct bignum_st {
struct bn_mont_ctx_st {
BIGNUM RR; /* used to convert to montgomery form */
BIGNUM N; /* The modulus */
BIGNUM Ni; /* R*(1/R mod N) - N*Ni = 1
* (Ni is only stored for bignum algorithm) */
BN_ULONG n0[2]; /* least significant word(s) of Ni;
(type changed with 0.9.9, was "BN_ULONG n0;" before) */
int ri; /* number of bits in R */
BN_ULONG n0[2]; /* least significant words of (R*Ri-1)/N */
};
OPENSSL_EXPORT unsigned BN_num_bits_word(BN_ULONG l);
+9 -10
View File
@@ -238,13 +238,13 @@ struct cbb_buffer_st {
struct cbb_st {
struct cbb_buffer_st *base;
/* offset is the offset from the start of |base->buf| to the position of any
* pending length-prefix. */
size_t offset;
/* child points to a child CBB if a length-prefix is pending. */
CBB *child;
/* pending_len_len contains the number of bytes in a pending length-prefix,
* or zero if no length-prefix is pending. */
/* offset is the number of bytes from the start of |base->buf| to this |CBB|'s
* pending length prefix. */
size_t offset;
/* pending_len_len contains the number of bytes in this |CBB|'s pending
* length-prefix, or zero if no length-prefix is pending. */
uint8_t pending_len_len;
char pending_is_asn1;
/* is_top_level is true iff this is a top-level |CBB| (as opposed to a child
@@ -292,12 +292,11 @@ OPENSSL_EXPORT int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len);
* on error. */
OPENSSL_EXPORT int CBB_flush(CBB *cbb);
/* CBB_len returns the number of bytes written to |cbb|'s top-level |CBB|. It
* may be compared before and after an operation to determine how many bytes
* were written.
/* CBB_len returns the number of bytes written to |cbb|. It does not flush
* |cbb|.
*
* It is a fatal error to call this on a CBB with any active children. This does
* not flush |cbb|. */
* To avoid unfinalized length prefixes, it is a fatal error to call this on a
* CBB with any active children. */
OPENSSL_EXPORT size_t CBB_len(const CBB *cbb);
/* CBB_add_u8_length_prefixed sets |*out_contents| to a new child of |cbb|. The

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