Compare commits

..

815 Commits

Author SHA1 Message Date
David Benjamin 1b5bcb59f4 Make CRYPTO_is_NEON_capable aware of the buggy CPU.
If we're to allow the buggy CPU workaround to fire when __ARM_NEON__ is set,
CRYPTO_is_NEON_capable also needs to be aware of it. Also add an API to export
this value out of BoringSSL, so we can get some metrics on how prevalent this
chip is.

BUG=chromium:606629

Change-Id: I97d65a47a6130689098b32ce45a8c57c468aa405
Reviewed-on: https://boringssl-review.googlesource.com/7796
Reviewed-by: Adam Langley <agl@google.com>
2016-04-29 14:24:33 -04:00
David Benjamin b69307a1c4 Don't set a default armcap state in dynamic armcap modes.
The getauxval (and friends) code would be filling that in anyway. The default
only serves to enable NEON even if the OS is old enough to be missing getauxval
(and everything else).

Notably, this unbreaks the has_buggy_neon code when __ARM_NEON__ is set, as is
the case in Chrome for Android, as of M50.  Before, the default
OPENSSL_armcap_P value was getting in the way.

Arguably, this doesn't make a whole lot of sense. We're saying we'll let the
CPU run compiler-generated NEON code, but not our hand-crafted stuff. But, so
far, we only have evidence of the hand-written NEON tickling the bug and not
the compiler-generated stuff, so avoid the unintentional regression. (Naively,
I would expect the hand-crafted NEON is better at making full use of the
pipeline and is thus more likely to tickle the CPU bug.)

This is not the fix for M50, as in the associated Chromium bug, but it will fix
master and M51. M50 will instead want to revert
https://codereview.chromium.org/1730823002.

BUG=chromium:606629

Change-Id: I394f97fea2f09891dd8fa30e0ec6fc6b1adfab7a
Reviewed-on: https://boringssl-review.googlesource.com/7794
Reviewed-by: Adam Langley <agl@google.com>
2016-04-29 14:24:26 -04:00
David Benjamin d44a943111 Fix docs typo.
Change-Id: Idb786ee2ca6354dcf2f665e9229aef4a43e05dd4
Reviewed-on: https://boringssl-review.googlesource.com/7614
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-31 22:15:51 +00:00
David Benjamin 046b27815e Decouple crypto/evp from the OID table.
BUG=chromium:499653

Change-Id: I4e8d4af3129dbf61d4a8846ec9db685e83999d5e
Reviewed-on: https://boringssl-review.googlesource.com/7565
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-31 22:12:46 +00:00
David Benjamin 0d76c402b8 Decouple crypto/ec from the OID table.
Instead, embed the (very short) encoding of the OID into built_in_curve.

BUG=chromium:499653

Change-Id: I0db36f83c71fbd3321831f54fa5022f8304b30cd
Reviewed-on: https://boringssl-review.googlesource.com/7564
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-31 22:12:09 +00:00
David Benjamin 981936791e Remove some easy obj.h dependencies.
A lot of consumers of obj.h only want the NID values. Others didn't need
it at all. This also removes some OBJ_nid2sn and OBJ_nid2ln calls in EVP
error paths which isn't worth pulling a large table in for.

BUG=chromium:499653

Change-Id: Id6dff578f993012e35b740a13b8e4f9c2edc0744
Reviewed-on: https://boringssl-review.googlesource.com/7563
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-31 20:50:33 +00:00
David Benjamin 5d38f78e29 Rename obj_mac.h to nid.h and make it a multiply-includable header.
obj_mac.h is missing #include guards, so one cannot use NIDs without
pulling in the OBJ_* functions which depend on the giant OID table. Give
it #include guards, tidy up the style slightly, and also rename it to
nid.h which is a much more reasonable name.

obj_mac.h is kept as a forwarding header as, despite it being a little
screwy, some code #includes it anyway.

BUG=chromium:499653

Change-Id: Iec0b3f186c02e208ff1f7437bf27ee3a5ad004b7
Reviewed-on: https://boringssl-review.googlesource.com/7562
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-31 20:45:35 +00:00
David Benjamin 66ec5c9066 Also re-serialize X509 objects in fuzz/cert.cc.
This is a fairly common operation on an X509.

Change-Id: I1820f20b555f75c98ab7e3283b5530bc1c200e2a
Reviewed-on: https://boringssl-review.googlesource.com/7611
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-31 19:37:53 +00:00
David Benjamin 20568e7a4f Remove inaccurate comments in fuzz/{client,server}.cc.
They now fuzz a lot more than just the initial flow.

Change-Id: Ib0b7eb66969442e539a937d7d87f5ba031fcbef3
Reviewed-on: https://boringssl-review.googlesource.com/7610
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-31 19:36:12 +00:00
David Benjamin 9e5eb63d01 Document that CRYPTO_library_init may be called concurrently.
This was fixed in 93a5b44296, but it wasn't
documented. Now that there are no pre-init functions to call like
CRYPTO_set_neon_capable, one instance of BoringSSL may be safely shared between
multiple consumers. As part of that, multiple consumers need to be able to call
CRYPTO_library_init possibly redundantlyand possibly on different threads
without synchronization.

(Though there is still that static initializer nuisance. It would be nice to
replace this with internal CRYPTO_once_t's and then CRYPTO_library_init need
only be called to prime armcap for a sandbox. But one thing at a time.)

Change-Id: I48430182d3649c8cf19082e34da24dee48e6119e
Reviewed-on: https://boringssl-review.googlesource.com/7571
Reviewed-by: Emily Stark (Dunn) <estark@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-31 19:35:53 +00:00
Brian Smith d879e29936 Further optimize Montgomery math in RSA blinding.
Change-Id: I830c6115ce2515a7b9d1dcb153c4cd8928fb978f
Reviewed-on: https://boringssl-review.googlesource.com/7591
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-31 19:35:33 +00:00
David Benjamin bfefc27c2b Avoid doing arithmetic on void pointers.
Whatever compiler settings AOSP is using warns that this is a GNU extension.

Change-Id: Ife395d2b206b607b14c713cbb5a94d479816dad0
Reviewed-on: https://boringssl-review.googlesource.com/7604
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-30 15:17:28 +00:00
David Benjamin 4b7b048417 Spell __attribute__((format(printf, ...))) with more underscores.
They may be spelled with or without underscores. Alas, a lot of C code (adb,
cURL) seems to find it a popular pasttime to #define printf *before* including
external headers. This is completely nonsense and invalid, but working around
it is easy and is what we (and OpenSSL) were doing before
061332f216.

I'll be sending a patch to cURL tomorrow to make them at least do their macro
trickery after external #includes for sanity. adb's sysdeps.h is a lot longer
and consistently #included first so I'll probably leave that be for lack of
time.

Change-Id: I03a0a253f2c902eb45f45faace1e5c5df4335ebf
Reviewed-on: https://boringssl-review.googlesource.com/7605
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-30 14:46:42 +00:00
David Benjamin aa0bea7bc1 Add additional poly1305 tests.
Thanks to Hanno Boeck for reporting them in
https://rt.openssl.org/Ticket/Display.html?id=4483

Change-Id: Ic902c0ceea32c76cad924a1ffc462d39ae6ca3de
Reviewed-on: https://boringssl-review.googlesource.com/7603
Reviewed-by: Emily Stark (Dunn) <estark@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-29 22:54:39 +00:00
David Benjamin 3c4a5cbb71 Revert "Enable upstream's Poly1305 code."
This reverts commit 6f0c4db90e except for the
imported assembly files, which are left as-is but unused. Until upstream fixes
https://rt.openssl.org/Ticket/Display.html?id=4483, we shouldn't ship this
code. Once that bug has been fixed, we'll restore it.

Change-Id: I74aea18ce31a4b79657d04f8589c18d6b17f1578
Reviewed-on: https://boringssl-review.googlesource.com/7602
Reviewed-by: Emily Stark (Dunn) <estark@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-29 22:47:11 +00:00
Brian Smith f08c1c6895 Drop support for custom |mod_exp| hooks in |RSA_METHOD|.
The documentation in |RSA_METHOD| says that the |ctx| parameter to
|mod_exp| can be NULL, however the default implementation doesn't
handle that case. That wouldn't matter since internally it is always
called with a non-NULL |ctx| and it is static, but an external
application could get a pointer to |mod_exp| by extracting it from
the default |RSA_METHOD|. That's unlikely, but making that impossible
reduces the chances that future refactorings will cause unexpected
trouble.

Change-Id: Ie0e35e9f107551a16b49c1eb91d0d3386604e594
Reviewed-on: https://boringssl-review.googlesource.com/7580
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-29 22:20:48 +00:00
Brian Smith 3426d10119 Convert RSA blinding to use Montgomery multiplication.
|BN_mod_mul_montgomery| has better constant-time behavior (usually)
than |BN_mod_mul| and |BN_mod_sqr| and on platforms where we have
assembly language optimizations (when |OPENSSL_BN_ASM_MONT| is set in
crypto/bn/montgomery.c) it is faster. While doing so, reorder and
rename the |BN_MONT_CTX| parameters of the blinding functions to match
the order normally used in Montgomery math functions.

As a bonus, remove a redundant copy of the RSA public modulus from the
|BN_BLINDING| structure, which reduces memory usage.

Change-Id: I70597e40246429c7964947a1dc46d0d81c7530ef
Reviewed-on: https://boringssl-review.googlesource.com/7524
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-29 22:07:22 +00:00
David Benjamin feaa57d13d Only call thread-local destructors on DLL_THREAD_DETACH.
In VS2015's debug runtime, the C runtime has been unloaded by the time
DLL_PROCESS_DETACH is called and things crash. Instead, don't run destructors
at that point.

This means we do *not* free memory associated with any remaining thread-locals
on application shutdown, only shutdown of individual threads. This is actually
desirable since it's consistent with pthreads. If an individual thread calls
pthread_exit, destructors are run. If the entire process exits, they are not.

(It's also consistent with thread_none.c which never bothers to free
anything.)

BUG=chromium:595795

Change-Id: I3e64d46ea03158fefff583c1e3e12dfa0c0e172d
Reviewed-on: https://boringssl-review.googlesource.com/7601
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-29 18:45:32 +00:00
David Benjamin 1e4ae00ac2 Add a comment about final empty extension intolerance.
We reordered extensions some time ago to ensure a non-empty extension was last,
but the comment was since lost (or I forgot to put one in in the first place).
Add one now so we don't regress.

Change-Id: I2f6e2c3777912eb2c522a54bbbee579ee37ee58a
Reviewed-on: https://boringssl-review.googlesource.com/7570
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-29 00:46:05 +00:00
Brian Smith 44477c03b9 Fix |BN_CTX_get| error checking in |BN_from_montgomery|.
In the case |BN_CTX_get| failed, the function returned without calling
|BN_CTX_end|. Fix that.

Change-Id: Ia24cba3256e2cec106b539324e9679d690048780
Reviewed-on: https://boringssl-review.googlesource.com/7592
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-29 00:44:10 +00:00
Brian Smith 9d354693ff Small tweak to P-256-x86-64 inversion.
Change-Id: I2a55db93e6140a0adc741b4ee5ee090d524605e0
Reviewed-on: https://boringssl-review.googlesource.com/7593
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-29 00:43:01 +00:00
David Benjamin 040ff622dc Remove duplicate BN_from_montgomery_word implementation.
It looks like we started reformatting that function and adding curly braces,
etc., but forget to finish it. This is corroborated by the diff. Although git
thinks I removed the EAY-style one and tweaked the #if-0'd one, I actually
clang-formatted the EAY-style one anew and deleted the #if-0'd one after
tweaking the style to match. Only difference is the alignment stuff is
uintptr_t rather than intptr_t since the old logic was using unsigned
arithmetic.

Change-Id: Ia244e4082a6b6aed3ef587d392d171382c32db33
Reviewed-on: https://boringssl-review.googlesource.com/7574
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-29 00:27:32 +00:00
Brian Smith 95cc3bea3b Remove dead code from |ec_GFp_mont_point_get_affine_coordinates|.
This code is only used in ec_montgomery.c, so |field_encode| and
|field_decode| are never NULL.

Change-Id: I42a3ad5744d4ed6f0be1707494411e7efcf930ff
Reviewed-on: https://boringssl-review.googlesource.com/7585
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-28 17:22:29 +00:00
Brian Smith a00f845434 Move & rename |ec_GFp_simple_point_get_affine_coordinates|.
It is only used in ec_montgomery.c, so move it there.

Change-Id: Ib189d5579d6363bdc1da89b775ad3df824129758
Reviewed-on: https://boringssl-review.googlesource.com/7584
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-28 17:21:32 +00:00
David Benjamin b7c5e84847 Fix some malloc test failures.
These only affect the tests.

Change-Id: If22d047dc98023501c771787b485276ece92d4a2
Reviewed-on: https://boringssl-review.googlesource.com/7573
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-28 17:17:32 +00:00
David Benjamin e29ea166a6 Use ssl3_is_version_enabled to skip offering sessions.
We do an ad-hoc upper-bound check, but if the version is too low, we also
shouldn't offer the session. This isn't fatal to the connection and doesn't
have issues (we'll check the version later regardless), but offering a session
we're never going to accept is pointless. The check should match what we do in
ServerHello.

Credit to Matt Caswell for noticing the equivalent issue in an OpenSSL pull
request.

Change-Id: I17a4efd37afa63b34fca53f4c9b7ac3ae2fa3336
Reviewed-on: https://boringssl-review.googlesource.com/7543
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-28 16:01:37 +00:00
David Benjamin 762e1d039c Import chacha-x86.pl fix.
Patch from https://mta.openssl.org/pipermail/openssl-dev/2016-March/005625.html.

Upstream has yet to make a decision on aliasing requirements for their
assembly. If they choose to go with the stricter aliasing requirement rather
than land this patch, we'll probably want to tweak EVP_AEAD's API guarantees
accordingly and then undiverge.

In the meantime, import this to avoid a regression on x86 from when we had
compiler-vectorized code on GCC platforms.  Per our assembly coverage tools and
pending multi-CPU-variant tests, we have good coverage here. Unlike Poly1305
(which is currently waiting on yet another upstream bugfix), where there is
risk of missed carries everywhere, it is much more difficult to accidentally
make a ChaCha20 implementation that fails based on the data passed into it.

This restores a sizeable speed improvement on x86.

Before:
Did 1131000 ChaCha20-Poly1305 (16 bytes) seal operations in 1000205us (1130768.2 ops/sec): 18.1 MB/s
Did 161000 ChaCha20-Poly1305 (1350 bytes) seal operations in 1006136us (160018.1 ops/sec): 216.0 MB/s
Did 28000 ChaCha20-Poly1305 (8192 bytes) seal operations in 1023264us (27363.4 ops/sec): 224.2 MB/s
Did 1166000 ChaCha20-Poly1305-Old (16 bytes) seal operations in 1000447us (1165479.0 ops/sec): 18.6 MB/s
Did 160000 ChaCha20-Poly1305-Old (1350 bytes) seal operations in 1004818us (159232.8 ops/sec): 215.0 MB/s
Did 30000 ChaCha20-Poly1305-Old (8192 bytes) seal operations in 1016977us (29499.2 ops/sec): 241.7 MB/s

After:
Did 2208000 ChaCha20-Poly1305 (16 bytes) seal operations in 1000031us (2207931.6 ops/sec): 35.3 MB/s
Did 402000 ChaCha20-Poly1305 (1350 bytes) seal operations in 1001717us (401310.9 ops/sec): 541.8 MB/s
Did 97000 ChaCha20-Poly1305 (8192 bytes) seal operations in 1005394us (96479.6 ops/sec): 790.4 MB/s
Did 2444000 ChaCha20-Poly1305-Old (16 bytes) seal operations in 1000089us (2443782.5 ops/sec): 39.1 MB/s
Did 459000 ChaCha20-Poly1305-Old (1350 bytes) seal operations in 1000563us (458741.7 ops/sec): 619.3 MB/s
Did 97000 ChaCha20-Poly1305-Old (8192 bytes) seal operations in 1007942us (96235.7 ops/sec): 788.4 MB/s

Change-Id: I976da606dae062a776e0cc01229ec03a074035d1
Reviewed-on: https://boringssl-review.googlesource.com/7561
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-28 15:58:24 +00:00
David Benjamin 17d729e61b Remove unnecessary include.
Change-Id: I24d0179ca5019e82ca1494c8773f373f8c09ce82
Reviewed-on: https://boringssl-review.googlesource.com/7566
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-28 15:57:17 +00:00
David Benjamin 2aca226412 Fix typo in comment.
Change-Id: I0effe99d244c4ccdbb0e34db6e01a59c9463cb15
Reviewed-on: https://boringssl-review.googlesource.com/7572
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-28 15:57:00 +00:00
David Benjamin baca950e8e Remove in_handshake.
The removes the last of OpenSSL's variables that count occurrences of a
function on the stack.

Change-Id: I1722c6d47bedb47b1613c4a5da01375b5c4cc220
Reviewed-on: https://boringssl-review.googlesource.com/7450
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-26 20:24:28 +00:00
David Benjamin c79845c2a8 Move implicit handshake driving out of read_bytes.
This removes the final use of in_handshake. Note that there is still a
rentrant call of read_bytes -> handshake_func when we see a
HelloRequest. That will need to be signaled up to ssl_read_impl
separately out of read_app_data.

Change-Id: I823de243f75e6b73eb40c6cf44157b4fc21eb8fb
Reviewed-on: https://boringssl-review.googlesource.com/7439
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-26 20:23:25 +00:00
David Benjamin b2a7318858 Switch some 0s to NULLs.
Change-Id: Id89c982f8f524720f189b528c987c9e58ca06ddf
Reviewed-on: https://boringssl-review.googlesource.com/7438
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-26 20:19:53 +00:00
David Benjamin d7ac143814 Lift the handshake driving in write_bytes up to SSL_write.
This removes one use of in_handshake and consolidates some DTLS and TLS
code.

Change-Id: Ibbdd38360a983dabfb7b18c7bd59cb5e316b2adb
Reviewed-on: https://boringssl-review.googlesource.com/7435
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-26 20:09:37 +00:00
David Benjamin 282511d7eb Consolidate shutdown state.
fatal_alert isn't read at all right now, and warn_alert is only checked
for close_notify. We only need three states:

 - Not shutdown.
 - Got a fatal alert (don't care which).
 - Got a warning close_notify.

Leave ssl->shutdown alone for now as it's tied up with SSL_set_shutdown
and friends. To distinguish the remaining two, we only need a boolean.

Change-Id: I5877723af82b76965c75cefd67ec1f981242281b
Reviewed-on: https://boringssl-review.googlesource.com/7434
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-26 20:04:34 +00:00
David Benjamin a2d4c0c426 Work around Android devices without AT_HWCAP2.
Some ARMv8 Android devices don't have AT_HWCAP2. This means, when running in
32-bit mode (ARM capability APIs on Linux are different between AArch32 and
AArch64), we can't discover the various nice instructions.

On a Nexus 6P, this gives a, uh, minor performance win when running in 32-bit
mode.

Before:
Did 1085000 AES-128-GCM (16 bytes) seal operations in 1000003us (1084996.7 ops/sec): 17.4 MB/s
Did 60000 AES-128-GCM (1350 bytes) seal operations in 1013416us (59205.7 ops/sec): 79.9 MB/s
Did 11000 AES-128-GCM (8192 bytes) seal operations in 1019778us (10786.7 ops/sec): 88.4 MB/s
Did 1009000 AES-256-GCM (16 bytes) seal operations in 1000650us (1008344.6 ops/sec): 16.1 MB/s
Did 49000 AES-256-GCM (1350 bytes) seal operations in 1015698us (48242.7 ops/sec): 65.1 MB/s
Did 9394 AES-256-GCM (8192 bytes) seal operations in 1071104us (8770.4 ops/sec): 71.8 MB/s
Did 1557000 SHA-1 (16 bytes) operations in 1000317us (1556506.6 ops/sec): 24.9 MB/s
Did 762000 SHA-1 (256 bytes) operations in 1000527us (761598.6 ops/sec): 195.0 MB/s
Did 45000 SHA-1 (8192 bytes) operations in 1013773us (44388.6 ops/sec): 363.6 MB/s
Did 1459000 SHA-256 (16 bytes) operations in 1000271us (1458604.7 ops/sec): 23.3 MB/s
Did 538000 SHA-256 (256 bytes) operations in 1000990us (537467.9 ops/sec): 137.6 MB/s
Did 26000 SHA-256 (8192 bytes) operations in 1008403us (25783.3 ops/sec): 211.2 MB/s

After:
Did 1890000 AES-128-GCM (16 bytes) seal operations in 1000068us (1889871.5 ops/sec): 30.2 MB/s
Did 509000 AES-128-GCM (1350 bytes) seal operations in 1000112us (508943.0 ops/sec): 687.1 MB/s
Did 110000 AES-128-GCM (8192 bytes) seal operations in 1007966us (109130.7 ops/sec): 894.0 MB/s
Did 1960000 AES-256-GCM (16 bytes) seal operations in 1000303us (1959406.3 ops/sec): 31.4 MB/s
Did 460000 AES-256-GCM (1350 bytes) seal operations in 1001873us (459140.0 ops/sec): 619.8 MB/s
Did 97000 AES-256-GCM (8192 bytes) seal operations in 1005337us (96485.1 ops/sec): 790.4 MB/s
Did 1927000 SHA-1 (16 bytes) operations in 1000429us (1926173.7 ops/sec): 30.8 MB/s
Did 1151000 SHA-1 (256 bytes) operations in 1000425us (1150511.0 ops/sec): 294.5 MB/s
Did 87000 SHA-1 (8192 bytes) operations in 1003089us (86732.1 ops/sec): 710.5 MB/s
Did 2357390 SHA-256 (16 bytes) operations in 1000116us (2357116.6 ops/sec): 37.7 MB/s
Did 1410000 SHA-256 (256 bytes) operations in 1000176us (1409751.9 ops/sec): 360.9 MB/s
Did 101000 SHA-256 (8192 bytes) operations in 1007007us (100297.2 ops/sec): 821.6 MB/s

BUG=chromium:596156

Change-Id: Iacc1f8d8a07e991d4615f2e12c5c54923fb31aa2
Reviewed-on: https://boringssl-review.googlesource.com/7507
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-26 04:56:45 +00:00
David Benjamin 054e151b16 Rewrite ARM feature detection.
This removes the thread-unsafe SIGILL-based detection and the
multi-consumer-hostile CRYPTO_set_NEON_capable API. (Changing
OPENSSL_armcap_P after initialization is likely to cause problems.)

The right way to detect ARM features on Linux is getauxval. On aarch64,
we should be able to rely on this, so use it straight. Split this out
into its own file. The #ifdefs in the old cpu-arm.c meant it shared all
but no code with its arm counterpart anyway.

Unfortunately, various versions of Android have different missing APIs, so, on
arm, we need a series of workarounds. Previously, we used a SIGILL fallback
based on OpenSSL's logic, but this is inherently not thread-safe. (SIGILL also
does not tell us if the OS knows how to save and restore NEON state.) Instead,
base the behavior on Android NDK's cpu-features library, what Chromium
currently uses with CRYPTO_set_NEON_capable:

- Android before API level 20 does not provide getauxval. Where missing,
  we can read from /proc/self/auxv.

- On some versions of Android, /proc/self/auxv is also not readable, so
  use /proc/cpuinfo's Features line.

- Linux only advertises optional features in /proc/cpuinfo. ARMv8 makes NEON
  mandatory, so /proc/cpuinfo can't be used without additional effort.

Finally, we must blacklist a particular chip because the NEON unit is broken
(https://crbug.com/341598).

Unfortunately, this means CRYPTO_library_init now depends on /proc being
available, which will require some care with Chromium's sandbox. The
simplest solution is to just call CRYPTO_library_init before entering
the sandbox.

It's worth noting that Chromium's current EnsureOpenSSLInit function already
depends on /proc/cpuinfo to detect the broken CPU, by way of base::CPU.
android_getCpuFeatures also interally depends on it. We were already relying on
both of those being stateful and primed prior to entering the sandbox.

BUG=chromium:589200

Change-Id: Ic5d1c341aab5a614eb129d8aa5ada2809edd6af8
Reviewed-on: https://boringssl-review.googlesource.com/7506
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-26 04:54:44 +00:00
Brian Smith dc6c1b8381 Fix build when using Visual Studio 2015 Update 1.
Many of the compatibility issues are described at
https://msdn.microsoft.com/en-us/library/mt612856.aspx. The macros
that suppressed warnings on a per-function basis no longer work in
Update 1, so replace them with #pragmas. Update 1 warns when |size_t|
arguments to |printf| are casted, so stop doing that casting.
Unfortunately, this requires an ugly hack to continue working in
MSVC 2013 as MSVC 2013 doesn't support "%zu". Finally, Update 1 has new
warnings, some of which need to be suppressed.

---

Updated by davidben to give up on suppressing warnings in crypto/x509 and
crypto/x509v3 as those directories aren't changed much from upstream. In each
of these cases, upstream opted just blindly initialize the variable, so do the
same. Also switch C4265 to level 4, per Microsoft's recommendation and work
around a bug in limits.h that happens to get fixed by Google include order
style.

(limits.h is sensitive to whether corecrt.h, pulled in by stddef.h and some
other headers, is included before it. The reason it affected just one file is
we often put the file's header first, which means base.h is pulling in
stddef.h. Relying on this is ugly, but it's no worse than what everything else
is doing and this doesn't seem worth making something as tame as limits.h so
messy to use.)

Change-Id: I02d1f935356899f424d3525d03eca401bfa3e6cd
Reviewed-on: https://boringssl-review.googlesource.com/7480
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-25 21:39:52 +00:00
David Benjamin db50299b24 Add tests for RSA objects with only n and d.
Conscrypt, thanks to Java's RSAPrivateKeySpec API, must be able to use RSA keys
with only modulus and exponent. This is kind of silly and breaks the blinding
code so they, both in OpenSSL and BoringSSL, had to explicitly turn blinding
off.

Add a test for this as we're otherwise sure to break it on accident.

We may wish to avoid the silly rsa->flags modification, I'm not sure. For now,
keep the requirement in so other consumers do not accidentally rely on this.

(Also add a few missing ERR_clear_error calls. Functions which are expected to
fail should be followed by an ERR_clear_error so later unexpected failures
don't get confused.)

BUG=boringssl:12

Change-Id: I674349821f1f59292b8edd085f21dc37e8bcaa75
Reviewed-on: https://boringssl-review.googlesource.com/7560
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-25 20:52:17 +00:00
Brian Smith cbf56a5683 Clarify lifecycle of |BN_BLINDING|.
In |bn_blinding_update| the condition |b->e != NULL| would never be
true (probably), but the test made reasoning about the correctness of
the code confusing. That confusion was amplified by the circuitous and
unusual way in which |BN_BLINDING|s are constructed. Clarify all this
by simplifying the construction of |BN_BLINDING|s, making it more like
the construction of other structures.

Also, make counter unsigned as it is no longer ever negative.

Change-Id: I6161dcfeae19a80c780ccc6762314079fca1088b
Reviewed-on: https://boringssl-review.googlesource.com/7530
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-25 20:08:04 +00:00
Brian Smith 24493a4ff4 Always cache Montgomery contexts in RSA.
Simplify the code by always caching Montgomery contexts in the RSA
structure, regardless of the |RSA_FLAG_CACHE_PUBLIC| and
|RSA_FLAG_CACHE_PRIVATE| flags. Deprecate those flags.

Now that we do this no more than once per key per RSA exponent, the
private key exponents better because the initialization of the
Montgomery contexts isn't perfectly side-channel protected.

Change-Id: I4fbcfec0f2f628930bfeb811285b0ae3d103ac5e
Reviewed-on: https://boringssl-review.googlesource.com/7521
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-25 20:04:24 +00:00
David Benjamin 4339552fbb Flip the arguments to ExpectBytesEqual in poly1305_test.
The function wants the expected value first.

Change-Id: I6d3e21ebfa55d6dd99a34fe8380913641b4f5ff6
Reviewed-on: https://boringssl-review.googlesource.com/7501
Reviewed-by: Emily Stark (Dunn) <estark@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-24 19:30:47 +00:00
David Benjamin 270f0a7761 Print an error if no tests match in runner.
Otherwise it's confusing if you mistype the test name.

Change-Id: Idf32081958f85f3b5aeb8993a07f6975c27644f8
Reviewed-on: https://boringssl-review.googlesource.com/7500
Reviewed-by: Emily Stark (Dunn) <estark@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-24 19:30:29 +00:00
David Benjamin 4c34026d12 Fix poly1305-x86.pl.
Imported from patch attached to
https://rt.openssl.org/Ticket/Display.html?id=4439.

But with the extra vs $extra typo fixed.

The root problem appears to be that lazy_reduction tries to use paddd instead
of paddq when they believe the sum will not overflow a u32. In the final call
to lazy_reduction, this is not true. svaldez and I attempted to work through
the bounds, but the bounds derived from the cited paper imply paddd is always
fine. Empirically in a debugger, the bounds are exceeded in the test case.

I requested more comments from upstream on the bug. When upstream lands their
final fix (hopefully with comments), I will update this code. In the meantime,
let's stop carrying known-broken stuff.

(vlazy_reduction is probably something similar, but since we don't enable that
code, we haven't bothered analyzing it.)

Also add the smaller of the two test cases that catch the bug. (The other uses
an update pattern which isn't quite what poly1305_test does.)

Change-Id: I446ed47c21f10b41a0745de96ab119a3f6fd7801
Reviewed-on: https://boringssl-review.googlesource.com/7544
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-24 15:04:23 +00:00
Piotr Sikora fdb88ba2e9 Fix build with -Wwrite-strings.
Change-Id: If76154c8d255600e925a408acdc674fc7dad0359
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
Reviewed-on: https://boringssl-review.googlesource.com/7526
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-24 03:11:20 +00:00
Matt Mueller 897be6afe3 Add CBS_ASN1_UTF8STRING define.
Change-Id: I34384feb46c15c4f443f506d724ad500a4cf0f36
Reviewed-on: https://boringssl-review.googlesource.com/7525
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-23 19:29:49 +00:00
Steven Valdez 0a0f83d308 Fixing assembly coverage
We failed to correctly parse files that executed from the very start of
the file due to a missing '- line XXX'. We now use the 'Ir' indicator to
recognize the beginning of a file.

Change-Id: I529fae9458ac634bf7bf8af61ef18f080e808535
Reviewed-on: https://boringssl-review.googlesource.com/7542
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-23 18:23:42 +00:00
Brian Smith afd6d9d61a Use |size_t| and |int| consistently in p{224,256}-64.c.
Use |size_t| for array indexes. Use |int| for boolean flags. Declare
the variables that had their types changed closer to where they are
used.

Previously, some `for` loops depended on `i` being signed, so their
structure had to be changed to work with the unsigned type.

Change-Id: I247e4f04468419466733b6818d81d28666da0ad3
Reviewed-on: https://boringssl-review.googlesource.com/7468
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-22 23:28:08 +00:00
David Benjamin 9539ebbf70 Update FUZZING documentation about max_len.
Maintain the max_len values in foo.options files which ClusterFuzz can process.
Also recompute the recommended client and server lengths as they've since
gotten much more extensive.

Change-Id: Ie87a80d8a4a0c41e215f0537c8ccf82b38c4de09
Reviewed-on: https://boringssl-review.googlesource.com/7509
Reviewed-by: Mike Aizatsky <aizatsky@chromium.org>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-22 18:46:35 +00:00
David Benjamin 78f8aabe44 ssl->ctx cannot be NULL.
Most code already dereferences it directly.

Change-Id: I227fa91ecbf25a19077f7cfba21b0abd2bc2bd1d
Reviewed-on: https://boringssl-review.googlesource.com/7422
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-22 15:24:10 +00:00
Steven Valdez c087c332f8 Fix potential double free in EVP_DigestInit_ex
There is a potential double free in EVP_DigestInit_ex. This is believed
to be reached only as a result of programmer error - but we should fix it
anyway.

(Imported from upstream's e78dc7e279ed98e1ab9845a70d14dafdfdc88f58)

Change-Id: I1da7be7db7afcbe9f30f168df000d64ed73d7edd
Reviewed-on: https://boringssl-review.googlesource.com/7541
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-22 15:17:32 +00:00
David Benjamin be12248829 Fix aarch64 build.
We recently gained -Werror=missing-prototypes. (See also, we really need to get
those Android bots...)

Change-Id: I3962d3050bccf5f5a057d029b5cbff1695ca1a03
Reviewed-on: https://boringssl-review.googlesource.com/7540
Reviewed-by: Emily Stark (Dunn) <estark@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-21 22:56:55 +00:00
Brian Smith 95b9769340 Fix error handling in |bn_blinding_update|.
The fields of the |bn_blinding_st| are not updated atomically.
Consequently, one field (|A| or |Ai|) might get updated while the
other field (|Ai| or |A|) doesn't get updated, if an error occurs in
the middle of updating. Deal with this by reseting the counter so that
|A| and |Ai| will both get recreated the next time the blinding is
used.

Fix a separate but related issue by resetting the counter to zero after
calling |bn_blinding_create_param| only if |bn_blinding_create_param|
succeeded. Previously, regardless of whether an error occured in
|bn_blinding_create_param|, |b->counter| would get reset to zero. The
consequence of this was that potentially-bad blinding values would get
used 32 times instead of (32 - |b->counter|) times.

Change-Id: I236cdb6120870ef06cba129ed86619f593cbcf3d
Reviewed-on: https://boringssl-review.googlesource.com/7520
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-21 20:26:21 +00:00
David Benjamin e11988f511 Tweak FUZZING.md and minimise_corpuses.sh.
Change-Id: If312ce3783bcc39ebd2047470251334aa0897d3d
Reviewed-on: https://boringssl-review.googlesource.com/7508
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-21 20:23:15 +00:00
Brian Smith fdc955cf14 Fix parameter type of p256-64.c's |select_point|.
Make it match how it is done in p224-64.c. Note in particular that
|size| may be 17, so presumably |pre_comp[16]| is accessed, which one
would not expect when it was declared |precomp[16][3]|.

Change-Id: I54c1555f9e20ccaacbd4cd75a7154b483b4197b7
Reviewed-on: https://boringssl-review.googlesource.com/7467
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-20 17:18:35 +00:00
Brian Smith df1201e6ee Remove unnecessary |BN_CTX_start|/|BN_CTX_end| in |BN_mod_exp_mont_consttime|.
Since the function doesn't call |BN_CTX_get|, it doesn't need to call
|BN_CTX_start|/|BN_CTX_end|.

Change-Id: I6cb954d3fee2959bdbc81b9b97abc52bb6f7704c
Reviewed-on: https://boringssl-review.googlesource.com/7469
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-20 17:16:27 +00:00
Brian Smith 7cf6085b00 Check for |BN_CTX_new| failure in |mod_exp|.
As far as I can tell, this is the last place within libcrypto where
this type of check is missing.

Change-Id: I3d09676abab8c9f6c4e87214019a382ec2ba90ee
Reviewed-on: https://boringssl-review.googlesource.com/7519
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-20 17:09:51 +00:00
Piotr Sikora 35673b945d Build with -Wmissing-prototypes -Wmissing-declarations.
Change-Id: Ieba81f114483095f3657e87f669c7562ff75b58c
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
Reviewed-on: https://boringssl-review.googlesource.com/7516
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-20 17:05:03 +00:00
Piotr Sikora f932894c7f Move function declarations to internal header.
Partially fixes build with -Wmissing-declarations.

Change-Id: Ia563063fb077cda79244c21f02fd1c0f550353c2
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
Reviewed-on: https://boringssl-review.googlesource.com/7515
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-20 16:56:32 +00:00
Piotr Sikora f188f9dce8 Fix typo in function name.
Partially fixes build with -Wmissing-prototypes.

Change-Id: I828bcfb49b23c5a9ea403038bc3fb76750556ef8
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
Reviewed-on: https://boringssl-review.googlesource.com/7514
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-20 16:55:41 +00:00
David Benjamin cd4cf9a12e Fix Windows build
Change-Id: I66ecb9f89ec13e432e888e3825d01a015b117568
Reviewed-on: https://boringssl-review.googlesource.com/7505
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-20 16:46:10 +00:00
Piotr Sikora 8b0fe8c0ac Add missing prototypes.
Partially fixes build with -Wmissing-prototypes.

Change-Id: If04d8fe7cbf068883485e95bd5ea6cdab6743e46
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
Reviewed-on: https://boringssl-review.googlesource.com/7513
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-20 16:43:50 +00:00
Piotr Sikora c6d3029eda Add missing internal includes.
Partially fixes build with -Wmissing-prototypes -Wmissing-declarations.

Change-Id: I51209c30f532899f57cfdd9a50cff0a8ee3da5b5
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
Reviewed-on: https://boringssl-review.googlesource.com/7512
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-20 16:38:54 +00:00
Piotr Sikora 9bb8ba6ba1 Make local functions static.
Partially fixes build with -Wmissing-prototypes -Wmissing-declarations.

Change-Id: I6048f5b7ef31560399b25ed9880156bc7d8abac2
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
Reviewed-on: https://boringssl-review.googlesource.com/7511
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-20 16:37:58 +00:00
Piotr Sikora 537cfc37b8 Use UINT64_C instead of unsigned long long integer constant.
Change-Id: I44aa9be26ad9aea6771cb46a886a721b4bc28fde
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
Reviewed-on: https://boringssl-review.googlesource.com/7510
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-18 23:04:48 +00:00
David Benjamin 594e7d2b77 Add a test that declining ALPN works.
Inspired by https://mta.openssl.org/pipermail/openssl-dev/2016-March/006150.html

Change-Id: I973b3baf054ed1051002f7bb9941cb1deeb36d78
Reviewed-on: https://boringssl-review.googlesource.com/7504
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-18 19:47:46 +00:00
David Benjamin f277add6c2 Run ripemd_test as part of all_tests.go.
Change-Id: I9c5e66c34d0f1b735c69d033daee5d312e3c2fe7
Reviewed-on: https://boringssl-review.googlesource.com/7410
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-17 21:37:14 +00:00
David Benjamin 110fcc9607 poly1305/asm/poly1305-x86_64.pl: make it work with linux-x32.
(Imported from upstream's 2460c7f13389d766dd65fa4e14b69b6fbe3e4e3b.)

This is a no-op for us, but avoid a diff with upstream.

Change-Id: I6e875704a38dcd9339371393a4dd523647aeef44
Reviewed-on: https://boringssl-review.googlesource.com/7491
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-17 18:33:18 +00:00
David Benjamin eebfd896fe Don't shift serial number into sign bit
(Imported from upstream's 01c32b5e448f6d42a23ff16bdc6bb0605287fa6f.)

Change-Id: Ib52278dbbac1ed1ad5c80f0ad69e34584d411cec
Reviewed-on: https://boringssl-review.googlesource.com/7461
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-17 18:23:49 +00:00
David Benjamin 8d5717b019 perlasm/x86_64-xlate.pl: handle binary constants early.
Not all assemblers of "gas" flavour handle binary constants, e.g.
seasoned MacOS Xcode doesn't, so give them a hand.

(Imported from upstream's ba26fa14556ba49466d51e4d9e6be32afee9c465.)

Change-Id: I35096dc8035e06d2fbef2363b869128da206ff9d
Reviewed-on: https://boringssl-review.googlesource.com/7459
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-17 18:23:40 +00:00
David Benjamin 51545ceac6 Remove a number of unnecessary stdio.h includes.
Change-Id: I6267c9bfb66940d0b6fe5368514210a058ebd3cc
Reviewed-on: https://boringssl-review.googlesource.com/7494
Reviewed-by: Emily Stark (Dunn) <estark@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-17 18:22:28 +00:00
David Benjamin b371f1b9dd Include time.h in time_support.h.
For time_t and struct tm.

BUG=595118

Change-Id: I6c7f05998887ed2bd3fb56c83ac543894ef27fe6
Reviewed-on: https://boringssl-review.googlesource.com/7462
Reviewed-by: Emily Stark (Dunn) <estark@google.com>
Reviewed-by: Nico Weber <thakis@chromium.org>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-17 17:27:27 +00:00
Brian Smith 9aa1562843 Remove unnecessary type casts in crypto/rsa.
Change-Id: I0b5c661674fbcaf6b4d5b0ce7944459cd45606b1
Reviewed-on: https://boringssl-review.googlesource.com/7466
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-15 23:06:01 +00:00
David Benjamin 6f7374b0ed Restore EC_GROUP_new_by_curve_name and EC_GROUP_set_generator.
Having a different API for this case than upstream is more trouble than is
worth it. This is sad since the new API avoids incomplete EC_GROUPs at least,
but I don't believe supporting this pair of functions will be significantly
more complex than supporting EC_GROUP_new_arbitrary even when we have static
EC_GROUPs.

For now, keep both sets of APIs around, but we'll be able to remove the scar
tissue once Conscrypt's complex dependencies are resolved.

Make the restored EC_GROUP_set_generator somewhat simpler than before by
removing the ability to call it multiple times and with some parameters set to
NULL. Keep the test.

Change-Id: I64e3f6a742678411904cb15c0ad15d56cdae4a73
Reviewed-on: https://boringssl-review.googlesource.com/7432
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-15 18:53:12 +00:00
Emily Stark 5c05648b8d Tiny documentation fix for EC_POINT_set_affine_coordinates_GFp
Change-Id: Icfd9986272f6e1adba54aa7521c28901fa02dfb7
Reviewed-on: https://boringssl-review.googlesource.com/7470
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-15 18:42:08 +00:00
David Benjamin a2f2bc3a40 Align with upstream's error strings, take two.
I messed up a few of these.

ASN1_R_UNSUPPORTED_ALGORITHM doesn't exist. X509_R_UNSUPPORTED_ALGORITHM does
exist as part of X509_PUBKEY_set, but the SPKI parser doesn't emit this. (I
don't mind the legacy code having really weird errors, but since EVP is now
limited to things we like, let's try to keep that clean.) To avoid churn in
Conscrypt, we'll keep defining X509_R_UNSUPPORTED_ALGORITHM, but not actually
do anything with it anymore.  Conscrypt was already aware of
EVP_R_UNSUPPORTED_ALGORITHM, so this should be fine. (I don't expect
EVP_R_UNSUPPORTED_ALGORITHM to go away. The SPKI parsers we like live in EVP
now.)

A few other ASN1_R_* values didn't quite match upstream, so make those match
again. Finally, I got some of the rsa_pss.c values wrong. Each of those
corresponds to an (overly specific) RSA_R_* value in upstream. However, those
were gone in BoringSSL since even the initial commit. We placed the RSA <-> EVP
glue in crypto/evp (so crypto/rsa wouldn't depend on crypto/evp) while upstream
placed them in crypto/rsa.

Since no one seemed to notice the loss of RSA_R_INVALID_SALT_LENGTH, let's undo
all the cross-module errors inserted in crypto/rsa. Instead, since that kind of
specificity is not useful, funnel it all into X509_R_INVALID_PSS_PARAMETERS
(formerly EVP_R_INVALID_PSS_PARAMETERS, formerly RSA_R_INVALID_PSS_PARAMETERS).

Reset the error codes for all affected modules.

(That our error code story means error codes are not stable across this kind of
refactoring is kind of a problem. Hopefully this will be the last of it.)

Change-Id: Ibfb3a0ac340bfc777bc7de6980ef3ddf0a8c84bc
Reviewed-on: https://boringssl-review.googlesource.com/7458
Reviewed-by: Emily Stark (Dunn) <estark@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-15 16:02:12 +00:00
David Benjamin a5177cb319 Use a less tedious pattern for X509_NAME.
Also fix a long/unsigned-long cast. (ssl_get_message returns long. It really
shouldn't, but ssl_get_message needs much more work than just a long -> size_t
change, so leave it as long for now.)

Change-Id: Ice8741f62a138c0f35ca735eedb541440f57e114
Reviewed-on: https://boringssl-review.googlesource.com/7457
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-14 23:12:35 +00:00
David Benjamin 6b6e0b2089 Fix a memory leak in ssl3_get_certificate_request.
Found by libFuzzer.

Change-Id: Ifa343a184cc65f71fb6591d290b2d47d24a2be80
Reviewed-on: https://boringssl-review.googlesource.com/7456
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-14 23:12:22 +00:00
David Benjamin 15c1488b61 Clear the error queue on entry to core SSL operations.
OpenSSL historically made some poor API decisions. Rather than returning a
status enum in SSL_read, etc., these functions must be paired with
SSL_get_error which determines the cause of the last error's failure. This
requires SSL_read communicate with SSL_get_error with some stateful flag,
rwstate.

Further, probably as workarounds for bugs elsewhere, SSL_get_error does not
trust rwstate. Among other quirks, if the error queue is non-empty,
SSL_get_error overrides rwstate and returns a value based on that. This
requires that SSL_read, etc., be called with an empty error queue. (Or we hit
one of the spurious ERR_clear_error calls in the handshake state machine,
likely added as further self-workarounds.)

Since requiring callers consistently clear the error queue everywhere is
unreasonable (crbug.com/567501), clear ERR_clear_error *once* at the entry
point. Until/unless[*] we make SSL_get_error sane, this is the most reasonable
way to get to the point that clearing the error queue on error is optional.

With those in place, the calls in the handshake state machine are no longer
needed. (I suspect all the ERR_clear_system_error calls can also go, but I'll
investigate and think about that separately.)

[*] I'm not even sure it's possible anymore, thanks to the possibility of
BIO_write pushing to the error queue.

BUG=567501,593963

Change-Id: I564ace199e5a4a74b2554ad3335e99cd17120741
Reviewed-on: https://boringssl-review.googlesource.com/7455
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-14 19:05:05 +00:00
David Benjamin cfa9de85a3 Revert "Revert "Reduce maximum RSA public exponent size to 33 bits.""
This reverts commit ba70118d8e. Reverting this
did not resolve the regression and the cause is now known.

BUG=593963

Change-Id: Ic5e24b74e8f16b01d9fdd80f267a07ef026c82cf
Reviewed-on: https://boringssl-review.googlesource.com/7454
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-14 19:04:17 +00:00
David Benjamin fb8e678897 Match upstream's error codes for the old sigalg code.
People seem to condition on these a lot. Since this code has now been moved
twice, just make them all cross-module errors rather than leave a trail of
renamed error codes in our wake.

Change-Id: Iea18ab3d320f03cf29a64a27acca119768c4115c
Reviewed-on: https://boringssl-review.googlesource.com/7431
Reviewed-by: Emily Stark (Dunn) <estark@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-11 21:15:47 +00:00
Brian Smith 3f1904bee1 Set |bn->neg| to zero in |bn_set_words|.
If the values of any of the coordinates in the output point |r| were
negative during nistz256 multiplication, then the calls to
|bn_set_word| would result in the wrong coordinates being returned
(the negatives of the correct coordinates would be returned instead).
Fix that.

Change-Id: I6048e62f76dca18f625650d11ef5a051c9e672a4
Reviewed-on: https://boringssl-review.googlesource.com/7442
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-11 19:21:11 +00:00
Brian Smith 6603b76f76 Remove reduction in |ec_GFp_simple_set_Jprojective_coordinates_GFp|.
The (internal) constant-time callers of this function already do a
constant-time reduction before calling. And, nobody should be calling
this function with out-of-range coordinates anyway. So, just require
valid coordinates as input.

Further, this function is rarely called, so don't bother with the
optimization to avoid encoding Montgomery encoding of 1 for the Z
coordinate.

Change-Id: I637ffaf4d39135ca17214915b9a8582ea052eea8
Reviewed-on: https://boringssl-review.googlesource.com/7441
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-11 19:20:43 +00:00
Brian Smith 8542daa22d Require compressed x EC coordinate to be a field element.
Don't try to fix a bad |x| coordinate by reducing it. Instead, just
fail. This also makes the code clearer; in particular, it was confusing
why |x_| was used for some calculations when it seems like |x| was just
as good or better.

Change-Id: I9a6911f0d2bd72852a26b46f3828eb5ba3ef924f
Reviewed-on: https://boringssl-review.googlesource.com/7440
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-11 19:13:20 +00:00
David Benjamin df28c3acf1 Tidy up the client Certificate message skipping slightly.
Align all unexpected messages on SSL_R_UNEXPECTED_MESSAGE. Make the SSL 3.0
case the exceptional case. In doing so, make sure the SSL 3.0
SSL_VERIFY_FAIL_IF_NO_PEER_CERT case has its own test as that's a different
handshake shape.

Change-Id: I1a539165093fbdf33e2c1b25142f058aa1a71d83
Reviewed-on: https://boringssl-review.googlesource.com/7421
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-11 19:10:55 +00:00
David Benjamin 11d50f94d8 Include colons in expectedError matches.
If we're doing substring matching, we should at least include the delimiter.

Change-Id: I98bee568140d0304bbb6a2788333dbfca044114c
Reviewed-on: https://boringssl-review.googlesource.com/7420
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-11 19:10:32 +00:00
David Benjamin 454aa4c25e Rewrite ssl3_send_client_certificate.
The old logic was quite messy and grew a number of no-ops over the
years. It was also unreasonably fond of the variable name |i|.

The current logic wasn't even correct. It's overly fond of sending no
certificate, even when it pushes errors on the error queue for a fatal
error.

Change-Id: Ie5b2b38dd309f535af1d17fa261da7dc23185866
Reviewed-on: https://boringssl-review.googlesource.com/7418
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-11 19:10:19 +00:00
David Benjamin 0b7ca7dc00 Add tests for doing client auth with no certificates.
In TLS, you never skip the Certificate message. It may be empty, but its
presence is determined by CertificateRequest. (This is sensible.)

In SSL 3.0, the client omits the Certificate message. This means you need to
probe and may receive either Certificate or ClientKeyExchange (thankfully,
ClientKeyExchange is not optional, or we'd have to probe at ChangeCipherSpec).

We didn't have test coverage for this, despite some of this logic being a
little subtle asynchronously. Fix this.

Change-Id: I149490ae5506f02fa0136cb41f8fea381637bf45
Reviewed-on: https://boringssl-review.googlesource.com/7419
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-11 19:09:59 +00:00
David Benjamin f41bb59703 Remove unused functions.
We never heap-allocate a GCM128_CONTEXT.

Change-Id: I7e89419ce4d81c1598a4b3a214c44dbbcd709651
Reviewed-on: https://boringssl-review.googlesource.com/7430
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-11 15:25:53 +00:00
David Benjamin acb6dccf12 Add tests for the old client cert callback.
Also add no-certificate cases to the state machine coverage tests.

Change-Id: I88a80df6f3ea69aabc978dd356abcb9e309e156f
Reviewed-on: https://boringssl-review.googlesource.com/7417
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-10 20:53:13 +00:00
David Benjamin a857159dd6 Clean up some silly variable names.
Change-Id: I5b38e2938811520f52ece6055245248c80308b4d
Reviewed-on: https://boringssl-review.googlesource.com/7416
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-10 19:21:20 +00:00
David Benjamin 08791e6756 Appease sanitizers in x25519_ge_scalarmult.
Although exactly one iteration of cmov_cached will always initialize selected,
it ends up messing with uninitialized memory. Initialize |selected| before the
loop.

BUG=593540

Change-Id: I5921843f68c6dd1dc7f752538825bc43ba75df4a
Reviewed-on: https://boringssl-review.googlesource.com/7415
Reviewed-by: Arnar Birgisson <arnarb@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-10 19:08:42 +00:00
Adam Langley 97c80512af Add |DH_generate_parameters| to decrepit.
This makes building OpenLDAP easier.

Change-Id: Id64699f95477fb8fb98957027c97070ebf41f4b1
Reviewed-on: https://boringssl-review.googlesource.com/7407
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-10 17:44:59 +00:00
Adam Langley b8b28a64ff Add CRYPTO_[malloc|free|realloc] as aliases for the OPENSSL_𝑥 names.
This makes building OpenLDAP easier.

Change-Id: Ic1c5bcb2ec35c61c048e780ebc56db033d8382d8
Reviewed-on: https://boringssl-review.googlesource.com/7406
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-10 17:44:23 +00:00
David Benjamin 8f307d3805 Update cmake-linux64.tar.gz and cmake-mac.tar.gz.
Built from:
92c83ad8a4fd6224cf6319a60b399854f55b38ebe9d297c942408b792b1a9efa  cmake-3.5.0.tar.gz

Update instructions in the UPDATING file.

Change-Id: I49d3f5ef353347c446a04797719227e9793e3e0d
Reviewed-on: https://boringssl-review.googlesource.com/7414
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-10 17:23:17 +00:00
David Benjamin 8169df23dd Update Windows tools for the bots.
See 0d5e080ab9 for the previous version. Include
instructions on where to get the tools used.

807f96230c889b10f2957a47585426af4cdb116a8a77f1caecca83b7d7ab862b  cmake-3.5.0-win32-x86.zip
e6bb5c3e4d936bb1067560a58a21260693a0fbe34e55afb0111fe14f7eebc92c  strawberry-perl-5.22.1.2-32bit-portable.zip

Change-Id: I504cf779abce26087d09c0c974fb481886c9c459
Reviewed-on: https://boringssl-review.googlesource.com/7413
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-10 16:44:17 +00:00
David Benjamin 659b24d961 Update versions of tools in util/bot.
Update the easy ones here. Also include instructions on how to do this. The
.sha1 files will be updated separately with instructions.

Change-Id: I2a3aba43b8ffbdf930b8a2602dc1460077f6d0e7
Reviewed-on: https://boringssl-review.googlesource.com/7412
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-10 16:24:09 +00:00
David Benjamin 23afa68937 Fix the shared library build.
libdecrepit wants some symbols visible. Also a build file typo.

Change-Id: I670d2324ab9048f84e7f80afdefc98cbab80335d
Reviewed-on: https://boringssl-review.googlesource.com/7411
Reviewed-by: Adam Langley <agl@google.com>
2016-03-09 20:13:41 +00:00
Adam Langley f284a7dab6 Fix Windows build.
Windows doesn't like returning void values from void functions.

Change-Id: I9fbcb26098a5434ff4e8980f3ed0cd7b2567d658
2016-03-09 12:09:00 -08:00
Adam Langley f202d96875 Fix bug in obj_decrepit.c
Interestingly, Windows caught this with:
..\decrepit\obj\obj_decrepit.c(33) : warning C4090: 'function' : different 'const' qualifiers

However, the value of |name| isn't const, only the thing that it points
to. So this seems like a bug in MSVC, but I'm ok with it this time.

Change-Id: I076f98339cb0b669a4f592fba89aafc0a580efc4
Reviewed-on: https://boringssl-review.googlesource.com/7404
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-09 20:06:46 +00:00
Brian Smith ef18746ad4 Remove unused code for multiple-point ECC multiplication.
The points are only converted to affine form when there are at least
three points being multiplied (in addition to the generator), but there
never is more than one point, so this is all dead code.

Also, I doubt that the comments "...point at infinity (which normally
shouldn't happen)" in the deleted code are accurate. And, the
projective->affine conversions that were removed from p224-64.c and
p256-64.c didn't seem to properly account for the possibility that any of
those points were at infinity.

Change-Id: I611d42d36dcb7515eabf3abf1857e52ff3b45c92
Reviewed-on: https://boringssl-review.googlesource.com/7100
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-09 19:47:19 +00:00
Adam Langley a7a226add9 Add |OBJ_NAME_do_all_sorted|.
This another of those functions that tries to turn C into Python. In
this case, implement it in terms of the similar functions in EVP so that
at least we only have one list of things.

This makes life with nmap easier.

Change-Id: I6d01c43f062748d4ba7d7020587c286322e610bb
Reviewed-on: https://boringssl-review.googlesource.com/7403
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-09 19:38:06 +00:00
Adam Langley ff452c1d0e Add RIPEMD160 support in decrepit.
This version is taken from OpenSSL 1.0.2 with tweaks to support the
changes that we have made to md32_common.h. None of the assembly
implementations have been imported.

This makes supporting nmap easier.

Change-Id: Iae9241abdbc9021cc6bc35a65b40c3d739011ccc
Reviewed-on: https://boringssl-review.googlesource.com/7402
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-09 19:37:14 +00:00
Brian Smith d279a21d8c Avoid potential uninitialized memory read in crypto/ec/p256-x86_64.c.
If the function returns early due to an error, then the coordinates of the
result will have their |top| value set to a value beyond what has actually
been been written. Fix that, and make it easier to avoid such issues in the
future by refactoring the code.

As a bonus, avoid a false positive MSVC 64-bit opt build "potentially
uninitialized value used" warning.

Change-Id: I8c48deb63163a27f739c8797962414f8ca2588cd
Reviewed-on: https://boringssl-review.googlesource.com/6579
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-09 19:04:36 +00:00
Brian Smith 081e3f34a2 Remove |EC_POINT::Z_is_one|.
Having |Z_is_one| be out of sync with |Z| could potentially be a very
bad thing, and in the past there have been multiple bugs of this sort,
including one currently in p256-x86_64.c (type confusion: Montgomery-
encoded vs unencoded). Avoid the issue entirely by getting rid of
|Z_is_one|.

Change-Id: Icb5aa0342df41d6bc443f15f952734295d0ee4ba
Reviewed-on: https://boringssl-review.googlesource.com/6576
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-09 18:58:43 +00:00
Adam Langley bfb38b1a3c Add |RC4_options| to decrepit.
I've no idea who thought that this function was a good idea in the first
place, but including it in decrepit makes supporting nmap easier.

Change-Id: I7433cda6a6ddf1cc545126edf779625e9fc70ada
Reviewed-on: https://boringssl-review.googlesource.com/7401
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-09 01:14:30 +00:00
Adam Langley a34a5aacff Add one-shot |MD4| function.
This could live in decrepit, but it's tiny and having it makes the
interface more uniform that what we have for MD5 so I put it in the main
code. This is to more easily support nmap.

Change-Id: Ia098cc7ef6e00a90d2f3f56ee7deba8329c9a82e
Reviewed-on: https://boringssl-review.googlesource.com/7400
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-09 01:13:55 +00:00
David Benjamin ba70118d8e Revert "Reduce maximum RSA public exponent size to 33 bits."
This reverts commit b944882f26.

Recent Chrome canaries show a visible jump in ERR_SSL_PROTOCOL_ERROR which
coincided with a DEPS roll that included this change. Speculatively revert it
to see if they go back down afterwards.

Change-Id: I067798db144c348d666985986dfb9720d1153b7a
Reviewed-on: https://boringssl-review.googlesource.com/7391
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-08 23:10:50 +00:00
Brian Smith 617804adc5 Always use |BN_mod_exp_mont|/|BN_mod_exp_mont_consttime| in RSA.
This removes a hard dependency on |BN_mod_exp|, which will allow the
linker to drop it in programs that don't use other features that
require it.

Also, remove the |mont| member of |bn_blinding_st| in favor of having
callers pass it when necssaary. The |mont| member was a weak reference,
and weak references tend to be error-prone.

Finally, reduce the scope of some parts of the blinding code to
|static|.

Change-Id: I16d8ccc2d6d950c1bb40377988daf1a377a21fe6
Reviewed-on: https://boringssl-review.googlesource.com/7111
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-08 22:30:19 +00:00
David Benjamin 3ed5977cbb Add an idle timeout to runner.go.
If a Read or Write blocks for too long, time out the operation. Otherwise, some
kinds of test failures result in hangs, which prevent the test harness from
progressing. (Notably, OpenSSL currently has a lot of those failure modes and
upstream expressed interest in being able to run the tests to completion.)

Go's APIs want you to send an absolute timeout, to avoid problems when a Read
is split into lots of little Reads. But we actively want the timer to reset in
that case, so this needs a trivial adapter.

The default timeout is set at 15 seconds for now. If this becomes a problem, we
can extend it or build a more robust deadlock detector given an out-of-band
channel (shim tells runner when it's waiting on data, abort if we're also
waiting on data at the same time). But I don't think we'll need that
complexity. 15 seconds appears fine for both valgrind and running tests on a
Nexus 4.

BUG=460189

Change-Id: I6463fd36058427d883b526044da1bbefba851785
Reviewed-on: https://boringssl-review.googlesource.com/7380
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-08 22:26:41 +00:00
David Benjamin 3d38c03a8e Fix a few more missing CBB_cleanups.
See also 1b0c438e1a.

Change-Id: Ifcfe15caa4d0db8ef725f8dacd0e8c5c94b00a09
Reviewed-on: https://boringssl-review.googlesource.com/7390
Reviewed-by: Emily Stark (Dunn) <estark@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-08 21:08:48 +00:00
David Benjamin f945952d57 Add a script to run tests on Android.
The bots will likely use different infrastructure (I expect I'll need to write
an isolate file and such). In the meantime, make it easier to run tests
manually.

BUG=487432

Change-Id: I0e10b23e5f3eb1c5cd60fb88f21ba4a8385b979e
Reviewed-on: https://boringssl-review.googlesource.com/7334
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-08 17:08:27 +00:00
David Benjamin dfd6fe4f95 Add a PULL_REQUEST_TEMPLATE.
Now that we have a GitHub mirror, set up a PULL_REQUEST_TEMPLATE so people know
not to file pull requests against us. Text borrowed from Go's version of this
file.

Change-Id: I7da127fbf36eb3a7cb68e3a91cc9dfbb7fc92155
Reviewed-on: https://boringssl-review.googlesource.com/7370
Reviewed-by: Adam Langley <agl@google.com>
2016-03-08 15:23:52 +00:00
Adam Langley cdd7048358 Fix windows build.
Windows doesn't like struct literals:
..\decrepit\dsa\dsa_decrepit.c(85) : warning C4204: nonstandard extension used : non-constant aggregate initializer

Change-Id: I12541f2883ecbb10c85cddfae8d2adbbb1365ae3
Reviewed-on: https://boringssl-review.googlesource.com/7364
Reviewed-by: Adam Langley <agl@google.com>
2016-03-08 01:57:24 +00:00
Adam Langley 6e96eaebe0 Add |X509_EXT_conf_nid| to decrepit.
This function is a deprecated version of |X509_EXT_nconf_nid| that takes
a hash of |CONF_VALUE|s directly rather than a |CONF|.

Change-Id: I5fd1025b31d73b988d9298b2624453017dd34ff4
Reviewed-on: https://boringssl-review.googlesource.com/7363
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-08 01:50:10 +00:00
Adam Langley 8ba4b2d5bf Add |RSA_[padding_add|verify]_PKCS1_PSS to decrepit.
These functions are just like the _mgf1 versions but omit one of the
parameters. It's easier to add them than to patch the callers in some
cases.

Change-Id: Idee5b81374bf15f2ea89b7e0c06400c2badbb275
Reviewed-on: https://boringssl-review.googlesource.com/7362
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-08 01:45:40 +00:00
Adam Langley 4435e96b08 Include buffer.h from bio.h.
We shouldn't really have to do this, but there's a lot of code that
doesn't always include what it uses. In this case, since bio.h
references |BUF_MEM| in function signatures, it seems a little less
distasteful.

Change-Id: Ifb50f8bce40639f977b4447404597168a68c8388
Reviewed-on: https://boringssl-review.googlesource.com/7361
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-08 01:44:37 +00:00
Adam Langley 99a24ba0f1 Add DSA_generate_parameters to decrepit.
This function was deprecated by OpenSSL in 0.9.8 but code that uses it
still exists. This change adds an implementation of this function to
decreipt/ to support these programs.

Change-Id: Ie99cd00ff8b0ab2675f2b1c821c3d664b9811f16
Reviewed-on: https://boringssl-review.googlesource.com/7360
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-08 01:44:27 +00:00
David Benjamin 22ce9b2d08 SSL_set_fd should create socket BIOs, not fd BIOs.
In OpenSSL, they create socket BIOs. The distinction isn't important on UNIX.
On Windows, file descriptors are provided by the C runtime, while sockets must
use separate recv and send APIs. Document how these APIs are intended to work.

Also add a TODO to resolve the SOCKET vs int thing. This code assumes that
Windows HANDLEs only use the bottom 32 bits of precision. (Which is currently
true and probably will continue to be true for the foreseeable future[*], but
it'd be nice to do this right.)

Thanks to Gisle Vanem and Daniel Stenberg for reporting the bug.

[*] Both so Windows can continue to run 32-bit programs and because of all the
random UNIX software, like OpenSSL and ourselves, out there which happily
assumes sockets are ints.

Change-Id: I67408c218572228cb1a7d269892513cda4261c82
Reviewed-on: https://boringssl-review.googlesource.com/7333
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-07 18:19:12 +00:00
Tom Thorogood 66b2fe8e02 Add |SSL_CTX_set_private_key_method| to parallel |SSL_set_private_key_method|
This change adds a |SSL_CTX_set_private_key_method| method that sets key_method on a SSL_CTX's cert.

It allows the private key method to be set once and inherited.

A copy of key_method (from SSL_CTX's cert to SSL's cert) is added in |ssl_cert_dup|.

Change-Id: Icb62e9055e689cfe2d5caa3a638797120634b63f
Reviewed-on: https://boringssl-review.googlesource.com/7340
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-07 18:16:58 +00:00
Emily Stark 62e0219679 Handle empty keys in EVP_marshal_public_key()
Instead of crashing when an empty key is passed to
EVP_marshal_public_key(), return with an
EVP_R_UNSUPPORTED_ALGORITHM_ERROR. This brings e.g. X509_PUBKEY_set()
closer to how it behaved before 68772b31 (previously, it returned an
error on an empty public key rather than dereferencing pkey->ameth).

Change-Id: Ieac368725adb7f22329c035d9d0685b44b885888
Reviewed-on: https://boringssl-review.googlesource.com/7351
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-07 15:54:54 +00:00
David Benjamin ad004af661 Rename NID_x25519 to NID_X25519.
I went with NID_x25519 to match NID_sha1 and friends in being lowercase.
However, upstream seems to have since chosen NID_X25519. Match their
name.

Change-Id: Icc7b183a2e2dfbe42c88e08e538fcbd242478ac3
Reviewed-on: https://boringssl-review.googlesource.com/7331
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-07 15:48:51 +00:00
David Benjamin 154c2f2b37 Add some missing return false lines to test_config.cc.
Change-Id: I9540c931b6cdd4d65fa9ebfc52e1770d2174abd2
Reviewed-on: https://boringssl-review.googlesource.com/7330
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-07 15:48:37 +00:00
Emily Stark 1b0c438e1a Fix i2d_RSAPrivateKey, i2d_RSAPublicKey memory leaks
Change-Id: Id2678c20270f2f45efe56efd65caf23e0bb8c09e
Reviewed-on: https://boringssl-review.googlesource.com/7350
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-07 15:48:21 +00:00
David Benjamin 05c7bb4565 Avoid shifting negative numbers in curve25519.
C is still kind of unsure about the whole two's complement thing and leaves
left-shifting of negative numbers undefined. Sadly, some sanitizers believe in
teaching the controversy and complain when code relies on the theory of two's
complement.

Shushing these sanitizers in this case is easier than fighting with build
configuration, so replace the shifts with masks. (This is equivalent as the
left-shift was of a value right-shifted by the same amount. Instead, we store
the unshifted value in carry0, etc., and mask off the bottom bits.) A few other
places get casts to unsigned types which, by some miracle, C compilers are
forbidden from miscompiling.

This is imported from upstream's b95779846dc876cf959ccf96c49d4c0a48ea3082 and
5b7af0dd6c9315ca76fba16813b66f5792c7fe6e.

Change-Id: I6bf8156ba692165940c0c4ea1edd5b3e88ca263e
Reviewed-on: https://boringssl-review.googlesource.com/7320
Reviewed-by: Adam Langley <agl@google.com>
2016-03-05 00:23:09 +00:00
David Benjamin 58218b63bc Regenerate server_corpus and client_corpus.
Now that client.cc and server.cc run through application data, regenerate the
corpus.

Change-Id: I8278ebfe47fd2ba74f67db6f9b545aabf9fd1f84
Reviewed-on: https://boringssl-review.googlesource.com/7301
Reviewed-by: Adam Langley <agl@google.com>
2016-03-04 19:13:32 +00:00
David Benjamin d86c8a400b Enable renegotiation in the client fuzzer and read app data.
As long as the HTTP/1.1 client auth hack forces use to support renego, having
it on seems much more useful than having it off for fuzzing purposes. Also read
app data to exercise that code and, on the client, trigger renegotiations as
needed.

Change-Id: I1941ded6ec9bd764abd199d1518420a1075ed1b2
Reviewed-on: https://boringssl-review.googlesource.com/7291
Reviewed-by: Adam Langley <agl@google.com>
2016-03-04 19:13:10 +00:00
David Benjamin 1d34e3c644 Add an option to pick a different build directory in minimise_corpuses.sh.
Also pass set -e instead of chaining things with &&. (One line was missing the
&&.)

Change-Id: Ia04e7f40f46688c9664101efefef1d1ea069de71
Reviewed-on: https://boringssl-review.googlesource.com/7300
Reviewed-by: Adam Langley <agl@google.com>
2016-03-04 19:12:43 +00:00
David Benjamin d7166d07ad Add a standalone ChaCha test.
The coverage tool revealed that we weren't testing all codepaths of the ChaCha
assembly. Add a standalone test as it's much easier to iterate over all lengths
when there isn't the entire AEAD in the way.

I wasn't able to find a really long test vector, so I generated a random one
with the Go implementation we have in runner.

This test gives us full coverage on the ChaCha20_ssse3 variant. (We'll see how
it fares on the other codepaths when the multi-variant test harnesses get in. I
certainly hope there isn't a more novel way to call ChaCha20 than this...)

Change-Id: I087e421c7351f46ea65dacdc7127e4fbf5f4c0aa
Reviewed-on: https://boringssl-review.googlesource.com/7299
Reviewed-by: Adam Langley <agl@google.com>
2016-03-04 19:11:03 +00:00
David Benjamin 433366587d Move AES128 above AES256 by default.
This is in preparation for adding AES_256_GCM in Chromium below AES_128_GCM.
For now, AES_128_GCM is preferable over AES_256_GCM for performance reasons.

While I'm here, swap the order of 3DES and RC4. Chromium has already disabled
RC4, but the default order should probably reflect that until we can delete it
altogether.

BUG=591516

Change-Id: I1b4df0c0b7897930be726fb8321cee59b5d93a6d
Reviewed-on: https://boringssl-review.googlesource.com/7296
Reviewed-by: Adam Langley <agl@google.com>
2016-03-04 19:07:12 +00:00
David Benjamin bd30f480c5 poly1305/asm/poly1305-*.pl: flip horizontal add and reduction.
Only the 32-bit AVX2 code path needs this, but upstream choose to harmonize all
vector code paths.

RT#4346

(Imported from 1ea8ae5090f557fea2e5b4d5758b10566825d74b.)

Tested the new code manually on arm and aarch64, NEON and non-NEON. Steven
reports that all variants pass on x86 and x86-64 too.

I've left the 32-bit x86 AVX2 code disabled since valgrind can't measure the
code coverage, but this avoids diff with upstream. We can enable it if we ever
end up caring.

Change-Id: Id9becc2adfbe44b84764f8e9c1fb5e8349c4d5a8
Reviewed-on: https://boringssl-review.googlesource.com/7295
Reviewed-by: Adam Langley <agl@google.com>
2016-03-04 19:06:20 +00:00
Steven Valdez ab14a4a440 Adding scripts to generate line coverage.
Uses LCOV for C(++) line coverage and Valgrind's Callgrind tool to
generate assembly-level line coverage for the generated assembly
code.

BUG=590332

Change-Id: Ic70300a272c38f4fa6dd615747db568aa0853584
Reviewed-on: https://boringssl-review.googlesource.com/7251
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-03 23:33:48 +00:00
Adam Langley 80c0fd6746 Update fuzzing corpuses.
This results from running the fuzzers for a little while with both the
8bit-counters change and after taking the transcripts from the runner
tests as seeds for the `client` and `server` fuzzers.

Change-Id: I545a89d8dccd7ef69dd97546ed61610eea4a27a3
Reviewed-on: https://boringssl-review.googlesource.com/7276
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-03 18:33:05 +00:00
David Benjamin fde5afcd88 Remove dead comment.
EC point format negotiation is dead and gone.

Change-Id: If13ed7c5f31b64df2bbe90c018b2683b6371a980
Reviewed-on: https://boringssl-review.googlesource.com/7293
Reviewed-by: Adam Langley <agl@google.com>
2016-03-03 18:06:19 +00:00
Adam Langley ddcc186ef1 Document how to minimise corpuses.
Change-Id: Ie487163787d78d867e34709fb34b4c6a836f668d
Reviewed-on: https://boringssl-review.googlesource.com/7275
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-03 18:05:34 +00:00
Adam Langley de29f36cf4 Add 8bit-counters option for fuzzing.
This enables coverage counters[1] when fuzzing.

[1] http://clang.llvm.org/docs/SanitizerCoverage.html#coverage-counters

Change-Id: I33fca02d0406b75ac1f7598f41fe4c2ce43538d1
Reviewed-on: https://boringssl-review.googlesource.com/7274
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-03 18:04:58 +00:00
Brian Smith cf81b540ce Remove call to |fprintf| in |CRYPTO_once|.
The |fprintf| dependency is quite heavyweight for small targets. Also,
using |fprintf| on a closed file dsecriptor is undefined behavior, and
there's no way that this code can know whether |stderr| has already
been closed. So, just don't do it.

Change-Id: I1277733afe0649ae1324d11cac84826a1056e308
Reviewed-on: https://boringssl-review.googlesource.com/6812
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-03 18:01:43 +00:00
David Benjamin 9867b7dca2 Add an option to record transcripts from runner tests.
This can be used to get some initial corpus for fuzzing.

Change-Id: Ifcd365995b54d202c4a2674f49e7b28515f36025
Reviewed-on: https://boringssl-review.googlesource.com/7289
Reviewed-by: Adam Langley <agl@google.com>
2016-03-03 01:38:14 +00:00
David Benjamin f2b8363578 Fix the tests for the fuzzer mode.
It's useful to make sure our fuzzer mode works. Not all tests pass, but most
do. (Notably the negative tests for everything we've disabled don't work.) We
can also use then use runner to record fuzzer-mode transcripts with the ciphers
correctly nulled.

Change-Id: Ie41230d654970ce6cf612c0a9d3adf01005522c6
Reviewed-on: https://boringssl-review.googlesource.com/7288
Reviewed-by: Adam Langley <agl@google.com>
2016-03-03 01:36:55 +00:00
David Benjamin bc5b2a2e22 Add a deterministic PRNG for fuzzing.
If running the stack through a fuzzer, we would like execution to be
completely deterministic. This is gated on a
BORINGSSL_UNSAFE_FUZZER_MODE #ifdef.

For now, this just uses the zero ChaCha20 key and a global counter. As
needed, we can extend this to a thread-local counter and a separate
ChaCha20 stream and counter per input length.

Change-Id: Ic6c9d8a25e70d68e5dc6804e2c234faf48e51395
Reviewed-on: https://boringssl-review.googlesource.com/7286
Reviewed-by: Adam Langley <agl@google.com>
2016-03-03 01:36:19 +00:00
David Benjamin 8b9e7802ac Fix up all_tests.go parallelism support.
A len(tests) should have been len(testCases), the code never added to the
sync.WaitGroup, and feeding tests to the tests channel blocks on the tests
completing, so with one worker the results didn't stream. (And if the results
channel wasn't large enough, we'd deadlock.)

Change-Id: Iee37507b9706b14cffddd9c1b55fc311ee9b666d
Reviewed-on: https://boringssl-review.googlesource.com/7292
Reviewed-by: Adam Langley <agl@google.com>
2016-03-02 23:47:43 +00:00
David Benjamin bf82aede67 Disable all TLS crypto in fuzzer mode.
Both sides' signature and Finished checks still occur, but the results
are ignored. Also, all ciphers behave like the NULL cipher.
Conveniently, this isn't that much code since all ciphers and their size
computations funnel into SSL_AEAD_CTX.

This does carry some risk that we'll mess up this code. Up until now, we've
tried to avoid test-only changes to the SSL stack.

There is little risk that anyone will ship a BORINGSSL_UNSAFE_FUZZER_MODE build
for anything since it doesn't interop anyway. There is some risk that we'll end
up messing up the disableable checks. However, both skipped checks have
negative tests in runner (see tests that set InvalidSKXSignature and
BadFinished). For good measure, I've added a server variant of the existing
BadFinished test to this CL, although they hit the same code.

Change-Id: I37f6b4d62b43bc08fab7411965589b423d86f4b8
Reviewed-on: https://boringssl-review.googlesource.com/7287
Reviewed-by: Adam Langley <agl@google.com>
2016-03-02 23:39:36 +00:00
Brian Smith 2477adcf62 Clarify use of |$end0| in stitched x86-64 AES-GCM code.
There was some uncertainty about what the code is doing with |$end0|
and whether it was necessary for |$len| to be a multiple of 16 or 96.
Hopefully these added comments make it clear that the code is correct
except for the caveat regarding low memory addresses.

Change-Id: Iea546a59dc7aeb400f50ac5d2d7b9cb88ace9027
Reviewed-on: https://boringssl-review.googlesource.com/7194
Reviewed-by: Adam Langley <agl@google.com>
2016-03-02 23:37:17 +00:00
Steven Valdez 32223940f2 Making all_tests.go parallelizable
Use -num-workers to run multiple workers in parallel when running tests.

Change-Id: Iee5554ee78ec8d77700a0df5a297bd2515d34dca
Reviewed-on: https://boringssl-review.googlesource.com/7285
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-02 17:44:36 +00:00
David Benjamin 9bea349660 Account for Windows line endings in runner.
Otherwise the split on "--- DONE ---\n" gets confused.

Change-Id: I74561a99e52b98e85f67efd85523213ad443d325
Reviewed-on: https://boringssl-review.googlesource.com/7283
Reviewed-by: Adam Langley <agl@google.com>
2016-03-02 16:02:45 +00:00
Adam Langley 29ec5d1fda Add dummy |SSL_get_server_tmp_key|.
Node.js calls it but handles it failing. Since we have abstracted this
in the state machine, we mightn't even be using a cipher suite where the
server's key can be expressed as an EVP_PKEY.

Change-Id: Ic3f013dc9bcd7170a9eb2c7535378d478b985849
Reviewed-on: https://boringssl-review.googlesource.com/7272
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-02 15:57:47 +00:00
Adam Langley d323f4b1e1 Bring back |verify_store|.
This was dropped in d27441a9cb due to lack
of use, but node.js now needs it.

Change-Id: I1e207d4b46fc746cfae309a0ea7bbbc04ea785e8
Reviewed-on: https://boringssl-review.googlesource.com/7270
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-02 15:57:27 +00:00
David Benjamin 2b07fa4b22 Fix a memory leak in an error path.
Found by libFuzzer combined with some experimental unsafe-fuzzer-mode patches
(to be uploaded once I've cleaned them up a bit) to disable all those pesky
cryptographic checks in the protocol.

Change-Id: I9153164fa56a0c2262c4740a3236c2b49a596b1b
Reviewed-on: https://boringssl-review.googlesource.com/7282
Reviewed-by: Adam Langley <agl@google.com>
2016-03-02 15:49:30 +00:00
David Benjamin ff3a1498da Ensure runner notices post-main stderr output.
If LeakSanitizer fires something on a test that's expected to fail, runner will
swallow it. Have stderr output always end in a "--- DONE ---" marker and treat
all output following that as a test failure.

Change-Id: Ia8fd9dfcaf48dd23972ab8f906d240bcb6badfe2
Reviewed-on: https://boringssl-review.googlesource.com/7281
Reviewed-by: Adam Langley <agl@google.com>
2016-03-02 15:37:45 +00:00
David Benjamin 3cd8196f14 Mark all curve25519 tables const.
See also upstream's dc22d6b37e8058a4334e6f98932c2623cd3d8d0d. (Though I'm not
sure why they didn't need to fix cmov.)

Change-Id: I2a194a8aea1734d4c1e7f6a0536a636379381627
Reviewed-on: https://boringssl-review.googlesource.com/7280
Reviewed-by: Adam Langley <agl@google.com>
2016-03-02 15:17:38 +00:00
Adam Langley 7a17ba2e3a Add |FIPS_mode|, which returns zero.
(node.js calls it.)

Change-Id: I7401f4cb4dfc61d500331821784ae717ad9f7adf
Reviewed-on: https://boringssl-review.googlesource.com/7271
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-02 00:15:37 +00:00
Adam Langley 708db16463 Pass |alice_msg| by reference in the SPAKE2 speed test.
This is an attempt to make MSVC happy. Currently it's saying:

..\tool\speed.cc(508) : error C2536: 'SpeedSPAKE2::<lambda_…>::SpeedSPAKE2::<lambda_…>::alice_msg' : cannot specify explicit initializer for arrays

Change-Id: Ifba1df26b5d734f142668a41834645c1549f9f52
Reviewed-on: https://boringssl-review.googlesource.com/7248
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-01 19:50:20 +00:00
Arnar Birgisson f27459e412 Add SPAKE2 over Ed25519.
SPAKE2 is a password-authenticated key exchange. This implementation is
over the twisted Edwards curve Ed25519, and uses SHA-512 as the hash
primitive.

See https://tools.ietf.org/html/draft-irtf-cfrg-spake2-03

Change-Id: I2cd3c3ebdc3d55ac3aea3a9eb0d06275509597ac
Reviewed-on: https://boringssl-review.googlesource.com/7114
Reviewed-by: Adam Langley <agl@google.com>
2016-03-01 19:34:10 +00:00
Adam Langley e4f3f4df6e Add test that A+A = 2×A on elliptic curves.
Change-Id: I914efab9a15c903f79a1b83388b577b14c534269
Reviewed-on: https://boringssl-review.googlesource.com/7247
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-01 18:08:51 +00:00
Adam Langley 060bd590ce ec/asm/p256-x86_64-asm.pl: get corner case logic right.
(Imported from upstream's 64333004a41a9f4aa587b8e5401420fb70d00687.)

RT#4284.

This case should be impossible to hit because |EC_POINT_add| doesn't use
this function and trying to add equal inputs should never occur during a
multiplication. Support for this exists because the pattern has been
copied from the first 64-bit P-224 and P-256 work that Emilia, Bodo and
I did. There it seemed like a reasonable defense-in-depth in case the
code changed in the future.

Change-Id: I7ff138669c5468b7d7a5153429bec728cb67e338
Reviewed-on: https://boringssl-review.googlesource.com/7246
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-01 18:06:46 +00:00
Steven Valdez 7aea80f576 Adding missing BN_CTX_start/BN_CTX_end in ec_key
Change-Id: Icfa6a0bc36b808e2e6ea8b36a0fc49b3c4943b07
Reviewed-on: https://boringssl-review.googlesource.com/7254
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-01 18:04:46 +00:00
Adam Langley df2a5562f3 bn/asm/x86_64-mont5.pl: unify gather procedure in hardly used path and reorganize/harmonize post-conditions.
(Imported from upstream's 515f3be47a0b58eec808cf365bc5e8ef6917266b)

Additional hardening following on from CVE-2016-0702.

Change-Id: I19a6739b401887a42eb335fe5838379dc8d04100
Reviewed-on: https://boringssl-review.googlesource.com/7245
Reviewed-by: Adam Langley <agl@google.com>
2016-03-01 18:04:20 +00:00
Adam Langley b360eaf001 crypto/bn/x86_64-mont5.pl: constant-time gather procedure.
(Imported from upstream's 25d14c6c29b53907bf614b9964d43cd98401a7fc.)

At the same time remove miniscule bias in final subtraction. Performance
penalty varies from platform to platform, and even with key length. For
rsa2048 sign it was observed to be 4% for Sandy Bridge and 7% on
Broadwell.

(This is part of the fix for CVE-2016-0702.)

Change-Id: I43a13d592c4a589d04c17c33c0ca40c2d7375522
Reviewed-on: https://boringssl-review.googlesource.com/7244
Reviewed-by: Adam Langley <agl@google.com>
2016-03-01 18:04:15 +00:00
Adam Langley 1168fc72fc bn/asm/rsaz-avx2.pl: constant-time gather procedure.
(Imported from upstream's 08ea966c01a39e38ef89e8920d53085e4807a43a)

Performance penalty is 2%.

(This is part of the fix for CVE-2016-0702.)

Change-Id: Id3b6262c5d3201dd64b93bdd34601a51794a9275
Reviewed-on: https://boringssl-review.googlesource.com/7243
Reviewed-by: Adam Langley <agl@google.com>
2016-03-01 18:04:09 +00:00
Adam Langley 842a06c2b9 bn/asm/rsax-x86_64.pl: constant-time gather procedure.
(Imported from upstream's ef98503eeef5c108018081ace902d28e609f7772.)

Performance penalty is 2% on Linux and 5% on Windows.

(This is part of the fix for CVE-2016-0702.)

Change-Id: If82f95131c93168282a46ac5a35e2b007cc2bd67
Reviewed-on: https://boringssl-review.googlesource.com/7242
Reviewed-by: Adam Langley <agl@google.com>
2016-03-01 18:03:16 +00:00
Adam Langley 82bdaa89f0 Make copy_from_prebuf constant time.
(Imported from upstream's 708dc2f1291e104fe4eef810bb8ffc1fae5b19c1.)

Performance penalty varies from platform to platform, and even key
length. For rsa2048 sign it was observed to reach almost 10%.

This is part of the fix for CVE-2016-0702.

Change-Id: Ie0860bf3e531196f03102db1bc48eeaf30ab1d58
Reviewed-on: https://boringssl-review.googlesource.com/7241
Reviewed-by: Adam Langley <agl@google.com>
2016-03-01 18:03:09 +00:00
Steven Valdez aeb69a02b8 Pass pure constants verbatim in perlasm/x86_64-xlate.pl
(Imported from upstream's 10c639a8a56c90bec9e332c7ca76ef552b3952ac)

Change-Id: Ia8203eeae9d274249595a6e352ec2f77a97ca5d5
Reviewed-on: https://boringssl-review.googlesource.com/7227
Reviewed-by: David Benjamin <davidben@google.com>
2016-03-01 17:52:20 +00:00
David Benjamin 2c198fae28 Enforce that d2i_PrivateKey returns a key of the specified type.
If d2i_PrivateKey hit the PKCS#8 codepath, it didn't enforce that the key was
of the specified type.

Note that this requires tweaking d2i_AutoPrivateKey slightly. A PKCS #8
PrivateKeyInfo may have 3 or 4 elements (optional attributes), so we were
relying on this bug for d2i_AutoPrivateKey to work.

Change-Id: If50b7a742f535d208e944ba37c3a585689d1da43
Reviewed-on: https://boringssl-review.googlesource.com/7253
Reviewed-by: Adam Langley <agl@google.com>
2016-03-01 00:06:55 +00:00
David Benjamin 886119b9f7 Disable ChaCha20 assembly for OPENSSL_X86.
They fail the newly-added in-place tests. Since we don't have bots for them
yet, verified manually that the arm and aarch64 code is fine.

Change-Id: Ic6f4060f63e713e09707af05e6b7736b7b65c5df
Reviewed-on: https://boringssl-review.googlesource.com/7252
Reviewed-by: Adam Langley <agl@google.com>
2016-02-29 22:30:46 +00:00
Adam Langley f132d4e8f8 Test AEAD interface with aliased buffers.
Cases where the input and output buffers overlap are always a little
odd. This change adds a test to ensures that the (generic) AEADs
function in these situations.

Change-Id: I6f1987a5e10ddef6b2b8f037a6d50737a120bc99
Reviewed-on: https://boringssl-review.googlesource.com/7195
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-29 22:14:18 +00:00
David Benjamin 42c8c63fcb Fix build.
Forgot to delete a line.

Change-Id: Ia1fb2904398816d495045dc237337f0be5b09272
Reviewed-on: https://boringssl-review.googlesource.com/7250
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-29 22:01:04 +00:00
Steven Valdez d7305d50e4 Add missing initialization in bn/exponentiation
(Imported from upstream's 04f2a0b50d219aafcef2fa718d91462b587aa23d)

Change-Id: Ie840edeb1fc9d5a4273f137467e3ef16528c9668
Reviewed-on: https://boringssl-review.googlesource.com/7234
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-29 21:54:15 +00:00
Steven Valdez 318c076b69 modes/ctr.c: Ensure ecount_buf alignment in CRYPTO_ctr128_encrypt.
This isn't a problem when called from EVP, since the buffer is
aligned in the EVP_CIPHER_CTX. The increment counter code is also
fixed to deal with overflow.

(Imported from upstream's 6533a0b8d1ed12aa5f7dfd7a429eec67c5486bb5)

Change-Id: I8d7191c3d3873db254a551085d2358d90bc8397a
Reviewed-on: https://boringssl-review.googlesource.com/7233
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-29 21:52:31 +00:00
David Benjamin df1dc98409 Add a few more large tag tests to asn1_test.
While we're here, may as well test others.

Change-Id: I711528641a3f7dd035c696c3c1d6b035437c91cc
Reviewed-on: https://boringssl-review.googlesource.com/7239
Reviewed-by: Adam Langley <agl@google.com>
2016-02-29 21:29:59 +00:00
David Benjamin fb2c6f8c85 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

Change-Id: I363e01ebfde621c8865101f5bcbd5f323fb59e79
Reviewed-on: https://boringssl-review.googlesource.com/7238
Reviewed-by: Adam Langley <agl@google.com>
2016-02-29 21:17:19 +00:00
Adam Langley 7e8ed44013 Fix possible memory leak on BUF_MEM_grow_clean failure
(Imported from upstream's e9cf5f03666bb82f0184e4f013702d0b164afdca and
29305f4edc886db349f2beedb345f9dd93311c09)

Change-Id: I0fa019e9d337676a84a7a6c103d2c4e14e18aede
Reviewed-on: https://boringssl-review.googlesource.com/7240
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-29 20:56:19 +00:00
Steven Valdez a14934ff2d Handle shutdown during init/handshake earlier
Sending close_notify during init causes some problems for some
applications so we instead revert to the previous behavior returning an
error instead of silently passing.

(Imported from upstream's 64193c8218540499984cd63cda41f3cd491f3f59)

Change-Id: I5efed1ce152197d291e6c7ece6e5dbb8f3ad867d
Reviewed-on: https://boringssl-review.googlesource.com/7232
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-29 20:33:51 +00:00
Adam Langley c4eec0c16b 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

Change-Id: I8959e8ae01510a5924862a3f353be23130eee554
Reviewed-on: https://boringssl-review.googlesource.com/7199
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-29 20:07:03 +00:00
Brian Smith b944882f26 Reduce maximum RSA public exponent size to 33 bits.
Reduce the maximum RSA exponent size to 33 bits, regardless of modulus
size, for public key operations.

Change-Id: I88502b1033d8854696841531031298e8ad96a467
Reviewed-on: https://boringssl-review.googlesource.com/6901
Reviewed-by: Adam Langley <agl@google.com>
2016-02-26 23:38:18 +00:00
David Benjamin f4e447c16d Move ASN1_bn_print to a static function in evp/print.c.
It's not used anywhere else, in the library or consumers (Google ones or
ones I could find on Debian codesearch). This is a sufficiently
specialized function that the risk of a third-party library newly
depending on it is low. This removes the last include of asn1.h or
x509.h in crypto/evp.

(This is almost entirely cosmetic because it wasn't keeping the static linker
from doing the right thing anyway. But if we were want to separate the legacy
ASN.1 stack into its own decrepit-like target, we'll need to be pickier about
separation.)

Change-Id: I9be97c9321572e3a2ed093e1d50036b7654cff41
Reviewed-on: https://boringssl-review.googlesource.com/7080
Reviewed-by: Adam Langley <agl@google.com>
2016-02-26 23:35:10 +00:00
David Benjamin 63d9246812 Reset crypto/evp error codes.
A number of values have fallen off now that code's been shuffled
around.

Change-Id: I5eac1d3fa4a9335c6aa72b9876d37bb9a9a029ac
Reviewed-on: https://boringssl-review.googlesource.com/7029
Reviewed-by: Adam Langley <agl@google.com>
2016-02-26 23:34:04 +00:00
David Benjamin 921d906bb6 Reimplement d2i_PrivateKey.
Functions which lose object reuse and need auditing:
- d2i_PrivateKey

This removes evp_asn1.c's dependency on the old stack. (Aside from
obj/.) It also takes old_priv_decode out of EVP_ASN1_METHOD in favor of
calling out to the new-style function. EVP_ASN1_METHOD no longer has any
old-style type-specific serialization hooks, only the PKCS#8 and SPKI
ones.

BUG=499653

Change-Id: Ic142dc05a5505b50e4717c260d3893b20e680194
Reviewed-on: https://boringssl-review.googlesource.com/7027
Reviewed-by: Adam Langley <agl@google.com>
2016-02-26 23:33:50 +00:00
David Benjamin 6d3387d9c1 Reimplement d2i_AutoPrivateKey with the new ASN.1 stack.
This is kind of a ridiculous function. It would be nice to lose it, but
SSL_use_PrivateKey_file actually calls into it (by way of
d2i_PrivateKey_bio).

BUG=499653

Change-Id: I83634f6982b15f4b877e29f6793b7e00a1c10450
Reviewed-on: https://boringssl-review.googlesource.com/7026
Reviewed-by: Adam Langley <agl@google.com>
2016-02-26 22:55:56 +00:00
David Benjamin 8ebc0f55a0 Decouple the EVP and PEM code.
EVP_PKEY_asn1_find can already be private. EVP_PKEY_asn1_find_str is used
only so the PEM code can get at legacy encoders. Since this is all
legacy non-PKCS8 stuff, we can just explicitly list out the three cases
in the two places that need it. If this changes, we can later add a
table in crypto/pem mapping string to EVP_PKEY type.

With this, EVP_PKEY_ASN1_METHOD is no longer exposed in the public API
and nothing outside of EVP_PKEY reaches into it. Unexport all of that.

Change-Id: Iab661014247dbdbc31e5e9887364176ec5ad2a6d
Reviewed-on: https://boringssl-review.googlesource.com/6871
Reviewed-by: Adam Langley <agl@google.com>
2016-02-26 22:50:21 +00:00
David Benjamin 3f4f7ee08f PEM_write_bio_PrivateKey is always PKCS#8.
Every key type which has a legacy PEM encoding also has a PKCS#8
encoding. The fallback codepath is never reached.

This removes the only consumer of pem_str, so that may be removed from
EVP_PKEY_ASN1_METHOD.

Change-Id: Ic680bfc162e1dc76db8b8016f6c10f669b24f5aa
Reviewed-on: https://boringssl-review.googlesource.com/6870
Reviewed-by: Adam Langley <agl@google.com>
2016-02-26 22:41:17 +00:00
David Benjamin 8c07ad3e3b Pull EVP_PKEY print hooks out of the main method table.
This allows the static linker to drop it in consumers which don't need this
stuff (i.e. all sane ones), once crypto/x509 falls off. This cuts down
on a number of dependencies from the core crypto bits on crypto/asn1 and
crypto/x509.

BUG=499653

Change-Id: I76a10a04dcc444c1ded31683df9f87725a95a4e6
Reviewed-on: https://boringssl-review.googlesource.com/5660
Reviewed-by: Adam Langley <agl@google.com>
2016-02-26 22:40:44 +00:00
David Benjamin 17727c6843 Move all signature algorithm code to crypto/x509.
All the signature algorithm logic depends on X509_ALGOR. This also
removes the X509_ALGOR-based EVP functions which are no longer used
externally. I think those APIs were a mistake on my part. The use in
Chromium was unnecessary (and has since been removed anyway). The new
X.509 stack will want to process the signatureAlgorithm itself to be
able to enforce policies on it.

This also moves the RSA_PSS_PARAMS bits to crypto/x509 from crypto/rsa.
That struct is also tied to crypto/x509. Any new RSA-PSS code would
have to use something else anyway.

BUG=499653

Change-Id: I6c4b4573b2800a2e0f863d35df94d048864b7c41
Reviewed-on: https://boringssl-review.googlesource.com/7025
Reviewed-by: Adam Langley <agl@google.com>
2016-02-26 22:39:02 +00:00
David Benjamin 93a69b4f8f Move X.509 signature algorithm tests to the crypto/x509 layer.
This is in preparation for moving the logic itself to crypto/x509, so
the lower-level functions will not be as readily available.

Change-Id: I6507b895317df831ab11d0588c5b09bbb2aa2c24
Reviewed-on: https://boringssl-review.googlesource.com/7023
Reviewed-by: Adam Langley <agl@google.com>
2016-02-26 22:38:50 +00:00
David Benjamin da295d35f2 Drop the DSA signature printing hook.
It's only used by crypto/x509, and we don't even support DSA in
crypto/x509 anymore since the EVP_PKEY_CTX hooks aren't wired up.

Change-Id: I1b8538353eb51df353cf9171b1cbb0bb47a879a3
Reviewed-on: https://boringssl-review.googlesource.com/7024
Reviewed-by: Adam Langley <agl@google.com>
2016-02-26 22:19:37 +00:00
Aaron Green 136df6bd99 Fix implementation-specific behavior in gcm_test.c
gcm_test.c includes a test case that does a 'malloc(0)'. This test case
currently fails if malloc(0) returns NULL.  According to the standard,
malloc's behavior with a size of 0is implementation specific and may
either be NULL or another pointer suitable to be passed to free().  This
change modifies gcm_test.c to handle a return value of NULL.  It has
been tested with a custom allocator on an experimental branch.

Change-Id: I35514ec9735cedffc621f7dfae42b4c6664a1766
Reviewed-on: https://boringssl-review.googlesource.com/7122
Reviewed-by: Adam Langley <agl@google.com>
2016-02-26 22:17:35 +00:00
Emily Stark 95a79eec40 Add a stub for SSL_get_shared_ciphers().
This stub returns an empty string rather than NULL (since some callers
might assume that NULL means there are no shared ciphers).

Change-Id: I9537fa0a80c76559b293d8518599b68fd9977dd8
Reviewed-on: https://boringssl-review.googlesource.com/7196
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-26 21:10:13 +00:00
David Benjamin 6f0c4db90e Enable upstream's Poly1305 code.
The C implementation is still our existing C implementation, but slightly
tweaked to fit with upstream's init/block/emits convention.

I've tested this by looking at code coverage in kcachegrind and

  valgrind --tool=callgrind --dump-instr=yes --collect-jumps=yes

(NB: valgrind 3.11.0 is needed for AVX2. And even that only does 64-bit AVX2,
so we can't get coverage for the 32-bit code yet. But I had to disable that
anyway.)

This was paired with a hacked up version of poly1305_test that would repeat
tests with different ia32cap and armcap values. This isn't checked in, but we
badly need a story for testing all the different variants.

I'm not happy with upstream's code in either the C/asm boundary or how it
dispatches between different versions, but just debugging the code has been a
significant time investment. I'd hoped to extract the SIMD parts and do the
rest in C, but I think we need to focus on testing first (and use that to
guide what modifications would help). For now, this version seems to work at
least.

The x86 (not x86_64) AVX2 code needs to be disabled because it's broken. It
also seems pretty unnecessary.
https://rt.openssl.org/Ticket/Display.html?id=4346

Otherwise it seems to work and buys us a decent performance improvement.
Notably, my Nexus 6P is finally faster at ChaCha20-Poly1305 than my Nexus 4!

bssl speed numbers follow:

x86
---
Old:
Did 1554000 ChaCha20-Poly1305 (16 bytes) seal operations in 1000536us (1553167.5 ops/sec): 24.9 MB/s
Did 136000 ChaCha20-Poly1305 (1350 bytes) seal operations in 1003947us (135465.3 ops/sec): 182.9 MB/s
Did 30000 ChaCha20-Poly1305 (8192 bytes) seal operations in 1022990us (29325.8 ops/sec): 240.2 MB/s
Did 1888000 ChaCha20-Poly1305-Old (16 bytes) seal operations in 1000206us (1887611.2 ops/sec): 30.2 MB/s
Did 173000 ChaCha20-Poly1305-Old (1350 bytes) seal operations in 1003036us (172476.4 ops/sec): 232.8 MB/s
Did 30000 ChaCha20-Poly1305-Old (8192 bytes) seal operations in 1027759us (29189.7 ops/sec): 239.1 MB/s
New:
Did 2030000 ChaCha20-Poly1305 (16 bytes) seal operations in 1000507us (2028971.3 ops/sec): 32.5 MB/s
Did 404000 ChaCha20-Poly1305 (1350 bytes) seal operations in 1000287us (403884.1 ops/sec): 545.2 MB/s
Did 83000 ChaCha20-Poly1305 (8192 bytes) seal operations in 1001258us (82895.7 ops/sec): 679.1 MB/s
Did 2018000 ChaCha20-Poly1305-Old (16 bytes) seal operations in 1000006us (2017987.9 ops/sec): 32.3 MB/s
Did 360000 ChaCha20-Poly1305-Old (1350 bytes) seal operations in 1001962us (359295.1 ops/sec): 485.0 MB/s
Did 85000 ChaCha20-Poly1305-Old (8192 bytes) seal operations in 1002479us (84789.8 ops/sec): 694.6 MB/s

x86_64, no AVX2
---
Old:
Did 2023000 ChaCha20-Poly1305 (16 bytes) seal operations in 1000258us (2022478.2 ops/sec): 32.4 MB/s
Did 466000 ChaCha20-Poly1305 (1350 bytes) seal operations in 1002619us (464782.7 ops/sec): 627.5 MB/s
Did 90000 ChaCha20-Poly1305 (8192 bytes) seal operations in 1001133us (89898.1 ops/sec): 736.4 MB/s
Did 2238000 ChaCha20-Poly1305-Old (16 bytes) seal operations in 1000175us (2237608.4 ops/sec): 35.8 MB/s
Did 483000 ChaCha20-Poly1305-Old (1350 bytes) seal operations in 1001348us (482349.8 ops/sec): 651.2 MB/s
Did 90000 ChaCha20-Poly1305-Old (8192 bytes) seal operations in 1003141us (89718.2 ops/sec): 735.0 MB/s
New:
Did 2558000 ChaCha20-Poly1305 (16 bytes) seal operations in 1000275us (2557296.7 ops/sec): 40.9 MB/s
Did 510000 ChaCha20-Poly1305 (1350 bytes) seal operations in 1001810us (509078.6 ops/sec): 687.3 MB/s
Did 115000 ChaCha20-Poly1305 (8192 bytes) seal operations in 1006457us (114262.2 ops/sec): 936.0 MB/s
Did 2818000 ChaCha20-Poly1305-Old (16 bytes) seal operations in 1000187us (2817473.1 ops/sec): 45.1 MB/s
Did 418000 ChaCha20-Poly1305-Old (1350 bytes) seal operations in 1001140us (417524.0 ops/sec): 563.7 MB/s
Did 91000 ChaCha20-Poly1305-Old (8192 bytes) seal operations in 1002539us (90769.5 ops/sec): 743.6 MB/s

x86_64, AVX2
---
Old:
Did 2516000 ChaCha20-Poly1305 (16 bytes) seal operations in 1000115us (2515710.7 ops/sec): 40.3 MB/s
Did 774000 ChaCha20-Poly1305 (1350 bytes) seal operations in 1000300us (773767.9 ops/sec): 1044.6 MB/s
Did 171000 ChaCha20-Poly1305 (8192 bytes) seal operations in 1004373us (170255.5 ops/sec): 1394.7 MB/s
Did 2580000 ChaCha20-Poly1305-Old (16 bytes) seal operations in 1000144us (2579628.5 ops/sec): 41.3 MB/s
Did 769000 ChaCha20-Poly1305-Old (1350 bytes) seal operations in 1000472us (768637.2 ops/sec): 1037.7 MB/s
Did 169000 ChaCha20-Poly1305-Old (8192 bytes) seal operations in 1000320us (168945.9 ops/sec): 1384.0 MB/s
New:
Did 3240000 ChaCha20-Poly1305 (16 bytes) seal operations in 1000114us (3239630.7 ops/sec): 51.8 MB/s
Did 932000 ChaCha20-Poly1305 (1350 bytes) seal operations in 1000059us (931945.0 ops/sec): 1258.1 MB/s
Did 217000 ChaCha20-Poly1305 (8192 bytes) seal operations in 1003282us (216290.1 ops/sec): 1771.8 MB/s
Did 3187000 ChaCha20-Poly1305-Old (16 bytes) seal operations in 1000100us (3186681.3 ops/sec): 51.0 MB/s
Did 926000 ChaCha20-Poly1305-Old (1350 bytes) seal operations in 1000071us (925934.3 ops/sec): 1250.0 MB/s
Did 215000 ChaCha20-Poly1305-Old (8192 bytes) seal operations in 1000479us (214897.1 ops/sec): 1760.4 MB/s

arm, Nexus 4
---
Old:
Did 430248 ChaCha20-Poly1305 (16 bytes) seal operations in 1000153us (430182.2 ops/sec): 6.9 MB/s
Did 115250 ChaCha20-Poly1305 (1350 bytes) seal operations in 1000549us (115186.8 ops/sec): 155.5 MB/s
Did 27000 ChaCha20-Poly1305 (8192 bytes) seal operations in 1030124us (26210.4 ops/sec): 214.7 MB/s
Did 451750 ChaCha20-Poly1305-Old (16 bytes) seal operations in 1000549us (451502.1 ops/sec): 7.2 MB/s
Did 118000 ChaCha20-Poly1305-Old (1350 bytes) seal operations in 1001557us (117816.6 ops/sec): 159.1 MB/s
Did 27000 ChaCha20-Poly1305-Old (8192 bytes) seal operations in 1024263us (26360.4 ops/sec): 215.9 MB/s
New:
Did 553644 ChaCha20-Poly1305 (16 bytes) seal operations in 1000183us (553542.7 ops/sec): 8.9 MB/s
Did 126000 ChaCha20-Poly1305 (1350 bytes) seal operations in 1000396us (125950.1 ops/sec): 170.0 MB/s
Did 27000 ChaCha20-Poly1305 (8192 bytes) seal operations in 1000336us (26990.9 ops/sec): 221.1 MB/s
Did 559000 ChaCha20-Poly1305-Old (16 bytes) seal operations in 1001465us (558182.3 ops/sec): 8.9 MB/s
Did 124000 ChaCha20-Poly1305-Old (1350 bytes) seal operations in 1000824us (123897.9 ops/sec): 167.3 MB/s
Did 28000 ChaCha20-Poly1305-Old (8192 bytes) seal operations in 1034854us (27057.0 ops/sec): 221.7 MB/s

aarch64, Nexus 6P
---
Old:
Did 358000 ChaCha20-Poly1305 (16 bytes) seal operations in 1000358us (357871.9 ops/sec): 5.7 MB/s
Did 45000 ChaCha20-Poly1305 (1350 bytes) seal operations in 1022386us (44014.7 ops/sec): 59.4 MB/s
Did 8657 ChaCha20-Poly1305 (8192 bytes) seal operations in 1063722us (8138.4 ops/sec): 66.7 MB/s
Did 350000 ChaCha20-Poly1305-Old (16 bytes) seal operations in 1000074us (349974.1 ops/sec): 5.6 MB/s
Did 44000 ChaCha20-Poly1305-Old (1350 bytes) seal operations in 1007907us (43654.8 ops/sec): 58.9 MB/s
Did 8525 ChaCha20-Poly1305-Old (8192 bytes) seal operations in 1042644us (8176.3 ops/sec): 67.0 MB/s
New:
Did 713000 ChaCha20-Poly1305 (16 bytes) seal operations in 1000190us (712864.6 ops/sec): 11.4 MB/s
Did 180000 ChaCha20-Poly1305 (1350 bytes) seal operations in 1004249us (179238.4 ops/sec): 242.0 MB/s
Did 41000 ChaCha20-Poly1305 (8192 bytes) seal operations in 1005811us (40763.1 ops/sec): 333.9 MB/s
Did 775000 ChaCha20-Poly1305-Old (16 bytes) seal operations in 1000719us (774443.2 ops/sec): 12.4 MB/s
Did 182000 ChaCha20-Poly1305-Old (1350 bytes) seal operations in 1003529us (181360.0 ops/sec): 244.8 MB/s
Did 41000 ChaCha20-Poly1305-Old (8192 bytes) seal operations in 1010576us (40570.9 ops/sec): 332.4 MB/s

Change-Id: Iaa4ab86ac1174b79833077963cc3616cfb08e686
Reviewed-on: https://boringssl-review.googlesource.com/7226
Reviewed-by: Adam Langley <agl@google.com>
2016-02-26 16:05:14 +00:00
David Benjamin a211aee545 Add SSL_CIPHER_has_SHA256_HMAC.
Change-Id: I05a8f5d1778aba1813fe4d34b4baa21849158218
Reviewed-on: https://boringssl-review.googlesource.com/7215
Reviewed-by: Adam Langley <agl@google.com>
2016-02-26 01:33:11 +00:00
David Benjamin e593fed378 Rename opensslfeatures.h to opensslconf.h.
Some software #includes opensslconf.h which typically contains settings that we
put in opensslfeatures.h (a header name not in OpenSSL). Rename it to
opensslconf.h.

Change-Id: Icd21dde172e5e489ce90dd5c16ae4d2696909fb6
Reviewed-on: https://boringssl-review.googlesource.com/7216
Reviewed-by: Adam Langley <agl@google.com>
2016-02-26 01:32:50 +00:00
David Benjamin a473e554b4 Add BIO_do_connect.
Some consumers of connect BIOs connect them explicitly, and we already have the
BIO_ctrl hooked up.

Change-Id: Ie6b14f8ceb272b560e2b534e0b6c32fae050475b
Reviewed-on: https://boringssl-review.googlesource.com/7217
Reviewed-by: Adam Langley <agl@google.com>
2016-02-26 01:32:21 +00:00
Brian Smith b4e3e694e8 Use correct counter after invoking stitched AES-NI GCM code.
Commit a3d9528e9e has a bug that could
cause counters to be reused if |$avx=2| were set in the AES-NI AES-GCM
assembly code, if the EVP interface were used with certain coding
patterns, as demonstrated by the test cases added in
a5ee83f67e.

This changes the encryption code in the same way the decryption code
was changed in a3d9528e9e.

This doesn't have any effect currently since the AES-NI AES-GCM code
has |$avx=0| now, so |aesni_gcm_encrypt| doesn't change the counter.

Change-Id: Iba69cb4d2043d1ea57c6538b398246af28cba006
Reviewed-on: https://boringssl-review.googlesource.com/7193
Reviewed-by: Adam Langley <agl@google.com>
2016-02-26 01:02:40 +00:00
David Benjamin 6234a7f3a7 Switch poly1305-armv4.pl to named constants.
See https://rt.openssl.org/Ticket/Display.html?id=4341.

Change-Id: Ied39744dcf557e4267c7a84d6f95d78a691084e1
Reviewed-on: https://boringssl-review.googlesource.com/7225
Reviewed-by: Adam Langley <agl@google.com>
2016-02-26 00:42:05 +00:00
David Benjamin f28caea521 Check in pristine copies of upstream's poly1305 assembly.
Taken from 6b2ebe4332e22b4eb7dd6fadf418e3da7b926ca4. These don't do anything
right now but are checked in unmodified to make diffs easier to see.

Change-Id: I4f5bdb7b16f4ac27e7ef175f475540c481b8d593
Reviewed-on: https://boringssl-review.googlesource.com/7224
Reviewed-by: Adam Langley <agl@google.com>
2016-02-26 00:41:48 +00:00
David Benjamin 8ccc3c383a Test poly1305 more aggressively.
OpenSSL upstream's SIMD assembly is rather complex. This pattern of update
calls should be sufficient to stress all the codepaths.

Change-Id: I50dea8351e4203b6b2cd9b23456eb4a592d31b5e
Reviewed-on: https://boringssl-review.googlesource.com/7223
Reviewed-by: Adam Langley <agl@google.com>
2016-02-26 00:32:41 +00:00
Steven Valdez 3f81b607fe Fix missing ok=0 with cert verification.
Also avoid using "i" in X509_cert_verify as a loop counter, trust
outcome and as an error ordinal.

(Imported from upstream's a3baa171053547488475709c7197592c66e427cf)

Change-Id: I4b0b542ffacf7fa861c93c8124b334c0aacc3c17
Reviewed-on: https://boringssl-review.googlesource.com/7222
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-25 20:43:58 +00:00
David Benjamin 06c5fb4512 Revert "Fix missing ok=0 with cert verification."
This reverts commit b0576889fa.

This broke x509_test.

Change-Id: Idbb60df9ca0a8ce727931f8e35e99bbd0f08c3c1
Reviewed-on: https://boringssl-review.googlesource.com/7221
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-25 20:23:38 +00:00
Steven Valdez fd26b7a015 If no comparison function is set, sk_sort is a NOP
(Imported from upstream's 402fb1896b2aab5cf887127bbce964554b9c8113)

Change-Id: I80c1f952085c8fc9062d3395f211a525151c404d
Reviewed-on: https://boringssl-review.googlesource.com/7219
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-25 20:02:53 +00:00
Steven Valdez b0576889fa Fix missing ok=0 with cert verification.
Also avoid using "i" in X509_cert_verify as a loop counter, trust
outcome and as an error ordinal.

(Imported from upstream's a3baa171053547488475709c7197592c66e427cf)

Change-Id: I492afdbaa5017bcf00a0412033cf99fca3fe9401
Reviewed-on: https://boringssl-review.googlesource.com/7218
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-25 20:01:07 +00:00
David Benjamin e42da0e4b4 Fix bssl rand -hex.
It emits NULs instead of c.

Change-Id: Id7f103eac049129dbf9a3e852454b22134ce3270
Reviewed-on: https://boringssl-review.googlesource.com/7220
Reviewed-by: Adam Langley <agl@google.com>
2016-02-25 19:23:58 +00:00
Brian Smith cd8d1761df Move |bn_div_words| to crypto/bn/div.c and make it static.
It is only used by |bn_div_rem_words|.

Change-Id: I57627091d8db5890d7fea34d8560897717008646
Reviewed-on: https://boringssl-review.googlesource.com/7128
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-25 16:16:14 +00:00
Brian Smith d1425f69df Simplify division-with-remainder calculations in crypto/bn/div.c.
Create a |bn_div_rem_words| that is used for double-word/single-word
divisions and division-with-remainder. Remove all implementations of
|bn_div_words| except for the implementation needed for 64-bit MSVC.
This allows more code to be shared across platforms and also removes
an instance of the dangerous pattern wherein the |div_asm| macro
modified a variable that wasn't passed as a parameter.

Also, document the limitations of the compiler-generated code for the
non-asm code paths more fully. Compilers indeed have not improved in
this respect.

Change-Id: I5a36a2edd7465de406d47d72dcd6bf3e63e5c232
Reviewed-on: https://boringssl-review.googlesource.com/7127
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-25 16:13:22 +00:00
Brian Smith 76c6381c21 Return 0 on error in |EC_POINT_is_on_curve| instead of -1.
Callers of this function are not checking for the -1 result. Change
the semantics to match their expectations and to match the common
semantics of most other parts of BoringSSL.

Change-Id: I4ec537d7619e20e8ddfee80c72125e4c02cfaac1
Reviewed-on: https://boringssl-review.googlesource.com/7125
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-24 22:00:58 +00:00
Brian Smith 0bc2349375 Remove unused |ccm128_context| in crypto/modes/internal.h.
Note that this structure has a weak pointer to the key, which was a
problem corrected in the AES-GCM code in
0f8bfdeb33. Also, it uses |void *|
instead of |const AES_KEY *| to refer to that key.

Change-Id: I70e632e3370ab27eb800bc1c0c64d2bd36b7cafb
Reviewed-on: https://boringssl-review.googlesource.com/7123
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-24 21:08:21 +00:00
Steven Valdez d8eea14443 BIO_new_mem_buf should take const void *
BIO_FLAGS_MEM_RDONLY keeps the invariant.

(Imported from upstream's a38a159bfcbc94214dda00e0e6b1fc6454a23b78)

Change-Id: I4cb35615d76b77929915e370dbb7fec1455da069
Reviewed-on: https://boringssl-review.googlesource.com/7214
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-24 19:14:19 +00:00
Adam Langley a5ee83f67e Test different chunk sizes in cipher_test.
This change causes cipher_test to test the EVP cipher interfaces with
various chunk sizes and adds a couple of large tests of GCM. This is
sufficient to uncover the issue that would have been caused by a3d9528e,
had the AVX code been enabled.

Change-Id: I58d4924c0bcd11a0999c24a0fb77fc5eee71130f
Reviewed-on: https://boringssl-review.googlesource.com/7192
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-24 18:12:57 +00:00
Steven Valdez 5ec72de203 Add missing EC NULL Check
(imported from upstream's 2b80d00e3ac652377ace84c51b53f51a1b7e1ba2)

Change-Id: Iee5a8d85d276033b6ac8bc9ac87e157916a1a29a
Reviewed-on: https://boringssl-review.googlesource.com/7212
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-24 17:33:22 +00:00
Steven Valdez b9824e2417 Handle SSL_shutdown while in init more appropriately
Calling SSL_shutdown while in init previously gave a "1" response,
meaning everything was successfully closed down (even though it
wasn't). Better is to send our close_notify, but fail when trying to
receive one.

The problem with doing a shutdown while in the middle of a handshake
is that once our close_notify is sent we shouldn't really do anything
else (including process handshake/CCS messages) until we've received a
close_notify back from the peer. However the peer might send a CCS
before acting on our close_notify - so we won't be able to read it
because we're not acting on CCS messages!

(Imported from upstream's f73c737c7ac908c5d6407c419769123392a3b0a9)
Change-Id: Iaad5c5e38983456d3697c955522a89919628024b
Reviewed-on: https://boringssl-review.googlesource.com/7207
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-24 15:57:09 +00:00
Steven Valdez e52d22d5f9 Empty SNI names are not valid
(Imported from upstream's 4d6fe78f65be650c84e14777c90e7a088f7a44ce)

Change-Id: Id28e0d49da2490e454dcb8603ccb93a506dfafaf
Reviewed-on: https://boringssl-review.googlesource.com/7206
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-24 15:49:09 +00:00
Steven Valdez e412bbd9a1 Fix wildcard match on punycode/IDNA DNS names
- bugfix: should not treat '--' as invalid domain substring.
- '-' should not be the first letter of a domain

(Imported from upstream's 15debc128ac13420a4eec9b4a66d72f1dfd69126)

Change-Id: Ifd8ff7cef1aab69da5cade8ff8c76c3a723f3838
Reviewed-on: https://boringssl-review.googlesource.com/7205
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-23 23:31:18 +00:00
David Benjamin 85003903fc Remove CRYPTO_set_NEON_functional.
This depends on https://codereview.chromium.org/1730823002/. The bit was only
ever targetted to one (rather old) CPU. Disable NEON on it uniformly, so we
don't have to worry about whether any new NEON code breaks it.

BUG=589200

Change-Id: Icc7d17d634735aca5425fe0a765ec2fba3329326
Reviewed-on: https://boringssl-review.googlesource.com/7211
Reviewed-by: Adam Langley <agl@google.com>
2016-02-23 23:19:46 +00:00
David Benjamin 030d08513e ymm registers are not suffixed with w.
This imports a fix to x86gas.pl from upstream's
a98c648e40ea5158c8ba29b5a70ccc239d426a20. It's needed to get poly1305-x86.pl
working.

Confirmed that this is a no-op for our current assembly files.

Change-Id: I28de1dbf421b29a06147d1aea3ff3659372a78b3
Reviewed-on: https://boringssl-review.googlesource.com/7210
Reviewed-by: Adam Langley <agl@google.com>
2016-02-23 23:18:53 +00:00
Brian Smith a3d9528e9e Unify AEAD and EVP code paths for AES-GCM.
This change makes the AEAD and EVP code paths use the same code for
AES-GCM. When AVX instructions are enabled in the assembly this will
allow them to use the stitched AES-GCM implementation.

Note that the stitched implementations are no-ops for small inputs
(smaller than 288 bytes for encryption; smaller than 96 bytes for
decryption). This means that only a handful of test cases with longish
inputs actually test the stitched code.

Change-Id: Iece8003d90448dcac9e0bde1f42ff102ebe1a1c9
Reviewed-on: https://boringssl-review.googlesource.com/7173
Reviewed-by: Adam Langley <agl@google.com>
2016-02-23 23:13:31 +00:00
David Benjamin 3dbecdf6f4 Append to CMAKE_ASM_FLAGS rather than replace it.
Otherwise we clobber things like -m32.

Change-Id: I9457e4b50dc3063643c31d19c7935276b8a312a1
Reviewed-on: https://boringssl-review.googlesource.com/7209
Reviewed-by: Adam Langley <agl@google.com>
2016-02-23 22:48:31 +00:00
David Benjamin 65f83b64d9 Set --noexecstack for assembly files in the standalone build.
See also upstream's 2966c2ec31e81187da3fbbe1499a6aa3acfd355f.

Change-Id: Iad0a0f11accb4fa2bd93667239dd7462f9fdbd7f
Reviewed-on: https://boringssl-review.googlesource.com/7180
Reviewed-by: Adam Langley <agl@google.com>
2016-02-23 22:38:44 +00:00
David Benjamin 35be688078 Enable upstream's ChaCha20 assembly for x86 and ARM (32- and 64-bit).
This removes chacha_vec_arm.S and chacha_vec.c in favor of unifying on
upstream's code. Upstream's is faster and this cuts down on the number of
distinct codepaths. Our old scheme also didn't give vectorized code on
Windows or aarch64.

BoringSSL-specific modifications made to the assembly:

- As usual, the shelling out to $CC is replaced with hardcoding $avx. I've
  tested up to the AVX2 codepath, so enable it all.

- I've removed the AMD XOP code as I have not tested it.

- As usual, the ARM file need the arm_arch.h include tweaked.

Speed numbers follow. We can hope for further wins on these benchmarks after
importing the Poly1305 assembly.

x86
---
Old:
Did 1422000 ChaCha20-Poly1305 (16 bytes) seal operations in 1000433us (1421384.5 ops/sec): 22.7 MB/s
Did 123000 ChaCha20-Poly1305 (1350 bytes) seal operations in 1003803us (122534.0 ops/sec): 165.4 MB/s
Did 22000 ChaCha20-Poly1305 (8192 bytes) seal operations in 1000282us (21993.8 ops/sec): 180.2 MB/s
Did 1428000 ChaCha20-Poly1305-Old (16 bytes) seal operations in 1000214us (1427694.5 ops/sec): 22.8 MB/s
Did 124000 ChaCha20-Poly1305-Old (1350 bytes) seal operations in 1006332us (123219.8 ops/sec): 166.3 MB/s
Did 22000 ChaCha20-Poly1305-Old (8192 bytes) seal operations in 1020771us (21552.3 ops/sec): 176.6 MB/s
New:
Did 1520000 ChaCha20-Poly1305 (16 bytes) seal operations in 1000567us (1519138.6 ops/sec): 24.3 MB/s
Did 152000 ChaCha20-Poly1305 (1350 bytes) seal operations in 1004216us (151361.9 ops/sec): 204.3 MB/s
Did 31000 ChaCha20-Poly1305 (8192 bytes) seal operations in 1009085us (30720.9 ops/sec): 251.7 MB/s
Did 1797000 ChaCha20-Poly1305-Old (16 bytes) seal operations in 1000141us (1796746.7 ops/sec): 28.7 MB/s
Did 171000 ChaCha20-Poly1305-Old (1350 bytes) seal operations in 1003204us (170453.9 ops/sec): 230.1 MB/s
Did 31000 ChaCha20-Poly1305-Old (8192 bytes) seal operations in 1005349us (30835.1 ops/sec): 252.6 MB/s

x86_64, no AVX2
---
Old:
Did 1782000 ChaCha20-Poly1305 (16 bytes) seal operations in 1000204us (1781636.5 ops/sec): 28.5 MB/s
Did 317000 ChaCha20-Poly1305 (1350 bytes) seal operations in 1001579us (316500.2 ops/sec): 427.3 MB/s
Did 62000 ChaCha20-Poly1305 (8192 bytes) seal operations in 1012146us (61256.0 ops/sec): 501.8 MB/s
Did 1778000 ChaCha20-Poly1305-Old (16 bytes) seal operations in 1000220us (1777608.9 ops/sec): 28.4 MB/s
Did 315000 ChaCha20-Poly1305-Old (1350 bytes) seal operations in 1002886us (314093.5 ops/sec): 424.0 MB/s
Did 71000 ChaCha20-Poly1305-Old (8192 bytes) seal operations in 1014606us (69977.9 ops/sec): 573.3 MB/s
New:
Did 1866000 ChaCha20-Poly1305 (16 bytes) seal operations in 1000019us (1865964.5 ops/sec): 29.9 MB/s
Did 399000 ChaCha20-Poly1305 (1350 bytes) seal operations in 1001017us (398594.6 ops/sec): 538.1 MB/s
Did 84000 ChaCha20-Poly1305 (8192 bytes) seal operations in 1005645us (83528.5 ops/sec): 684.3 MB/s
Did 1881000 ChaCha20-Poly1305-Old (16 bytes) seal operations in 1000325us (1880388.9 ops/sec): 30.1 MB/s
Did 404000 ChaCha20-Poly1305-Old (1350 bytes) seal operations in 1000004us (403998.4 ops/sec): 545.4 MB/s
Did 85000 ChaCha20-Poly1305-Old (8192 bytes) seal operations in 1010048us (84154.4 ops/sec): 689.4 MB/s

x86_64, AVX2
---
Old:
Did 2375000 ChaCha20-Poly1305 (16 bytes) seal operations in 1000282us (2374330.4 ops/sec): 38.0 MB/s
Did 448000 ChaCha20-Poly1305 (1350 bytes) seal operations in 1001865us (447166.0 ops/sec): 603.7 MB/s
Did 88000 ChaCha20-Poly1305 (8192 bytes) seal operations in 1005217us (87543.3 ops/sec): 717.2 MB/s
Did 2409000 ChaCha20-Poly1305-Old (16 bytes) seal operations in 1000188us (2408547.2 ops/sec): 38.5 MB/s
Did 446000 ChaCha20-Poly1305-Old (1350 bytes) seal operations in 1001003us (445553.1 ops/sec): 601.5 MB/s
Did 90000 ChaCha20-Poly1305-Old (8192 bytes) seal operations in 1006722us (89399.1 ops/sec): 732.4 MB/s
New:
Did 2622000 ChaCha20-Poly1305 (16 bytes) seal operations in 1000266us (2621302.7 ops/sec): 41.9 MB/s
Did 794000 ChaCha20-Poly1305 (1350 bytes) seal operations in 1000783us (793378.8 ops/sec): 1071.1 MB/s
Did 173000 ChaCha20-Poly1305 (8192 bytes) seal operations in 1000176us (172969.6 ops/sec): 1417.0 MB/s
Did 2623000 ChaCha20-Poly1305-Old (16 bytes) seal operations in 1000330us (2622134.7 ops/sec): 42.0 MB/s
Did 783000 ChaCha20-Poly1305-Old (1350 bytes) seal operations in 1000531us (782584.4 ops/sec): 1056.5 MB/s
Did 174000 ChaCha20-Poly1305-Old (8192 bytes) seal operations in 1000840us (173854.0 ops/sec): 1424.2 MB/s

arm, Nexus 4
---
Old:
Did 388550 ChaCha20-Poly1305 (16 bytes) seal operations in 1000580us (388324.8 ops/sec): 6.2 MB/s
Did 90000 ChaCha20-Poly1305 (1350 bytes) seal operations in 1003816us (89657.9 ops/sec): 121.0 MB/s
Did 19000 ChaCha20-Poly1305 (8192 bytes) seal operations in 1045750us (18168.8 ops/sec): 148.8 MB/s
Did 398500 ChaCha20-Poly1305-Old (16 bytes) seal operations in 1000305us (398378.5 ops/sec): 6.4 MB/s
Did 90500 ChaCha20-Poly1305-Old (1350 bytes) seal operations in 1000305us (90472.4 ops/sec): 122.1 MB/s
Did 19000 ChaCha20-Poly1305-Old (8192 bytes) seal operations in 1043278us (18211.8 ops/sec): 149.2 MB/s
New:
Did 424788 ChaCha20-Poly1305 (16 bytes) seal operations in 1000641us (424515.9 ops/sec): 6.8 MB/s
Did 115000 ChaCha20-Poly1305 (1350 bytes) seal operations in 1001526us (114824.8 ops/sec): 155.0 MB/s
Did 27000 ChaCha20-Poly1305 (8192 bytes) seal operations in 1033023us (26136.9 ops/sec): 214.1 MB/s
Did 447750 ChaCha20-Poly1305-Old (16 bytes) seal operations in 1000549us (447504.3 ops/sec): 7.2 MB/s
Did 117500 ChaCha20-Poly1305-Old (1350 bytes) seal operations in 1001923us (117274.5 ops/sec): 158.3 MB/s
Did 27000 ChaCha20-Poly1305-Old (8192 bytes) seal operations in 1025118us (26338.4 ops/sec): 215.8 MB/s

aarch64, Nexus 6p
(Note we didn't have aarch64 assembly before at all, and still don't have it
for Poly1305. Hopefully once that's added this will be faster than the arm
numbers...)
---
Old:
Did 145040 ChaCha20-Poly1305 (16 bytes) seal operations in 1003065us (144596.8 ops/sec): 2.3 MB/s
Did 14000 ChaCha20-Poly1305 (1350 bytes) seal operations in 1042605us (13427.9 ops/sec): 18.1 MB/s
Did 2618 ChaCha20-Poly1305 (8192 bytes) seal operations in 1093241us (2394.7 ops/sec): 19.6 MB/s
Did 148000 ChaCha20-Poly1305-Old (16 bytes) seal operations in 1000709us (147895.1 ops/sec): 2.4 MB/s
Did 14000 ChaCha20-Poly1305-Old (1350 bytes) seal operations in 1047294us (13367.8 ops/sec): 18.0 MB/s
Did 2607 ChaCha20-Poly1305-Old (8192 bytes) seal operations in 1090745us (2390.1 ops/sec): 19.6 MB/s
New:
Did 358000 ChaCha20-Poly1305 (16 bytes) seal operations in 1000769us (357724.9 ops/sec): 5.7 MB/s
Did 45000 ChaCha20-Poly1305 (1350 bytes) seal operations in 1021267us (44062.9 ops/sec): 59.5 MB/s
Did 8591 ChaCha20-Poly1305 (8192 bytes) seal operations in 1047136us (8204.3 ops/sec): 67.2 MB/s
Did 343000 ChaCha20-Poly1305-Old (16 bytes) seal operations in 1000489us (342832.4 ops/sec): 5.5 MB/s
Did 44000 ChaCha20-Poly1305-Old (1350 bytes) seal operations in 1008326us (43636.7 ops/sec): 58.9 MB/s
Did 8866 ChaCha20-Poly1305-Old (8192 bytes) seal operations in 1083341us (8183.9 ops/sec): 67.0 MB/s

Change-Id: I629fe195d072f2c99e8f947578fad6d70823c4c8
Reviewed-on: https://boringssl-review.googlesource.com/7202
Reviewed-by: Adam Langley <agl@google.com>
2016-02-23 17:19:45 +00:00
David Benjamin 0182ecd346 Consistently use named constants in ARM assembly files.
Most of the OPENSSL_armcap_P accesses in assembly use named constants from
arm_arch.h, but some don't. Consistently use the constants. The dispatch really
should be in C, but in the meantime, make it easier to tell what's going on.

I'll send this patch upstream so we won't be carrying a diff here.

Change-Id: I63c68d2351ea5ce11005813314988e32b6459526
Reviewed-on: https://boringssl-review.googlesource.com/7203
Reviewed-by: Adam Langley <agl@google.com>
2016-02-23 17:18:18 +00:00
David Benjamin 295960044b Fix chacha-armv4.pl.
Patch taken from https://rt.openssl.org/Ticket/Display.html?id=4323.

Change-Id: Icbaf8f9a0f92da48f213b251b0afa4b0d5aa627d
Reviewed-on: https://boringssl-review.googlesource.com/7201
Reviewed-by: Adam Langley <agl@google.com>
2016-02-23 01:07:48 +00:00
David Benjamin ea4d6863c7 Check in pristine copies of OpenSSL's chacha-{arm*,x86}.pl.
They won't be used as-is. This is just to make the diffs easier to see. Taken
from upstream's 4f16039efe3589aa4d63a6f1fab799d0cd9338ca.

Change-Id: I34d8be409f9c8f15b8a6da4b2d98ba3e60aa2210
Reviewed-on: https://boringssl-review.googlesource.com/7200
Reviewed-by: Adam Langley <agl@google.com>
2016-02-23 01:06:43 +00:00
Adam Langley b104517f1d Add some bug references to the LICENSE file.
Add references for some cases where we have explicit permission from
authors to use their work. This is just to make things easy for us to
find.

Change-Id: I47dacc6a80f9d0c960c5b6713a8dc25e1a4e6f0b
Reviewed-on: https://boringssl-review.googlesource.com/7191
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-22 20:16:48 +00:00
Adam Langley 65dcfc7f9b Remove CP_UTF8 code for Windows filenames.
Thanks to Gisle Vanem for pointing out that this code was broken and
could never have compiled. Since it has never worked, and thus has never
been used, remove it.

Change-Id: Ic274eaf187928765a809690eda8d790b79f939a5
Reviewed-on: https://boringssl-review.googlesource.com/7190
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-22 17:19:33 +00:00
Brian Smith 6d49157929 Restore |xmm7| correctly on Win64 in aesni-gcm-x86_64.
See OpenSSL df057ea6c8a20e4babc047689507dfafde59ffd6.

Change-Id: Ife10dc13ca335cd51434d7769ff85c6929f10226
Reviewed-on: https://boringssl-review.googlesource.com/7172
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-18 15:50:46 +00:00
Adam Langley e976e4349d Don't read uninitialised data for short session IDs.
While it's always safe to read |SSL_MAX_SSL_SESSION_ID_LENGTH| bytes
from an |SSL_SESSION|'s |session_id| array, the hash function would do
so with without considering if all those bytes had been written to.

This change checks |session_id_length| before possibly reading
uninitialised memory. Since the result of the hash function was already
attacker controlled, and since a lookup of a short session ID will
always fail, it doesn't appear that this is anything more than a clean
up.

BUG=586800

Change-Id: I5f59f245b51477d6d4fa2cdc20d40bb6b4a3eae7
Reviewed-on: https://boringssl-review.googlesource.com/7150
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-18 15:45:48 +00:00
David Benjamin f48fcaf901 Have fuzz/cert.cc also call X509_get_pubkey.
crypto/x509 parses the SPKI on-demand, so we weren't actually exercising the
SPKI code.

Change-Id: I2e16045bd35dbe04d4b8d8b45939c8885e09a550
Reviewed-on: https://boringssl-review.googlesource.com/7161
Reviewed-by: Adam Langley <agl@google.com>
2016-02-18 00:10:15 +00:00
David Benjamin de94238217 Fix SSL_get_{read,write}_sequence.
I switched up the endianness. Add some tests to make sure those work right.

Also tweak the DTLS semantics. SSL_get_read_sequence should return the highest
sequence number received so far. Include the epoch number in both so we don't
need a second API for it.

Change-Id: I9901a1665b41224c46fadb7ce0b0881dcb466bcc
Reviewed-on: https://boringssl-review.googlesource.com/7141
Reviewed-by: Adam Langley <agl@google.com>
2016-02-17 22:05:29 +00:00
David Benjamin d3a49953d8 Add missing " in comment.
Change-Id: If33d3a11a0b48403fc009688b9300c92e5494d94
Reviewed-on: https://boringssl-review.googlesource.com/7160
Reviewed-by: Adam Langley <agl@google.com>
2016-02-17 21:17:26 +00:00
David Benjamin f4ef9b517e otherPrimeInfos is not optional in version 1 RSAPrivateKeys.
Currently, we correctly refuse to parse version 0 multi-prime keys, but we
still parse version 1 two-prime keys. Both should be rejected.

I missed an additional clause in the spec originally. It seems otherPrimeInfos
is marked OPTIONAL not because it is actually optional, but because they wanted
the two RSAPrivateKey forms to share one definition. The prose rules following
the definition imply that otherPrimeInfos' presence is entirely determined by
the version:

    * version is the version number, for compatibility with future
      revisions of this document.  It shall be 0 for this version of the
      document, unless multi-prime is used, in which case it shall be 1.

            Version ::= INTEGER { two-prime(0), multi(1) }
               (CONSTRAINED BY
               {-- version must be multi if otherPrimeInfos present --})

and:

    * otherPrimeInfos contains the information for the additional primes
      r_3, ..., r_u, in order.  It shall be omitted if version is 0 and
      shall contain at least one instance of OtherPrimeInfo if version
      is 1.

Change-Id: I458232a2e20ed68fddcc39c4c45333f33441f70b
Reviewed-on: https://boringssl-review.googlesource.com/7143
Reviewed-by: Adam Langley <agl@google.com>
2016-02-17 18:28:05 +00:00
David Benjamin 9cd7fbdac6 Remove support for blocks in file_test.h.
That was probably more complexity than we needed. Nothing uses it
anymore, now that getting to the PKCS#8 logic isn't especially tedious.

Change-Id: I4f0393b1bd75e71664f65e3722c14c483c13c5cf
Reviewed-on: https://boringssl-review.googlesource.com/6867
Reviewed-by: Adam Langley <agl@google.com>
2016-02-17 17:24:57 +00:00
David Benjamin e30a09e604 Implement new PKCS#8 parsers.
As with SPKI parsers, the intent is make EVP_PKEY capture the key's
constraints in full fidelity, so we'd have to add new types or store the
information in the underlying key object if people introduce variant key
types with weird constraints on them.

Note that because PKCS#8 has a space for arbitrary attributes, this
parser must admit a hole. I'm assuming for now that we don't need an API
that enforces no attributes and just ignore trailing data in the
structure for simplicity.

BUG=499653

Change-Id: I6fc641355e87136c7220f5d7693566d1144a68e8
Reviewed-on: https://boringssl-review.googlesource.com/6866
Reviewed-by: Adam Langley <agl@google.com>
2016-02-17 17:24:10 +00:00
David Benjamin 440f103771 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-17 16:32:31 +00:00
David Benjamin 239a0abfd5 Slightly simplify and deprecate i2d_{Public,Private}Key.
There are all the type-specific serializations rather than something
tagged with a type. i2d_PrivateKey's PKCS#8 codepath was unreachable
because every EVP_PKEY type has an old_priv_encode function.

To prune EVP_PKEY_ASN1_METHOD further, replace i2d_PrivateKey into a
switch case so we don't need to keep old_priv_encode around. This cuts
down on a case of outside modules reaching into crypto/evp method
tables.

Change-Id: I30db2eed836d560056ba9d1425b960d0602c3cf2
Reviewed-on: https://boringssl-review.googlesource.com/6865
Reviewed-by: Adam Langley <agl@google.com>
2016-02-17 16:31:26 +00:00
David Benjamin 32fdc512ca Remove param_decode and param_encode EVP_PKEY hooks.
They're only used by a pair of PEM functions, which are never used.

BUG=499653

Change-Id: I89731485c66ca328c634efbdb7e182a917f2a963
Reviewed-on: https://boringssl-review.googlesource.com/6863
Reviewed-by: Adam Langley <agl@google.com>
2016-02-17 16:30:29 +00:00
David Benjamin 68772b31b0 Implement new SPKI parsers.
Many consumers need SPKI support (X.509, TLS, QUIC, WebCrypto), each
with different ways to set signature parameters. SPKIs themselves can
get complex with id-RSASSA-PSS keys which come with various constraints
in the key parameters. This suggests we want a common in-library
representation of an SPKI.

This adds two new functions EVP_parse_public_key and
EVP_marshal_public_key which converts EVP_PKEY to and from SPKI and
implements X509_PUBKEY functions with them. EVP_PKEY seems to have been
intended to be able to express the supported SPKI types with
full-fidelity, so these APIs will continue this.

This means future support for id-RSASSA-PSS would *not* repurpose
EVP_PKEY_RSA. I'm worried about code assuming EVP_PKEY_RSA implies
acting on the RSA* is legal. Instead, it'd add an EVP_PKEY_RSA_PSS and
the data pointer would be some (exposed, so the caller may still check
key size, etc.) RSA_PSS_KEY struct. Internally, the EVP_PKEY_CTX
implementation would enforce the key constraints. If RSA_PSS_KEY would
later need its own API, that code would move there, but that seems
unlikely.

Ideally we'd have a 1:1 correspondence with key OID, although we may
have to fudge things if mistakes happen in standardization. (Whether or
not X.509 reuses id-ecPublicKey for Ed25519, we'll give it a separate
EVP_PKEY type.)

DSA parsing hooks are still implemented, missing parameters and all for
now. This isn't any worse than before.

Decoupling from the giant crypto/obj OID table will be a later task.

BUG=522228

Change-Id: I0e3964edf20cb795a18b0991d17e5ca8bce3e28c
Reviewed-on: https://boringssl-review.googlesource.com/6861
Reviewed-by: Adam Langley <agl@google.com>
2016-02-17 16:28:07 +00:00
David Benjamin 2dc469e066 Remove dead header file.
There's nothing in here.

Change-Id: I3a501389e7e237b2e6907f27d2eb788a298d6c03
Reviewed-on: https://boringssl-review.googlesource.com/6877
Reviewed-by: Adam Langley <agl@google.com>
2016-02-17 01:34:15 +00:00
David Benjamin df98a7ad3a Reimplement DSA_size without crypto/asn1.
BUG=499653

Change-Id: I16963fb198609d7fc0df6c57923cda3e13350753
Reviewed-on: https://boringssl-review.googlesource.com/6875
Reviewed-by: Adam Langley <agl@google.com>
2016-02-17 01:02:51 +00:00
David Benjamin fda22a7573 Reimplement DSA parsing logic with crypto/asn1.
Functions which lose object reuse and need auditing:
- d2i_DSA_SIG
- d2i_DSAPublicKey
- d2i_DSAPrivateKey
- d2i_DSAparams

BUG=499653

Change-Id: I1cc2ae10e1e77eb57da3a858ac8734a95715ce4b
Reviewed-on: https://boringssl-review.googlesource.com/7022
Reviewed-by: Adam Langley <agl@google.com>
2016-02-17 00:26:01 +00:00
David Benjamin 3cadf63c68 Remove DSA write_params.
This imports upstream's ea6b07b54c1f8fc2275a121cdda071e2df7bd6c1 along
with a bugfix in 987157f6f63fa70dbeffca3c8bc62f26e9767ff2.

In an SPKI, a DSA key is only an INTEGER, with the group information in
the AlgorithmIdentifier. But a standalone DSAPublicKey is more complex
(and apparently made up by OpenSSL). OpenSSL implemented this with a
write_params boolean and making DSAPublicKey a CHOICE.

Instead, have p_dsa_asn1.c encode an INTEGER directly. d2i_DSAPublicKey
only parses the standalone form. (That code will be replaced later, but
first do this in preparation for rewriting the DSA ASN.1 code.)

Change-Id: I6fbe298d2723b9816806e9c196c724359b9ffd63
Reviewed-on: https://boringssl-review.googlesource.com/7021
Reviewed-by: Adam Langley <agl@google.com>
2016-02-16 23:54:38 +00:00
David Benjamin 985da09340 Remove flags field from EC_KEY.
It doesn't do anything.

Change-Id: Ifcc2c824faf6012d2a442208b8204a32e141a650
Reviewed-on: https://boringssl-review.googlesource.com/7073
Reviewed-by: Adam Langley <agl@google.com>
2016-02-16 23:51:53 +00:00
David Benjamin 2f6410ba4e Rewrite ECPrivateKey serialization.
Functions which lose object reuse and need auditing:
- d2i_ECParameters
- d2i_ECPrivateKey

This adds a handful of bytestring-based APIs to handle EC key
serialization. Deprecate all the old serialization APIs. Notes:

- An EC_KEY has additional state that controls its encoding, enc_flags
  and conv_form. conv_form is left alone, but enc_flags in the new API
  is an explicit parameter.

- d2i_ECPrivateKey interpreted its T** argument unlike nearly every
  other d2i function. This is an explicit EC_GROUP parameter in the new
  function.

- The new specified curve code is much stricter and should parse enough
  to uniquely identify the curve.

- I've not bothered with a new version of i2d_ECParameters. It just
  writes an OID. This may change later when decoupling from the giant
  OID table.

- Likewise, I've not bothered with new APIs for the public key since the
  EC_POINT APIs should suffice.

- Previously, d2i_ECPrivateKey would not call EC_KEY_check_key and it
  was possible for the imported public and private key to mismatch. It
  now calls it.

BUG=499653

Change-Id: I30b4dd2841ae76c56ab0e1808360b2628dee0615
Reviewed-on: https://boringssl-review.googlesource.com/6859
Reviewed-by: Adam Langley <agl@google.com>
2016-02-16 23:51:09 +00:00
David Benjamin 666973b8e9 Add tests for EC keys with specified curves.
In c0d9484902, we had to add support for
recognizing specified versions of named curves. I believe the motivation
was an ECPrivateKey encoded by OpenSSL without the EC_KEY's asn1_flag
set to OPENSSL_EC_NAMED_CURVE. Annoyingly, it appears OpenSSL's API
defaulted to the specified form while the tool defaulted to the named
form.

Add tests for this at the ECPrivateKey and the PKCS#8 level. The latter
was taken from Chromium's ec_private_key_unittest.cc which was the
original impetus for this.

Change-Id: I53a80c842c3fc9598f2e0ee7bf2d86b2add9e6c4
Reviewed-on: https://boringssl-review.googlesource.com/7072
Reviewed-by: Adam Langley <agl@google.com>
2016-02-16 21:51:32 +00:00
Adam Langley 815b12ece6 ed25519: Don't negate output when decoding.
The function |ge_frombytes_negate_vartime|, as the name suggests,
negates its output. This change converts it to |ge_frombytes_vartime|
and, instead, does the negation explicitly when verifying signatures.
The latter function is more generally useful.

Change-Id: I465f8bdf5edb101a80ab1835909ae0ff41d3e295
Reviewed-on: https://boringssl-review.googlesource.com/7142
Reviewed-by: Arnar Birgisson <arnarb@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-16 21:07:44 +00:00
David Benjamin bd42603943 Add a convenience function for i2d compatibility wrappers.
An i2d compatibility function is rather long, so add CBB_finish_i2d for
part of it. It takes a CBB as input so only a 'marshal' function is
needed, rather than a 'to_bytes' one.

Also replace the *inp d2i update pattern with a slightly shorter one.

Change-Id: Ibb41059c9532f6a8ce33460890cc1afe26adc97c
Reviewed-on: https://boringssl-review.googlesource.com/6868
Reviewed-by: Adam Langley <agl@google.com>
2016-02-16 19:40:53 +00:00
David Benjamin 375124b162 Parse BER for PKCS#12 more accurately.
CBS_asn1_ber_to_der currently uses heuristics because implicitly-tagged
constructed strings in BER are ambiguous with implicitly-tagged sequences. It's
not possible to convert BER to DER without knowing the schema.

Fortunately, implicitly tagged strings don't appear often so instead split the
job up: CBS_asn1_ber_to_der fixes indefinite-length elements and constructed
strings it can see. Implicitly-tagged strings it leaves uncoverted, but they
will only nest one level down (because BER kindly allows one to nest
constructed strings arbitrarily!).

CBS_get_asn1_implicit_string then performs the final concatenation at parse
time. This isn't much more complex and lets us parse BER more accurately and
also reject a number of mis-encoded values (e.g. constructed INTEGERs are not a
thing) we'd previously let through. The downside is the post-conversion parsing
code must be aware of this limitation of CBS_asn1_ber_to_der. Fortunately,
there's only one implicitly-tagged string in our PKCS#12 code.

(In the category of things that really really don't matter, but I had spare
cycles and the old BER converter is weird.)

Change-Id: Iebdd13b08559fa158b308ef83a5bb07bfdf80ae8
Reviewed-on: https://boringssl-review.googlesource.com/7052
Reviewed-by: Adam Langley <agl@google.com>
2016-02-16 19:32:50 +00:00
David Benjamin fb974e6cb3 Use initializer lists to specify cipher rule tests.
This is significantly less of a nuisance than having to explicitly type out
kRule5, kExpected5.

Change-Id: I61820c26a159c71e09000fbe0bf91e30da42205e
Reviewed-on: https://boringssl-review.googlesource.com/7000
Reviewed-by: Adam Langley <agl@google.com>
2016-02-16 18:42:07 +00:00
Brian Smith 894a47df24 Clarify some confusing casts involving |size_t|.
Change-Id: I7af2c87fe6e7513aa2603d5e845a4db87ab14fcc
Reviewed-on: https://boringssl-review.googlesource.com/7101
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-12 15:37:15 +00:00
Brian Smith 11676a7399 Use |kSizeTWithoutLower4Bits| in crypto/modes/gcm.c.
Some instances were missed in eca509c8da.

Change-Id: I53a6bd944fbf0df439b8e6f9db761f61d7237ba2
Reviewed-on: https://boringssl-review.googlesource.com/7103
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-11 22:08:42 +00:00
Brian Smith 5ba06897be Don't cast |OPENSSL_malloc|/|OPENSSL_realloc| result.
C has implicit conversion of |void *| to other pointer types so these
casts are unnecessary. Clean them up to make the code easier to read
and to make it easier to find dangerous casts.

Change-Id: I26988a672e8ed4d69c75cfbb284413999b475464
Reviewed-on: https://boringssl-review.googlesource.com/7102
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-11 22:07:56 +00:00
Brian Smith 46a4d6d705 Remove out-of-date and misleading comment in |bn_blinding_st|.
I guess the comment "just a reference" was intended to mean that the
|mod| member is a weak reference to a |BIGNUM| owned by something else.
However, it is actually owned by the |bn_blinding_st|, as one can see
by reading |BN_BLINDING_new| and |BN_BLINDING_free|.

Change-Id: If2a681fc9d9db536170e0efb11fdab93e4f0baba
Reviewed-on: https://boringssl-review.googlesource.com/7112
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-11 22:01:14 +00:00
David Benjamin 3ab3e3db6e Mark ARM assembly globals hidden uniformly in arm-xlate.pl.
We'd manually marked some of them hidden, but missed some. Do it in the perlasm
driver instead since we will never expose an asm symbol directly. This reduces
some of our divergence from upstream on these files (and indeed we'd
accidentally lose some .hiddens at one point).

BUG=586141

Change-Id: Ie1bfc6f38ba73d33f5c56a8a40c2bf1668562e7e
Reviewed-on: https://boringssl-review.googlesource.com/7140
Reviewed-by: Adam Langley <agl@google.com>
2016-02-11 17:28:03 +00:00
David Benjamin 5acc423517 Add a CONTRIBUTING.md file.
Change-Id: I4e1ed0aaddf4dc516a81155ef62dba138f8495ae
Reviewed-on: https://boringssl-review.googlesource.com/7120
Reviewed-by: Adam Langley <agl@google.com>
2016-02-10 21:38:19 +00:00
nmittler 042e8f721a Updating BUILDING.md for windows.
Updating the Perl docs to describe behavior of Strawberry Perl and possible
interaction with CMake on Windows.

Also adding a few other links and instructions for using CMake/Ninja to build
release mode with position independent code, since this seems generally useful.

Change-Id: I616c0d267da749fe90673bc9e8bde9ec181fec25
Reviewed-on: https://boringssl-review.googlesource.com/7113
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-10 17:42:36 +00:00
Brian Smith 642b0b825e Remove unused bits of RSA blinding code.
The |_ex| versions of these functions are unnecessary because when they
are used, they are always passed |NULL| for |r|, which is what the
non-|_ex| versions do. Just use the non-|_ex| versions instead and
remove the |_ex| versions.

Also, drop the unused flags mechanism.

Change-Id: Ida4cb5a2d4c89d9cd318e06f71867aea98408d0d
Reviewed-on: https://boringssl-review.googlesource.com/7110
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-09 16:45:13 +00:00
Brian Smith a051bdd6cd Remove dead non-|BN_ULLONG|, non-64-bit-MSVC code in crypto/bn.
It is always the case that either |BN_ULLONG| is defined or
|BN_UMULT_LOHI| is defined because |BN_ULLONG| is defined everywhere
except 64-bit MSVC, and BN_UMULT_LOHI is defined for 64-bit MSVC.

Change-Id: I85e5d621458562501af1af65d587c0b8d937ba3b
Reviewed-on: https://boringssl-review.googlesource.com/7044
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-09 16:21:41 +00:00
Brian Smith 767e1210e0 Remove unused Simics code in crypto/bn/asm/x86_64-gcc.c.
Change-Id: If9c5031855c0acfafb73caba169e146f0e16f706
Reviewed-on: https://boringssl-review.googlesource.com/7093
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-08 23:41:47 +00:00
Brian Smith b121a26736 Remove unused |ec_GFp_simple_group_check_discriminant|.
Change-Id: I995a445fea1de7f85ec917694abb8273a82339d3
Reviewed-on: https://boringssl-review.googlesource.com/7092
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-08 18:33:09 +00:00
Brian Smith 4862b3b93c Remove useless and out-of-date comments in crypto/ec/internal.h.
Change-Id: Ia80372316e67822d44b8b90f7983f3ef773ed0fd
Reviewed-on: https://boringssl-review.googlesource.com/7091
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-08 18:32:20 +00:00
Brian Smith fce7604350 Remove duplicative ECC |group_init| and |group_set_curve| methods.
|a_is_minus_3| is calculated in |ec_GFp_simple_group_set_curve|, so
the custom |group_init| functions are unnecessary. Just as in
commit 9f1f04f313, it is never the case
that custom parameters are passed to the |group_set_curve| method for
these curves.

Change-Id: I18a38b104bc332e44cc2053c465cf234f4c5163b
Reviewed-on: https://boringssl-review.googlesource.com/7090
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-08 18:31:46 +00:00
Brian Smith aadf1ee77f Minimize the scope of the |BN_*_SIZE_*| constants.
mul.c is the only file that uses these values.

Change-Id: I50a685cbff0f26357229e742f42e014434e9cebe
Reviewed-on: https://boringssl-review.googlesource.com/7061
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-08 18:28:31 +00:00
Brian Smith 8c5ea1338a Remove unused |bn_mul_low_normal| and related #defines.
Change-Id: I2e3745f5dd5132a48dcbf472bca3638324dfc7a3
Reviewed-on: https://boringssl-review.googlesource.com/7060
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-08 18:25:23 +00:00
David Benjamin 2c71ce135c Update some URLs in BUILDING.md.
Change-Id: Ic7aa22b10d2d69bdc3a548273640574203e93012
Reviewed-on: https://boringssl-review.googlesource.com/7071
Reviewed-by: Adam Langley <agl@google.com>
2016-02-08 18:12:56 +00:00
David Benjamin 6b34d54945 Prefer MSVC over GCC if both are in %PATH%.
Notably, putting Strawberry Perl in %PATH% will usually end up putting a copy
of gcc in %PATH%, which trips up people trying to build on Windows.

This is arguably misusing the variable (normally set by the generator), but it
should work.

Change-Id: I13a011eb33688ae928a56cce266edd2759a3cb32
Reviewed-on: https://boringssl-review.googlesource.com/7070
Reviewed-by: Adam Langley <agl@google.com>
2016-02-08 18:12:36 +00:00
David Benjamin 089cba090c No-op change to kick the bots again.
Infra fixed some stuff. Let's try again.

Change-Id: Ib5f3d7e94091655ee5893ae19e5e0bfbfe888b3d
2016-02-05 21:44:56 -05:00
Brian Smith f98be21fad Remove dead platform-specific code in |BN_div|.
It is always the case that |BN_ULLONG| is defined or we're building for
64-bit MSVC. Lots of code is trying to handle impossible cases where
neither of those is true.

Change-Id: Ie337adda1dfb453843c6e0999807dfa1afb1ed89
Reviewed-on: https://boringssl-review.googlesource.com/7043
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-05 23:12:11 +00:00
David Benjamin a37fc70175 Another no-op change.
I did that too quickly. The machines hadn't picked up the new recipe yet.

Change-Id: Ie63c8f022049ba72106b0a31bc35b20819514707
2016-02-05 17:59:15 -05:00
David Benjamin fcde5aa74d No-op change to kick the bots.
Windows build failures seem to have been a CMake statefulness problem. Recipes
were changed to do clean builds each run.

Change-Id: Id5aefa53aead7e82e095d7dccbf88ad89a678c62
2016-02-05 17:52:28 -05:00
Brian Smith 926f2194df Enable MSVC 128-bit multiplication regardless of OPENSSL_NO_ASM.
This allows much code to be subsequently simplified and removed.

Change-Id: I0ac256957c6eae9f35a70508bd454cb44f3f8653
Reviewed-on: https://boringssl-review.googlesource.com/7042
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-05 00:30:34 +00:00
David Benjamin 11aac10987 Fix theoretical memory leak on malloc error in CBS_asn1_ber_to_der.
On failure, CBB_finish doesn't call CBB_cleanup. Also chain more of the ||s
together now that CBB_cleanup after failed CBB_init is legal.

(I don't think this is actually reachable because the CBB is guaranteed to be
flushed by this point.)

Change-Id: Ib16a0a185f15e13675ac2550c5e8e0926ceb7957
Reviewed-on: https://boringssl-review.googlesource.com/7051
Reviewed-by: Adam Langley <agl@google.com>
2016-02-04 17:23:28 +00:00
Brian Smith 168297e870 Test |ECDSA_SIG_to_bytes| using the P-521 order size, not 512-bits.
There was a test for 512 bit orders but not one for 521-bit orders.
Test 521-bit orders instead.

Change-Id: I61a76d02637ca55d8ae21834085311dd84fd870f
Reviewed-on: https://boringssl-review.googlesource.com/7011
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-03 23:26:42 +00:00
Adam Langley d057454f90 Changes to support node.js's use of PKCS#12.
node.js uses a memory BIO in the wrong mode which, for now, we work
around. It also passes in NULL (rather than empty) strings and a
non-NULL out-arg for |d2i_PKCS12_bio|.

Change-Id: Ib565b4a202775bb32fdcb76db8a4e8c54268c052
Reviewed-on: https://boringssl-review.googlesource.com/7012
Reviewed-by: Adam Langley <agl@google.com>
2016-02-02 19:21:59 +00:00
David Benjamin e66148a18f Drop dh->q in bssl_shim when -use-sparse-dh-prime is passed.
Otherwise it still thinks this is an RFC 5114 prime and kicks in the (now
incorrect) validity check.

Change-Id: Ie78514211927f1f2d2549958621cb7896f68b5ce
Reviewed-on: https://boringssl-review.googlesource.com/7050
Reviewed-by: Adam Langley <agl@google.com>
2016-02-02 19:18:27 +00:00
David Benjamin 6014ea6248 Add EC_POINT_point2cbb.
This slightly simplifies the SSL_ECDH code and will be useful later on
in reimplementing the key parsing logic.

Change-Id: Ie41ea5fd3a9a734b3879b715fbf57bd991e23799
Reviewed-on: https://boringssl-review.googlesource.com/6858
Reviewed-by: Adam Langley <agl@google.com>
2016-02-02 19:04:33 +00:00
Adam Langley dd31c4eba2 Update some comments in bn_test.c in light of acb24518.
Change acb24518 renamed some functions, but there were some dangling
references in bn_test.c. Thanks to Brian Smith for noticing.

This change has no semantic effect.

Change-Id: Id149505090566583834be3abce2cee28b8c248e2
Reviewed-on: https://boringssl-review.googlesource.com/7040
Reviewed-by: David Benjamin <davidben@google.com>
2016-02-02 18:22:19 +00:00
David Benjamin 47ebec1210 Validate DH public keys for RFC 5114 groups.
This is CVE-2016-0701 for OpenSSL, reported by Antonio Sanso. It is a no-op for
us as we'd long removed SSL_OP_DH_SINGLE_USE and static DH cipher suites. (We
also do not parse or generate X9.42 DH parameters.)

However, we do still have the APIs which return RFC 5114 groups, so we should
perform the necessary checks in case later consumers reuse keys.

Unlike groups we generate, RFC 5114 groups do not use "safe primes" and have
many small subgroups. In those cases, the subprime q is available. Before using
a public key, ensure its order is q by checking y^q = 1 (mod p). (q is assumed
to be prime and the existing range checks ensure y is not 1.)

(Imported from upstream's 878e2c5b13010329c203f309ed0c8f2113f85648 and
75374adf8a6ff69d6718952121875a491ed2cd29, but with some bugs fixed. See
RT4278.)

Change-Id: Ib18c3e84819002fa36a127ac12ca00ee33ea018a
Reviewed-on: https://boringssl-review.googlesource.com/7001
Reviewed-by: Adam Langley <agl@google.com>
2016-02-02 16:44:38 +00:00
David Benjamin 43946d44ae Update references to the extended master secret draft.
It's now an RFC too.

Change-Id: I2aa7a862bf51ff01215455e87b16f259fc468490
Reviewed-on: https://boringssl-review.googlesource.com/7028
Reviewed-by: Adam Langley <agl@google.com>
2016-02-02 16:37:55 +00:00
David Benjamin 4e3d17a7e7 Remove redundant logic to compute EC public key.
d2i_ECPrivateKey already computes it as of
9f5a314d35.

Change-Id: Ie48b2319ee7d96d09c8e4f13d99de38bfa89be76
Reviewed-on: https://boringssl-review.googlesource.com/6857
Reviewed-by: Adam Langley <agl@google.com>
2016-02-02 16:23:05 +00:00
David Benjamin 4aafe6a3af Document the d2i object reuse changes in PORTING.md.
Change-Id: I1875c5246c7da19af13683ca36c737c188a97d18
Reviewed-on: https://boringssl-review.googlesource.com/6984
Reviewed-by: Adam Langley <agl@google.com>
2016-02-02 16:21:20 +00:00
William Hesse bf3335c621 Add #ifdef guards to crypto/curve25519 assembly files.
Add guards for the architecture and OPENSSL_NO_ASM to
the assembly-language files in crypto/curve25519/asm.
The Dart compilation of BoringSSL includes all files,
because the architecture is not known when gyp is run.

Change-Id: I66f5ae525266b63b0fe3a929012b771d545779b5
Reviewed-on: https://boringssl-review.googlesource.com/7030
Reviewed-by: Adam Langley <agl@google.com>
2016-02-02 16:03:33 +00:00
David Benjamin 72f7e21087 Stop allowing SHA-224 in TLS 1.2.
Take the mappings for MD5 and SHA-224 values out of the code altogether. This
aligns with the current TLS 1.3 draft.

For MD5, this is a no-op. It is not currently possible to configure accepted
signature algorithms, MD5 wasn't in the hardcoded list, and we already had a
test ensuring we enforced our preferences correctly. MD5 also wasn't in the
default list of hashes our keys could sign and no one overrides it with a
different hash.

For SHA-224, this is not quite a no-op. The hardcoded accepted signature
algorithms list included SHA-224, so this will break servers relying on that.
However, Chrome's metrics have zero data points of servers picking SHA-224 and
no other major browser includes it. Thus that should be safe.

SHA-224 was also in the default list of hashes we are willing to sign. For
client certificates, Chromium's abstractions already did not allow signing
SHA-224, so this is a no-op there. For servers, this will break any clients
which only accept SHA-224. But no major browsers do this and I am not aware of
any client implementation which does such ridiculous thing.

(SHA-1's still in there. Getting rid of that one is going to take more effort.)

Change-Id: I6a765fdeea9e19348e409d58a0eac770b318e599
Reviewed-on: https://boringssl-review.googlesource.com/7020
Reviewed-by: Adam Langley <agl@google.com>
2016-01-29 21:30:00 +00:00
Brian Smith 5fa8f5bc9a Fix |-Werror=old-style-declaration| violations in poly1305_vec.c.
The |inline| must appear before the type.

Change-Id: Iecebbcc50024a846d7804228a858acfc33d68efd
Reviewed-on: https://boringssl-review.googlesource.com/7010
Reviewed-by: David Benjamin <davidben@google.com>
2016-01-28 23:58:45 +00:00
David Benjamin 2cdf398773 Remove pkey_base_id.
This is never accessed.

Change-Id: I4cade5e907ad4c03e9de7634b53ef965f7240087
Reviewed-on: https://boringssl-review.googlesource.com/6864
Reviewed-by: Adam Langley <agl@google.com>
2016-01-28 15:55:24 +00:00
David Benjamin 415564fe2c Update draft-irtf-cfrg-curves-11 references to RFC 7748.
Change-Id: I6148df93a1748754ee6be9e2b98cc8afd38746cb
Reviewed-on: https://boringssl-review.googlesource.com/6960
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-28 00:53:26 +00:00
David Benjamin 4f6acaf0da Use more C++11 features.
Finally, we can stick ScopedFOO in containers.

Change-Id: I3ed166575822af9f182e8be8f4db723e1f08ea31
Reviewed-on: https://boringssl-review.googlesource.com/6553
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-28 00:52:37 +00:00
David Benjamin c3774c1187 Fix some indentation.
Change-Id: I3507be754b489a99a04c0dea888cb1f3652e68c3
Reviewed-on: https://boringssl-review.googlesource.com/6854
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-28 00:51:45 +00:00
David Benjamin 0a2c9938a5 Don't allow the specifiedCurve form of ECParameters in SPKIs.
Although RFC 3279 allows both, per RFC 5912, keys must use a named curve
rather than spelling out the curve parameters. Although we do not allow
arbitrary curves, we do have to (pretty hackishly) recognize built-in
curves in ECPrivateKeys.

It seems the cause of this was that OpenSSL, unless you set asn1_flag on
the EC_GROUP, likes to encode keys by spelling out the parameters. This
is in violation of RFC 5915, though probably not in violation of one of
the other redundant ECC specifications. For more fun, it appears
asn1_flag defaults to *off* in the API and *on* in the command-line
tools.

I think the original cause was these defaults meant the pre-BoringSSL
Android/OpenSSL Chromium port wrote out Channel ID keys in this format.
By now this should no longer by an issue, but it'll warrant a bit more
investigation to be sure we can drop it.

For now, keep this logic out of SPKIs by not calling d2i_ECParameters.
d2i_ECParameters is a fairly pointless function when only named curves
are allowed. In testing other implementations, none of Firefox, Safari,
or IE11/Win will parse such certificates (i.e. the error is fatal and
unbypassable). Likewise, because Mac and Windows' underlying libraries
reject this, Chrome on Mac and Windows already rejects such things. Thus
this change should be compatible.

The following is the certificate and key I constructed to test with:

-----BEGIN CERTIFICATE-----
MIICwjCCAmqgAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC
QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp
dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ
BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l
dCBXaWRnaXRzIFB0eSBMdGQwggFLMIIBAwYHKoZIzj0CATCB9wIBATAsBgcqhkjO
PQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAA
AAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQaw
zFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEQQRrF9Hy4SxCR/i8
5uVjpEDydwN9gS3rM6D0oTlF2JjClk/jQuL+Gn+bjufrSnwPnhYrzjNXazFezsu2
QGg3v1H1AiEA/////wAAAAD//////////7zm+q2nF56E87nKwvxjJVECAQEDQgAE
5itp4r9ln5e+Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY+cPEox5W4nyD
SNsWGhz1HX7xlC1Lz3IiwaNQME4wHQYDVR0OBBYEFKuE0qyrlfCCThZ4B1VXX+Qm
jYLRMB8GA1UdIwQYMBaAFKuE0qyrlfCCThZ4B1VXX+QmjYLRMAwGA1UdEwQFMAMB
Af8wCQYHKoZIzj0EAQNHADBEAiBATB6aVJxDD6YAxEM4vf6Sbg2Ty334ldXpkNwc
TF+SngIgZ/f59kgDLf6YA04iLw1fUv5Wf1nLYJWwgrRFON5+zvw=
-----END CERTIFICATE-----
-----BEGIN EC PARAMETERS-----
MIH3AgEBMCwGByqGSM49AQECIQD/////AAAAAQAAAAAAAAAAAAAAAP//////////
/////zBbBCD/////AAAAAQAAAAAAAAAAAAAAAP///////////////AQgWsY12Ko6
k+ez671VdpiGvGUdBrDMU7D2O848PifSYEsDFQDEnTYIhucEk2pmeOETnSa3gZ9+
kARBBGsX0fLhLEJH+Lzm5WOkQPJ3A32BLeszoPShOUXYmMKWT+NC4v4af5uO5+tK
fA+eFivOM1drMV7Oy7ZAaDe/UfUCIQD/////AAAAAP//////////vOb6racXnoTz
ucrC/GMlUQIBAQ==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIAcPCHJ61KBKnN1ZyU2JaHcItW/JXTB3DujRyc4Ki7RqoAoGCCqGSM49
AwEHoUQDQgAE5itp4r9ln5e+Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY
+cPEox5W4nyDSNsWGhz1HX7xlC1Lz3IiwQ==
-----END EC PRIVATE KEY-----

BUG=522228

Change-Id: I3723411a633dc07c4640027de07500293f8f7913
Reviewed-on: https://boringssl-review.googlesource.com/6853
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-28 00:51:14 +00:00
David Benjamin f6094e05ef Don't allow EVP_PKEY_RSA2.
OpenSSL accepts both OID 2.5.8.1.1 and OID 1.2.840.113549.1.1.1 for RSA
public keys. The latter comes from RFC 3279 and is widely implemented.
The former comes from the ITU-T version of X.509. Interestingly,
2.5.8.1.1 actually has a parameter, which OpenSSL ignores:

  rsa ALGORITHM ::= {
     KeySize
     IDENTIFIED BY id-ea-rsa
  }
  KeySize ::= INTEGER

Remove support for 2.5.8.1.1 completely. In tests with a self-signed
certificate and code inspection:

- IE11 on Win8 does not accept the certificate in a TLS handshake at
  all. Such a certificate is fatal and unbypassable. However Microsoft's
  libraries do seem to parse it, so Chrome on Windows allows one to
  click through the error. I'm guessing either the X.509 stack accepts
  it while the TLS stack doesn't recognize it as RSA or the X.509 stack
  is able to lightly parse it but not actually understand the key. (The
  system certificate UI didn't display it as an RSA key, so probably the
  latter?)

- Apple's certificate library on 10.11.2 does not parse the certificate
  at all. Both Safari and Chrome on Mac treat it as a fatal and
  unbypassable error.

- mozilla::pkix, from code inspection, does not accept such
  certificates. However, Firefox does allow clicking through the error.
  This is likely a consequence of mozilla::pkix and NSS having different
  ASN.1 stacks. I did not test this, but I expect this means Chrome on
  Linux also accepts it.

Given IE and Safari's results, it should be safe to simply remove this.
Firefox's data point is weak (perhaps someone is relying on being able
to click-through a self-signed 2.5.8.1.1 certificate), but it does
further ensure no valid certificate could be doing this.

The following is the 2.5.8.1.1 certificate I constructed to test with.
The private key is key.pem from ssl/test/runner:

-----BEGIN CERTIFICATE-----
MIICVTCCAb6gAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGcMAoGBFUIAQECAgQAA4GNADCBiQKBgQDY
K8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLciHnAj
kXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfVW28t
Q+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNVHQ4E
FgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4fZbf6
Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQAIZuUICtYv
w3cbpCGX6HNCtyI0guOfbytcdwzRkQaCsYNSDrTxrSSWxHwqg3Dl/RlvS+T3Yaua
Xkioadstwt7GDP6MwpIpdbjchh0XZd3kjdJWqXSvihUDpRePNjNS2LmJW8GWfB3c
F6UVyNK+wcApRY+goREIhyYupAHUexR7FQ==
-----END CERTIFICATE-----

BUG=522228

Change-Id: I031d03c0f53a16cbc749c4a5d8be6efca50dc863
Reviewed-on: https://boringssl-review.googlesource.com/6852
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-28 00:43:37 +00:00
David Benjamin c612e61e1d Fix minor stylistic problem.
Normally this would be pretty scary:
  if (...) {
  } if (...) {
  }
But it's an early return anyway.

Change-Id: I0a8965b5e294d3aaa803be47f4006ea0311c431d
Reviewed-on: https://boringssl-review.googlesource.com/6851
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-28 00:35:35 +00:00
David Benjamin 719594e512 Un-const EVP_PKEY_CTX_set0_rsa_oaep_label and fix overflow check.
It takes ownership of the buffer, so it's not actually const. The
const-ness gets dropped once it transits through EVP_PKEY_CTX_ctrl.

Also compare against INT_MAX explicitly for the overflow check. I'm not sure
whether the casting version is undefined, but comparing against INT_MAX matches
the rest of the codebase when transiting in and out of signed ints.

Change-Id: I131165a4b5f0ebe02c6db3e7e3e0d1af5b771710
Reviewed-on: https://boringssl-review.googlesource.com/6850
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-28 00:34:38 +00:00
David Benjamin b6155e60f3 Remove app_data from EVP_PKEY_CTX.
It's never used. It's not clear why one would want such a thing.
EVP_PKEY_CTX has no way for callers to register callbacks, which means
there shouldn't be a way for the library to present you an EVP_PKEY_CTX
out-of-context. (Whereas app_data/ex_data makes sense on SSL because of
its numerous callbacks or RSA because of RSA_METHOD.)

Change-Id: I55af537ab101682677af34f6ac1f2c27b5899a89
Reviewed-on: https://boringssl-review.googlesource.com/6849
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-28 00:29:34 +00:00
David Benjamin 4e98e5c903 Implement pkey_ec_keygen with EC_KEY APIs.
This removes the last caller of EVP_PKEY_copy_parameters within the
library.

Change-Id: I6af138d364973b18f52baf55c36c50a24a56bd44
Reviewed-on: https://boringssl-review.googlesource.com/6848
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-28 00:28:43 +00:00
David Benjamin 692878a5f4 Remove EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID.
This is never exposed.

Change-Id: I332bc45f724eb42d68a0839e72b21593d01005ee
Reviewed-on: https://boringssl-review.googlesource.com/6847
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-28 00:27:42 +00:00
David Benjamin 8ac35f0274 Remove unused EVP_PKEY_METHOD hooks.
foo_init hooks are never implemented. Even upstream never uses them. The
flags member is also never used. We also don't expose paramgen, so
remove it.

Change-Id: I51d9439316c5163520ab7168693c457f33e59417
Reviewed-on: https://boringssl-review.googlesource.com/6846
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-28 00:23:46 +00:00
David Benjamin 9bf1b1b440 Remove group_clear_finish EC_GROUP hooks.
These are never called. Group parameters are not secret anyway. This is
a remnant of upstream's EC_GROUP_clear_free.

Change-Id: I23a4076eae8e4561abddbe74d0ba72641532f229
Reviewed-on: https://boringssl-review.googlesource.com/6823
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-28 00:17:43 +00:00
David Benjamin acb2451807 Rename the BIGNUM ASN.1 functions.
There's many ways to serialize a BIGNUM, so not including asn1 in the name is
confusing (and collides with BN_bn2cbb_padded). Since BN_asn12bn looks
ridiculous, match the parse/marshal naming scheme of other modules instead.

Change-Id: I53d22ae0537a98e223ed943e943c48cb0743cf51
Reviewed-on: https://boringssl-review.googlesource.com/6822
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-27 22:37:44 +00:00
David Benjamin 647cd02e59 Fix 32-bit build.
__uint128_t and friends don't exist in 32-bit. (Build fix for
https://boringssl-review.googlesource.com/#/c/6975/.)

Change-Id: I959a1f23c8cb3f11344f1da50cecd82d3080e3a0
Reviewed-on: https://boringssl-review.googlesource.com/6983
Reviewed-by: Adam Langley <agl@google.com>
2016-01-27 22:29:52 +00:00
David Benjamin b04c905da9 Remove the arch-specific HOST_c2l/HOST_l2c implementations.
These do not appear to have much discernable effect on performance. Three
comparison runs:

Before:
Did 5414000 SHA-1 (16 bytes) operations in 1000009us (5413951.3 ops/sec): 86.6 MB/s
Did 1607000 SHA-1 (256 bytes) operations in 1000403us (1606352.6 ops/sec): 411.2 MB/s
Did 70000 SHA-1 (8192 bytes) operations in 1014426us (69004.5 ops/sec): 565.3 MB/s
Did 2991000 SHA-256 (16 bytes) operations in 1000204us (2990390.0 ops/sec): 47.8 MB/s
Did 741000 SHA-256 (256 bytes) operations in 1000371us (740725.2 ops/sec): 189.6 MB/s
Did 31000 SHA-256 (8192 bytes) operations in 1019327us (30412.2 ops/sec): 249.1 MB/s
Did 2340000 SHA-512 (16 bytes) operations in 1000312us (2339270.1 ops/sec): 37.4 MB/s
Did 880000 SHA-512 (256 bytes) operations in 1000879us (879227.2 ops/sec): 225.1 MB/s
Did 44000 SHA-512 (8192 bytes) operations in 1013355us (43420.1 ops/sec): 355.7 MB/s
After:
Did 5259000 SHA-1 (16 bytes) operations in 1000013us (5258931.6 ops/sec): 84.1 MB/s
Did 1547000 SHA-1 (256 bytes) operations in 1000011us (1546983.0 ops/sec): 396.0 MB/s
Did 69000 SHA-1 (8192 bytes) operations in 1001089us (68924.9 ops/sec): 564.6 MB/s
Did 2984000 SHA-256 (16 bytes) operations in 1000207us (2983382.4 ops/sec): 47.7 MB/s
Did 734000 SHA-256 (256 bytes) operations in 1000317us (733767.4 ops/sec): 187.8 MB/s
Did 31000 SHA-256 (8192 bytes) operations in 1021065us (30360.5 ops/sec): 248.7 MB/s
Did 2324000 SHA-512 (16 bytes) operations in 1000116us (2323730.4 ops/sec): 37.2 MB/s
Did 828000 SHA-512 (256 bytes) operations in 1001046us (827134.8 ops/sec): 211.7 MB/s
Did 43000 SHA-512 (8192 bytes) operations in 1003381us (42855.1 ops/sec): 351.1 MB/s

---

Before:
Did 5415000 SHA-1 (16 bytes) operations in 1000055us (5414702.2 ops/sec): 86.6 MB/s
Did 1604000 SHA-1 (256 bytes) operations in 1000524us (1603159.9 ops/sec): 410.4 MB/s
Did 71000 SHA-1 (8192 bytes) operations in 1007686us (70458.5 ops/sec): 577.2 MB/s
Did 2984000 SHA-256 (16 bytes) operations in 1000472us (2982592.2 ops/sec): 47.7 MB/s
Did 738000 SHA-256 (256 bytes) operations in 1000885us (737347.4 ops/sec): 188.8 MB/s
Did 30000 SHA-256 (8192 bytes) operations in 1020475us (29398.1 ops/sec): 240.8 MB/s
Did 2297000 SHA-512 (16 bytes) operations in 1000391us (2296102.2 ops/sec): 36.7 MB/s
Did 882000 SHA-512 (256 bytes) operations in 1000389us (881657.0 ops/sec): 225.7 MB/s
Did 43000 SHA-512 (8192 bytes) operations in 1001313us (42943.6 ops/sec): 351.8 MB/s
After:
Did 5228000 SHA-1 (16 bytes) operations in 1000035us (5227817.0 ops/sec): 83.6 MB/s
Did 1575000 SHA-1 (256 bytes) operations in 1000410us (1574354.5 ops/sec): 403.0 MB/s
Did 69000 SHA-1 (8192 bytes) operations in 1004180us (68712.8 ops/sec): 562.9 MB/s
Did 2884000 SHA-256 (16 bytes) operations in 1000093us (2883731.8 ops/sec): 46.1 MB/s
Did 718000 SHA-256 (256 bytes) operations in 1000413us (717703.6 ops/sec): 183.7 MB/s
Did 31000 SHA-256 (8192 bytes) operations in 1030257us (30089.6 ops/sec): 246.5 MB/s
Did 2286000 SHA-512 (16 bytes) operations in 1000172us (2285606.9 ops/sec): 36.6 MB/s
Did 979000 SHA-512 (256 bytes) operations in 1000384us (978624.2 ops/sec): 250.5 MB/s
Did 47000 SHA-512 (8192 bytes) operations in 1017846us (46175.9 ops/sec): 378.3 MB/s

---

Before:
Did 5429000 SHA-1 (16 bytes) operations in 1000104us (5428435.4 ops/sec): 86.9 MB/s
Did 1604000 SHA-1 (256 bytes) operations in 1000473us (1603241.7 ops/sec): 410.4 MB/s
Did 69000 SHA-1 (8192 bytes) operations in 1002621us (68819.6 ops/sec): 563.8 MB/s
Did 3021000 SHA-256 (16 bytes) operations in 1000152us (3020540.9 ops/sec): 48.3 MB/s
Did 735000 SHA-256 (256 bytes) operations in 1000048us (734964.7 ops/sec): 188.2 MB/s
Did 31000 SHA-256 (8192 bytes) operations in 1019902us (30395.1 ops/sec): 249.0 MB/s
Did 2301000 SHA-512 (16 bytes) operations in 1000207us (2300523.8 ops/sec): 36.8 MB/s
Did 881000 SHA-512 (256 bytes) operations in 1001122us (880012.6 ops/sec): 225.3 MB/s
Did 44000 SHA-512 (8192 bytes) operations in 1015313us (43336.4 ops/sec): 355.0 MB/s
After:
Did 5264000 SHA-1 (16 bytes) operations in 1000061us (5263678.9 ops/sec): 84.2 MB/s
Did 1587000 SHA-1 (256 bytes) operations in 1000293us (1586535.1 ops/sec): 406.2 MB/s
Did 71000 SHA-1 (8192 bytes) operations in 1007587us (70465.4 ops/sec): 577.3 MB/s
Did 2967000 SHA-256 (16 bytes) operations in 1000240us (2966288.1 ops/sec): 47.5 MB/s
Did 737000 SHA-256 (256 bytes) operations in 1000874us (736356.4 ops/sec): 188.5 MB/s
Did 31000 SHA-256 (8192 bytes) operations in 1019630us (30403.2 ops/sec): 249.1 MB/s
Did 2326000 SHA-512 (16 bytes) operations in 1000413us (2325039.8 ops/sec): 37.2 MB/s
Did 885000 SHA-512 (256 bytes) operations in 1000253us (884776.2 ops/sec): 226.5 MB/s
Did 44000 SHA-512 (8192 bytes) operations in 1013216us (43426.1 ops/sec): 355.7 MB/s

Change-Id: Ifd4500f4e9f41ffc0f73542141e8888b4d7f1e0b
Reviewed-on: https://boringssl-review.googlesource.com/6652
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-27 22:26:32 +00:00
David Benjamin 8f2d4e344c Fix documentation string.
SSL_CTX_set_retain_only_sha256_of_client_certs's comment wasn't quite right.

Change-Id: I40527eebf2988d117cd8bd544bb5f16936c2cbfb
Reviewed-on: https://boringssl-review.googlesource.com/6982
Reviewed-by: Adam Langley <agl@google.com>
2016-01-27 22:20:32 +00:00
Brian Smith 87c7640773 Use |inline| in crypto/poly1305/poly1305_vec.c.
The code was using `#define INLINE` instead, but we have `inline` so
use it.

Change-Id: Id05eaec4720061c5d9a7278e20127c2bebcb2495
Reviewed-on: https://boringssl-review.googlesource.com/6976
Reviewed-by: David Benjamin <davidben@google.com>
2016-01-27 22:15:34 +00:00
Brian Smith 24e428899b Define int128_t and uint128_t in one place.
Change-Id: Ia93130aadf319eaba1b6f2ec2896a4c50d9e8ede
Reviewed-on: https://boringssl-review.googlesource.com/6975
Reviewed-by: David Benjamin <davidben@google.com>
2016-01-27 22:15:04 +00:00
Brian Smith f547007332 Use |alignas| more in crypto/chacha/chacha_vec.c.
Commit 75a64c08fc missed one case where
the GCC syntax should have been replaced with |alignas|.

Change-Id: Iebdaa9c9a2c0aff171f0b5d4daac607e351a4b7e
Reviewed-on: https://boringssl-review.googlesource.com/6974
Reviewed-by: David Benjamin <davidben@google.com>
2016-01-27 22:12:22 +00:00
Brian Smith 9333d6df11 Fix data <-> function pointer casts in thread_win.c.
The uses of |memcpy| to cast pointer-to-function to pointer-to-data and
back again did not have well-defined semantics. Use a union instead to
avoid the need for such a conversion get well-defined semantics.

Change-Id: I8ee54a83ba75440f7bc78c194eb55e2cf09b05d8
Reviewed-on: https://boringssl-review.googlesource.com/6972
Reviewed-by: David Benjamin <davidben@google.com>
2016-01-27 22:08:26 +00:00
Brian Smith f5f4be8fac Fix pointer-to-non-volatile cast in thread_win.c.
Casting a pointer-to-non-volatile to pointer-to-volatile can be a no-op
as the compiler only requires volatile semantics when the pointed-to
object is a volatile object and there are no pointers-to-non-volatile
involved. This probably doesn't matter unless building with the MSVC
-volatile:iso flag, and maybe not even then, but it is good practice
anyway.

Change-Id: I94900d3dc61de3b8ce2ddecab2811907a9a7adbf
Reviewed-on: https://boringssl-review.googlesource.com/6973
Reviewed-by: David Benjamin <davidben@google.com>
2016-01-27 22:06:11 +00:00
Adam Langley 54a8d7c14f Use Barrett reduction in CBC processing rather than tricks.
Division isn't constant-time on Intel chips so the code was adding a
large multiple of md_size to try and force the operation to always take
the maximum amount of time.

I'm less convinced, these days, that compilers aren't going to get smart
enough to optimise that away so use Barrett reduction instead.

Change-Id: Ib8c514192682a2fcb4b1fb7e7c6dd1301d9888d0
Reviewed-on: https://boringssl-review.googlesource.com/6906
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-27 22:05:01 +00:00
David Benjamin 91b2501f02 Add functions for accessing read_sequence and write_sequence.
OpenSSL 1.1.0 doesn't seem to have these two, so this isn't based on anything.
Have them return uint64_t in preparation for switching the internal
representation to uint64_t so ssl_record_sequence_update can go away.

Change-Id: I21d55e9a29861c992f409ed293e0930a7aaef7a3
Reviewed-on: https://boringssl-review.googlesource.com/6941
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-27 22:03:57 +00:00
David Benjamin cdd0b7e775 Add SSL_CTX_set_retain_only_sha256_of_client_certs.
We have the hook on the SSL_CTX, but it should be possible to set it without
reaching into SSL_CTX.

Change-Id: I93db070c7c944be374543442a8de3ce655a28928
Reviewed-on: https://boringssl-review.googlesource.com/6880
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-27 22:02:53 +00:00
David Benjamin 4b9205b583 Align SSL_CTX_set1_tls_channel_id with SSL_set1_tls_channel_id.
They should use the same P-256 check.

Change-Id: I66dd63663e638cba35b8f70f9cf119c718af4aec
Reviewed-on: https://boringssl-review.googlesource.com/6845
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-27 21:51:39 +00:00
David Benjamin b83003ebc6 Don't initialize enc_method before version negotiation.
Move it into ssl->s3 so it automatically behaves correctly on SSL_clear.
ssl->version is still a mess though.

Change-Id: I17a692a04a845886ec4f8de229fa6cf99fa7e24a
Reviewed-on: https://boringssl-review.googlesource.com/6844
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-27 21:38:12 +00:00
David Benjamin a565d29ce6 Remove alert mapping machinery.
For TLS, this machinery only exists to swallow no_certificate alerts
which only get sent in an SSL 3.0 codepath anyway. It's much less a
no-op for SSL 3.0 which, strictly speaking, has only a subset of TLS's
alerts.

This gets messy around version negotiation because of the complex
relationship between enc_method, have_version, and version which all get
set at different times. Given that SSL 3.0 is nearly dead and all these
alerts are fatal to the connection anyway, this doesn't seem worth
carrying around. (It doesn't work very well anyway. An SSLv3-only server
may still send a record_overflow alert before version negotiation.)

This removes the last place enc_method is accessed prior to version
negotiation.

Change-Id: I79a704259fca69e4df76bd5a6846c9373f46f5a9
Reviewed-on: https://boringssl-review.googlesource.com/6843
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-27 21:28:48 +00:00
David Benjamin a1e9cabd8b Replace enc_flags with normalized version checks.
This removes the various non-PRF checks from SSL3_ENC_METHOD so that can
have a clearer purpose. It also makes TLS 1.0 through 1.2's
SSL3_ENC_METHOD tables identical and gives us an assert to ensure
nothing accesses the version bits before version negotiation.
Accordingly, ssl_needs_record_splitting was reordered slightly so we
don't rely on enc_method being initialized to TLS 1.2
pre-version-negotiation.

This leaves alert_value as the only part of SSL3_ENC_METHOD which may be
accessed before version negotiation.

Change-Id: If9e299e2ef5511b5fa442b2af654eed054c3e675
Reviewed-on: https://boringssl-review.googlesource.com/6842
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-27 21:17:55 +00:00
Adam Langley ef7dba6ac7 Fix error in ce9d85ee.
I used a size_t out of habit, but |RSA_public_decrypt| is an old-style
function.

Change-Id: Ibd94d03743fe0099d61578ec15c19fa5333127db
2016-01-26 15:31:23 -08:00
Adam Langley ce9d85eedd Tweaks for node.js
node.js is, effectively, another bindings library. However, it's better
written than most and, with these changes, only a couple of tiny fixes
are needed in node.js. Some of these changes are a little depressing
however so we'll need to push node.js to use APIs where possible.

Changes:
  ∙ Support verify_recover. This is very obscure and the motivation
    appears to be https://github.com/nodejs/node/issues/477 – where it's
    not clear that anyone understands what it means :(
  ∙ Add a few, no-op #defines
  ∙ Add some members to |SSL_CTX| and |SSL| – node.js needs to not
    reach into these structs in the future.
  ∙ Add EC_get_builtin_curves.
  ∙ Add EVP_[CIPHER|MD]_do_all_sorted – these functions are limited to
    decrepit.

Change-Id: I9a3566054260d6c4db9d430beb7c46cc970a9d46
Reviewed-on: https://boringssl-review.googlesource.com/6952
Reviewed-by: Adam Langley <agl@google.com>
2016-01-26 23:23:42 +00:00
Adam Langley eac0ce09d8 Have doc.go parse struct comments.
In code, structs that happened to have a '(' somewhere in their body
would cause the parser to go wrong. This change fixes that and updates
the comments on a number of structs.

Change-Id: Ia76ead266615a3d5875b64a0857a0177fec2bd00
Reviewed-on: https://boringssl-review.googlesource.com/6970
Reviewed-by: Adam Langley <agl@google.com>
2016-01-26 23:23:23 +00:00
David Benjamin 241ae837f0 Add some tests to ensure we ignore bogus curves and ciphers.
We haven't had problems with this, but make sure it stays that way.
Bogus signature algorithms are already covered.

Change-Id: I085350d89d79741dba3f30fc7c9f92de16bf242a
Reviewed-on: https://boringssl-review.googlesource.com/6910
Reviewed-by: David Benjamin <davidben@google.com>
2016-01-26 21:51:55 +00:00
David Benjamin f6494f4928 Add a SSL_get_pending_cipher API.
Conscrypt needs to, in the certificate verification callback, know the key
exchange + auth method of the current cipher suite to pass into
X509TrustManager.checkServerTrusted. Currently it reaches into the struct to
get it. Add an API for this.

Change-Id: Ib4e0a1fbf1d9ea24e0114f760b7524e1f7bafe33
Reviewed-on: https://boringssl-review.googlesource.com/6881
Reviewed-by: David Benjamin <davidben@google.com>
2016-01-26 21:51:02 +00:00
David Benjamin 7027d25c6b Also add a no-op stub for OPENSSL_config.
Apparently OpenSSL's API is made entirely of initialization functions.
Some external libraries like to initialize with OPENSSL_config instead.

Change-Id: I28efe97fc5eb21309f560c84112b80e947f8bb17
Reviewed-on: https://boringssl-review.googlesource.com/6981
Reviewed-by: Adam Langley <agl@google.com>
2016-01-26 15:48:51 +00:00
David Benjamin e5aa791a1c Add a few more no-op stubs for cURL compatibility.
With these stubs, cURL should not need any BoringSSL #ifdefs at all,
except for their OCSP #ifdefs (which can switch to the more generally
useful OPENSSL_NO_OCSP) and the workaround for wincrypt.h macro
collisions. That we intentionally leave to the consumer rather than add
a partial hack that makes the build sensitive to include order.

(I'll send them a patch upstream once this cycles in.)

Change-Id: I815fe67e51e80e9aafa9b91ae68867ca1ff1d623
Reviewed-on: https://boringssl-review.googlesource.com/6980
Reviewed-by: Adam Langley <agl@google.com>
2016-01-26 15:48:41 +00:00
David Benjamin 5aae776ede Remove calls to ERR_load_crypto_strings.
Since the error string logic was rewritten, this hasn't done anything.

Change-Id: Icb73dca65e852bb3c7d04c260d591906ec72c15f
Reviewed-on: https://boringssl-review.googlesource.com/6961
Reviewed-by: Adam Langley <agl@google.com>
2016-01-25 23:09:08 +00:00
Adam Langley 75a64c08fc Remove some mingw support cruft.
This was needed for Android, but “the new version of mingw has moved all
of time_s.h into time.h” [1].

[1] https://android-review.googlesource.com/#/c/196597/

Change-Id: I17e66ed93606f3e6a774af3290c15b5ca151449f
Reviewed-on: https://boringssl-review.googlesource.com/6971
Reviewed-by: David Benjamin <davidben@google.com>
2016-01-25 23:05:45 +00:00
Brian Smith 7cae9f5b6c Use |alignas| for alignment.
MSVC doesn't have stdalign.h and so doesn't support |alignas| in C
code. Define |alignas(x)| as a synonym for |__decltype(align(x))|
instead for it.

This also fixes -Wcast-qual warnings in rsaz_exp.c.

Change-Id: Ifce9031724cb93f5a4aa1f567e7af61b272df9d5
Reviewed-on: https://boringssl-review.googlesource.com/6924
Reviewed-by: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-01-25 23:05:04 +00:00
Brian Smith 34749f47da Remove unnecessary assignment of |e| in |rsa_setup_blinding|.
After its initial assignment, |e| is immediately reassigned another
value and so the initial assignment from |BN_CTX_get| is useless. If
that were not the case, then the |BN_free(e)| at the end of the
function would be very bad.

Change-Id: Id63a172073501c8ac157db9188a22f55ee36b205
Reviewed-on: https://boringssl-review.googlesource.com/6951
Reviewed-by: David Benjamin <davidben@google.com>
2016-01-23 17:08:23 +00:00
David Benjamin 232127d245 Fold EC_GROUP_new_curve_GFp and EC_GROUP_set_generator into a EC_GROUP_new_arbitrary.
This is only for Conscrypt which always calls the pair in succession. (Indeed
it wouldn't make any sense to not call it.) Remove those two APIs and replace
with a single merged API. This way incomplete EC_GROUPs never escape outside
our API boundary and EC_GROUPs may *finally* be made immutable.

Also add a test for this to make sure I didn't mess it up.

Add a temporary BORINGSSL_201512 define to ease the transition for Conscrypt.
Conscrypt requires https://android-review.googlesource.com/#/c/187801/ before
picking up this change.

Change-Id: I3706c2ceac31ed2313175ba5ee724bd5c74ef6e1
Reviewed-on: https://boringssl-review.googlesource.com/6550
Reviewed-by: Adam Langley <agl@google.com>
2016-01-21 22:35:46 +00:00
David Benjamin 95219feafd Fix some documentation comments.
The new OPENSSL_PRINTF_FORMAT_FUNC macro let doc.go catch a few problems. It
also confuses doc.go, but this CL doesn't address that. At some point we
probably need to give it a real C parser.

Change-Id: I39f945df04520d1e0a0ba390cac7b308baae0622
Reviewed-on: https://boringssl-review.googlesource.com/6940
Reviewed-by: Adam Langley <agl@google.com>
2016-01-21 22:12:08 +00:00
Brian Smith d3a4e280db Fix trivial -Wcast-qual violations.
Fix casts from const to non-const where dropping the constness is
completely unnecessary. The changes to chacha_vec.c don't result in any
changes to chacha_vec_arm.S.

Change-Id: I2f10081fd0e73ff5db746347c5971f263a5221a6
Reviewed-on: https://boringssl-review.googlesource.com/6923
Reviewed-by: David Benjamin <davidben@google.com>
2016-01-21 21:06:02 +00:00
Brian Smith a646258c14 Enable stronger format string checking |-Wformat=2|.
Also, factor out flags based to both the C and C++ compiler into a
single variable.

Change-Id: I432de0cc516e95a0d48146fae2dda8b7b3b38d4b
Reviewed-on: https://boringssl-review.googlesource.com/6922
Reviewed-by: David Benjamin <davidben@google.com>
2016-01-21 21:00:31 +00:00
Brian Smith d92f1d39a8 Fix |sscanf| format string in cpu-intel.c.
Fix the signness of the format flag in the |sscanf| call in cpu-intel.c.

Change-Id: I31251d79aa146bf9c78be47020ee83d30864a3d2
Reviewed-on: https://boringssl-review.googlesource.com/6921
Reviewed-by: David Benjamin <davidben@google.com>
2016-01-21 20:59:35 +00:00
Brian Smith 8d3c43e4b1 Annotate |ERR_add_error_dataf| as |OPENSSL_PRINTF_FORMAT_FUNC|.
Besides being a good idea anyway, this avoids clang warning about using
a non-literal format string when |ERR_add_error_dataf| calls
|BIO_vsnprintf|.

Change-Id: Iebc84d9c9d85e08e93010267d473387b661717a5
Reviewed-on: https://boringssl-review.googlesource.com/6920
Reviewed-by: David Benjamin <davidben@google.com>
2016-01-21 20:59:18 +00:00
Brian Smith 061332f216 Define |OPENSSL_PRINTF_FORMAT_FUNC| for format string annotations.
This centralizes the conditional logic into openssl/base.h so that it
doesn't have to be repeated. The name |OPENSSL_PRINTF_FORMAT_FUNC| was
chosen in anticipation of eventually defining an
|OPENSSL_PRINTF_FORMAT_ARG| for MSVC-style parameter annotations.

Change-Id: I273e6eddd209e696dc9f82099008c35b6d477cdb
Reviewed-on: https://boringssl-review.googlesource.com/6909
Reviewed-by: David Benjamin <davidben@google.com>
2016-01-21 20:58:51 +00:00
Brian Smith 0687bdfc12 Fix -Wformat-nonliteral violation in ssl_cipher.c.
Besides avoiding the -Wformat-nonliteral warning, it is easier to
review (changes to) the code when the format string is passed to the
function as a literal.

Change-Id: I5093ad4494d5ebeea3f2671509b916cd6c5fb173
Reviewed-on: https://boringssl-review.googlesource.com/6908
Reviewed-by: David Benjamin <davidben@google.com>
2016-01-21 20:56:59 +00:00
David Benjamin 6c22f542f4 Fix build of x509_test.
Some combination of Chromium's copy of clang and Chromium's Linux sysroot
doesn't like syntax. It complains that "chosen constructor is explicit in
copy-initialization".

Change-Id: Ied6bc17b19421998f926483742510c81f732566b
Reviewed-on: https://boringssl-review.googlesource.com/6930
Reviewed-by: Adam Langley <agl@google.com>
2016-01-20 23:08:03 +00:00
David Benjamin fc6e5a7372 Drop the silly 'ECDH_' prefix on X25519.
I got that from the TLS 1.3 draft, but it's kind of silly-looking. X25519
already refers to a Diffie-Hellman primitive.

Also hopefully the WG will split NamedGroups and SignatureAlgorithms per the
recent proposal, so it won't be needed anyway. (Most chatter is about what
hashes should be allowed with what NIST curves, so it seems like people like
the split itself? We'll see.)

Change-Id: I7bb713190001199a3ebd30b67df2c00d29132431
Reviewed-on: https://boringssl-review.googlesource.com/6912
Reviewed-by: Adam Langley <agl@google.com>
2016-01-20 17:26:13 +00:00
David Benjamin d2f0ce80a2 Enable X25519 by default in TLS.
BUG=571231

Change-Id: I73e39411ccdc817f172c7a94b7f70c448eed938f
Reviewed-on: https://boringssl-review.googlesource.com/6911
Reviewed-by: Adam Langley <agl@google.com>
2016-01-20 17:26:02 +00:00
Adam Langley 3a39b06011 Import “altchains” support.
This change imports the following changes from upstream:

6281abc79623419eae6a64768c478272d5d3a426
dfd3322d72a2d49f597b86dab6f37a8cf0f26dbf
f34b095fab1569d093b639bfcc9a77d6020148ff
21376d8ae310cf0455ca2b73c8e9f77cafeb28dd
25efcb44ac88ab34f60047e16a96c9462fad39c1
56353962e7da7e385c3d577581ccc3015ed6d1dc
39c76ceb2d3e51eaff95e04d6e4448f685718f8d
a3d74afcae435c549de8dbaa219fcb30491c1bfb

These contain the “altchains” functionality which allows OpenSSL to
backtrack when chain building.

Change-Id: I8d4bc2ac67b90091f9d46e7355cae878b4ccf37d
Reviewed-on: https://boringssl-review.googlesource.com/6905
Reviewed-by: Adam Langley <agl@google.com>
2016-01-19 17:02:31 +00:00
Adam Langley 57707c70dc OpenSSL reformat x509/, x509v3/, pem/ and asn1/.
OpenSSL upstream did a bulk reformat. We still have some files that have
the old OpenSSL style and this makes applying patches to them more
manual, and thus more error-prone, than it should be.

This change is the result of running
  util/openssl-format-source -v -c .
in the enumerated directories. A few files were in BoringSSL style and
have not been touched.

This change should be formatting only; no semantic difference.

Change-Id: I75ced2970ae22b9facb930a79798350a09c5111e
Reviewed-on: https://boringssl-review.googlesource.com/6904
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2016-01-19 17:01:51 +00:00
Adam Langley 62882187c9 Update comments to better document in-place semantics.
(Comment-only change; no functional difference.)

Some code was broken by the |d2i_ECDSA_SIG| change in 87897a8c. It was
passing in a pointer to an existing |ECDSA_SIG| as the first argument
and then simply assuming that the structure would be updated in place.
The comments on the function suggested that this was reasonable.

This change updates the comments that use similar wording to either note
that the function will never update in-place, or else to note that
depending on that is a bad idea for the future.

I've also audited all the uses of these functions that I can find and,
in addition to the one case with |d2i_ECDSA_SIG|, there are several
users of |d2i_PrivateKey| that could become a problem in the future.
I'll try to fix them before it does become an issue.

Change-Id: I769f7b2e0b5308d09ea07dd447e02fc161795071
Reviewed-on: https://boringssl-review.googlesource.com/6902
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2016-01-19 17:01:37 +00:00
David Benjamin b8ba65a73a Fix arm perlasm trailing newline.
Change-Id: I1119fd8d5a0e03832644cb4b8128eed8ed9acb9e
Reviewed-on: https://boringssl-review.googlesource.com/6890
Reviewed-by: Adam Langley <agl@google.com>
2016-01-19 16:35:20 +00:00
Matt Braithwaite 0b553eb531 Remove a trailing ^M (DOS newline).
Change-Id: Iacce453dc55847e0d35a7a25c5997a3a46bb4c9a
Reviewed-on: https://boringssl-review.googlesource.com/6907
Reviewed-by: Adam Langley <agl@google.com>
2016-01-16 04:08:14 +00:00
David Benjamin b9e4fa5e02 Add a helper function to normalize the current version.
We have need to normalize other versions during version negotiation, but
almost all will be post-negotiation. Hopefully later this can be
replaced with a value explicitly stored on the object and we do away
with ssl->version.

Change-Id: I595db9163d0af2e7c083b9a09310179aaa9ac812
Reviewed-on: https://boringssl-review.googlesource.com/6841
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-15 22:17:00 +00:00
David Benjamin 23b0a65df1 Move some functions to file scope.
The various SSL3_ENC_METHODs ought to be defined in the same file their
functions are defined in, so they can be static.

Change-Id: I34a1d3437e8e61d4d50f2be70312e4630ea89c19
Reviewed-on: https://boringssl-review.googlesource.com/6840
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-15 22:14:39 +00:00
David Benjamin 928f32a492 Add APIs to extract the SSL key block.
This is a companion to SSL_get_rc4_state and SSL_get_ivs which doesn't
require poking at internal state. Partly since it aligns with the
current code and partly the off chance we ever need to get
wpa_supplicant's EAP-FAST code working, the API allows one to generate
more key material than is actually in the key block.

Change-Id: I58bc3f2b017482dbb8567dcd0cd754947a95397f
Reviewed-on: https://boringssl-review.googlesource.com/6839
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-15 22:09:24 +00:00
David Benjamin baa1216ac0 Prune finished labels from SSL3_ENC_METHOD.
There's not much point in putting those in the interface as the
final_finished_mac implementation is itself different between SSL 3.0
and TLS.

Change-Id: I76528a88d255c451ae008f1a34e51c3cb57d3073
Reviewed-on: https://boringssl-review.googlesource.com/6838
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-15 22:04:53 +00:00
David Benjamin f8d807176a Remove a few unnecessary SSL3_ENC_METHOD hooks.
As things stand now, they don't actually do anything.

Change-Id: I9f8b4cbf38a0dffabfc5265805c52bb8d7a8fb0d
Reviewed-on: https://boringssl-review.googlesource.com/6837
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-15 22:02:30 +00:00
David Benjamin b35d68483c Minor cleanup.
Mostly alg_k and alg_a variables had the wrong type.

Change-Id: I66ad4046b1f5a4e3e58bc407096d95870b42b9dd
Reviewed-on: https://boringssl-review.googlesource.com/6836
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-15 22:01:28 +00:00
David Benjamin 79978df4ec Move aead_{read,write}_ctx and next_proto_negotiated into ssl->s3.
Both are connection state rather than configuration state. Notably this
cuts down more of SSL_clear that can't just use ssl_free + ssl_new.

Change-Id: I3c05b3ae86d4db8bd75f1cd21656f57fc5b55ca9
Reviewed-on: https://boringssl-review.googlesource.com/6835
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-15 21:40:25 +00:00
David Benjamin 57997da8ee Simplify the ChangeCipherSpec logic.
It's the same between TLS and SSL 3.0. There's also no need for the
do_change_cipher_spec wrapper (it no longer needs checks to ensure it
isn't called at a bad place). Finally fold the setup_key_block call into
change_cipher_spec.

Change-Id: I7917f48e1a322f5fbafcf1dfb8ad53f66565c314
Reviewed-on: https://boringssl-review.googlesource.com/6834
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-15 21:33:57 +00:00
David Benjamin 0623bceb25 Fill in ssl->session->cipher when resumption is resolved.
Doing it at ChangeCipherSpec makes it be set twice and, more
importantly, causes us to touch SSL_SESSION objects on resumption. (With
a no-op change, but this still isn't a good idea.)

This should actually let us get rid of ssl->s3->tmp.new_cipher but some
of external code accesses that field directly.

Change-Id: Ia6b7e0964c1b430f963ad0b1a5417b339b7b19d3
Reviewed-on: https://boringssl-review.googlesource.com/6833
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-15 20:46:45 +00:00
David Benjamin 4119d42e7c Tidy up keyblock and CCS logic slightly.
Move the actual SSL_AEAD_CTX swap into the record layer. Also revise the
intermediate state we store between setup_key_block and
change_cipher_state. With SSL_AEAD_CTX_new abstracted out, keeping the
EVP_AEAD around doesn't make much sense. Just store enough to partition
the key block.

Change-Id: I773fb46a2cb78fa570f00c0a89339c15bbb1d719
Reviewed-on: https://boringssl-review.googlesource.com/6832
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-15 20:40:44 +00:00
David Benjamin 1db2156ce8 Move ssl3_record_sequence_update with the other record-layer bits.
Change-Id: I045a4d3e304872b8c97231dcde5bca7753a878fb
Reviewed-on: https://boringssl-review.googlesource.com/6831
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-15 20:15:55 +00:00
David Benjamin 96ba15fc69 Add SSL_get_client_random and SSL_get_server_random.
wpa_supplicant needs to get at the client and server random. OpenSSL
1.1.0 added these APIs, so match their semantics.

Change-Id: I2b71ba850ac63e574c9ea79012d1d0efec5a979a
Reviewed-on: https://boringssl-review.googlesource.com/6830
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-15 20:15:29 +00:00
David Benjamin ef1b009344 Consider session if the client supports tickets but offered a session ID.
This is a minor regression from
https://boringssl-review.googlesource.com/5235.

If the client, for whatever reason, had an ID-based session but also
supports tickets, it will send non-empty ID + empty ticket extension.
If the ticket extension is non-empty, then the ID is not an ID but a
dummy signaling value, so 5235 avoided looking it up. But if it is
present and empty, the ID is still an ID and should be looked up.

This shouldn't have any practical consequences, except if a server
switched from not supporting tickets and then started supporting it,
while keeping the session cache fixed.

Add a test for this case, and tighten up existing ID vs ticket tests so
they fail if we resume with the wrong type.

Change-Id: Id4d08cd809af00af30a2b67fe3a971078e404c75
Reviewed-on: https://boringssl-review.googlesource.com/6554
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-15 20:08:52 +00:00
Adam Langley dd1f6f4fba Rename the curve25519 precomputed tables.
These symbols can show up in lists of large symbols but, so I
understand, these lists might not include the filename path. Thus |base|
as a symbol name is rather unhelpful.

This change renames the two precomputated tables to have slightly more
greppable names.

Change-Id: I77059250cfce4fa9eceb64e260b45db552b63255
Reviewed-on: https://boringssl-review.googlesource.com/6813
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <alangley@gmail.com>
2016-01-15 19:51:05 +00:00
Matt Braithwaite e021a245bf Add curve25519/asm/x25519-asm-x86_64.S.
Change-Id: I5feff96d8d80981e72a8b3aa3fd90e3202dff39e
Reviewed-on: https://boringssl-review.googlesource.com/6903
Reviewed-by: Adam Langley <agl@google.com>
2016-01-14 22:36:58 +00:00
Brian Smith 625475f3e3 Fix bits vs. bytes confusion in RSA encryption.
rsa_default_encrypt allowed an RSA modulus 8 times larger than the
intended maximum size due to bits vs. bytes confusion.

Further, as |rsa_default_encrypt| got this wrong while
|rsa_default_verify_raw| got it right, factor out the duplicated logic
so that such inconsistencies are less likely to occur.

BUG=576856

Change-Id: Ic842fadcbb3b140d2ba4295793457af2b62d9444
Reviewed-on: https://boringssl-review.googlesource.com/6900
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2016-01-13 22:28:54 +00:00
Adam Langley 7b8b9c17db Include 'asm' in the name of X25519 asm sources.
Some build systems don't like two targets with the same base name and
the curve25519 code had x25519-x86_64.[Sc].

Change-Id: If8382eb84996d7e75b34b28def57829d93019cff
Reviewed-on: https://boringssl-review.googlesource.com/6878
Reviewed-by: Adam Langley <agl@google.com>
2016-01-05 16:05:50 +00:00
Adam Langley 3202750a98 Update the fuzz tests for the server.
These seeds are the result of spending more CPU time fuzzing the server.

Change-Id: Iacf889ae6e214056033f4a5f9f3b89e4710c22a5
2015-12-22 16:35:07 -08:00
David Benjamin 6544426d82 Fix a ** 0 mod 1 = 0 for real this time.
Commit 2b0180c37fa6ffc48ee40caa831ca398b828e680 attempted to do this but
only hit one of many BN_mod_exp codepaths. Fix remaining variants and
add a test for each method.

Thanks to Hanno Boeck for reporting this issue.

(Imported from upstream's 44e4f5b04b43054571e278381662cebd3f3555e6.)

Change-Id: Ic691b354101c3e9c3565300836fb6d55c6f253ba
Reviewed-on: https://boringssl-review.googlesource.com/6820
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 23:30:22 +00:00
David Benjamin fe5f7c7b56 Only reserve EVP_MAX_MD_SIZE for the Finished, not twice of it.
EVP_MAX_MD_SIZE is large enough to fit a MD5/SHA1 concatenation, and
necessarily is because EVP_md5_sha1 exists. This shaves 128 bytes of
per-connection state.

Change-Id: I848a8563dfcbac14735bb7b302263a638528f98e
Reviewed-on: https://boringssl-review.googlesource.com/6804
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 23:29:21 +00:00
David Benjamin 0d56f888c3 Switch s to ssl everywhere.
That we're half and half is really confusing.

Change-Id: I1c2632682e8a3e63d01dada8e0eb3b735ff709ce
Reviewed-on: https://boringssl-review.googlesource.com/6785
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 23:28:22 +00:00
David Benjamin 974c7ba4ef Route DHE through the SSL_ECDH abstraction as well.
This unifies the ClientKeyExchange code rather nicely. ServerKeyExchange
is still pretty specialized. For simplicity, I've extended the yaSSL bug
workaround for clients as well as servers rather than route in a
boolean.

Chrome's already banished DHE to a fallback with intention to remove
altogether later, and the spec doesn't say anything useful about
ClientDiffieHellmanPublic encoding, so this is unlikely to cause
problems.

Change-Id: I0355cd1fd0fab5729e8812e4427dd689124f53a2
Reviewed-on: https://boringssl-review.googlesource.com/6784
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 23:17:32 +00:00
David Benjamin 4cc36adf5a Make it possible to tell what curve was used on the server.
We don't actually have an API to let you know if the value is legal to
interpret as a curve ID. (This was kind of a poor API. Oh well.) Also add tests
for key_exchange_info. I've intentionally left server-side plain RSA missing
for now because the SSL_PRIVATE_KEY_METHOD abstraction only gives you bytes and
it's probably better to tweak this API instead.

(key_exchange_info also wasn't populated on the server, though due to a
rebasing error, that fix ended up in the parent CL. Oh well.)

Change-Id: I74a322c8ad03f25b02059da7568c9e1a78419069
Reviewed-on: https://boringssl-review.googlesource.com/6783
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 23:12:25 +00:00
David Benjamin 4298d77379 Implement draft-ietf-tls-curve25519-01 in C.
The new curve is not enabled by default.

As EC_GROUP/EC_POINT is a bit too complex for X25519, this introduces an
SSL_ECDH_METHOD abstraction which wraps just the raw ECDH operation. It
also tidies up some of the curve code which kept converting back and
force between NIDs and curve IDs. Now everything transits as curve IDs
except for API entry points (SSL_set1_curves) which take NIDs. Those
convert immediately and act on curve IDs from then on.

Note that, like the Go implementation, this slightly tweaks the order of
operations. The client sees the server public key before sending its
own. To keep the abstraction simple, SSL_ECDH_METHOD expects to
generate a keypair before consuming the peer's public key. Instead, the
client handshake stashes the serialized peer public value and defers
parsing it until it comes time to send ClientKeyExchange. (This is
analogous to what it was doing before where it stashed the parsed peer
public value instead.)

It still uses TLS 1.2 terminology everywhere, but this abstraction should also
be compatible with TLS 1.3 which unifies (EC)DH-style key exchanges.
(Accordingly, this abstraction intentionally does not handle parsing the
ClientKeyExchange/ServerKeyExchange framing or attempt to handle asynchronous
plain RSA or the authentication bits.)

BUG=571231

Change-Id: Iba09dddee5bcdfeb2b70185308e8ab0632717932
Reviewed-on: https://boringssl-review.googlesource.com/6780
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 21:51:30 +00:00
David Benjamin c18ef750ee Allocate a NID for X25519.
No corresponding OID, but SSL_CTX_set1_curves assumes NIDs exist.

BUG=571231

Change-Id: Id5221cdc59132e26a89ae5f8978b946de690b4e0
Reviewed-on: https://boringssl-review.googlesource.com/6779
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 18:56:53 +00:00
David Benjamin 3a2a48086b Remove long-dead comment.
clang-format keeps getting annoyed at it. Also remove some long-dead
constants.

Change-Id: I61e773f5be1e60ca28f1ea085e3afa7cb2c97b9e
Reviewed-on: https://boringssl-review.googlesource.com/6778
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 18:55:53 +00:00
David Benjamin cba2b62a85 Implement draft-ietf-tls-curve25519-01 in Go.
This injects an interface to abstract between elliptic.Curve and a
byte-oriented curve25519. The C implementation will follow a similar
strategy.

Note that this slightly tweaks the order of operations. The client sees
the server public key before sending its own. To keep the abstraction
simple, ecdhCurve expects to generate a keypair before consuming the
peer's public key. Instead, the client handshake stashes the serialized
peer public value and defers parsing it until it comes time to send
ClientKeyExchange. (This is analogous to what it was doing before where
it stashed the parsed peer public value instead.)

BUG=571231

Change-Id: I771bb9aee0dd6903d395c84ec4f2dd7b3e366c75
Reviewed-on: https://boringssl-review.googlesource.com/6777
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 18:43:33 +00:00
David Benjamin ab14563022 Bundle a copy of golang.org/x/crypto/curve25519 for testing.
Hopefully this can be replaced with a standard library version later.

BUG=571231

Change-Id: I61ae1d9d057c6d9e1b92128042109758beccc7ff
Reviewed-on: https://boringssl-review.googlesource.com/6776
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 17:47:53 +00:00
David Benjamin a029ebc4c6 Switch the bundled poly1305 to relative imports.
We don't live in a workspace, but relative import paths exist, so we
don't have to modify the modules we bundle to avoid naming collisions.

Change-Id: Ie7c70dbc4bb0485421814d40b6a6bd5f140e1d29
Reviewed-on: https://boringssl-review.googlesource.com/6781
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 17:47:28 +00:00
David Benjamin 64d9250e2f Completely remove P-224 from the TLS stack.
It already wasn't in the default list and no one enables it. Remove it
altogether. (It's also gone from the current TLS 1.3 draft.)

Change-Id: I143d07d390d186252204df6bdb8ffd22649f80e3
Reviewed-on: https://boringssl-review.googlesource.com/6775
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 17:45:26 +00:00
David Benjamin 8c2b3bf965 Test all supported curves (including those off by default).
Change-Id: I54b2b354ab3d227305f829839e82e7ae7292fd7d
Reviewed-on: https://boringssl-review.googlesource.com/6774
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 17:41:47 +00:00
David Benjamin fc8251258d Convert ssl3_send_cert_verify to CBB.
In doing so, make the asynchronous portion look more like
ssl3_send_server_key_exchange. This is a considerably simpler structure,
so the save/resume doesn't need any state.

Mostly this means writing out the signature algorithm can now go through
CBB rather than a uint8_t* without bounds check.

Change-Id: If99fcffd0d41a84514c3d23034062c582f1bccb2
Reviewed-on: https://boringssl-review.googlesource.com/6771
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 17:40:47 +00:00
Adam Langley 5fb18c6b42 Make MSVC happy.
The MSVC build is failing with:
  ssl\s3_srvr.c(1363) : warning C4701: potentially uninitialized local variable 'digest_len' used

I don't believe that this warning is valid, but this change assigns a
value to |digest_len| to fix the build.

Change-Id: I20107a932bc16c880032cc1a57479b1a806aa8ea
Reviewed-on: https://boringssl-review.googlesource.com/6821
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 17:38:45 +00:00
David Benjamin 2a0b391ac9 Rewrite ssl3_send_server_key_exchange to use CBB.
There is some messiness around saving and restoring the CBB, but this is
still significantly clearer.

Note that the BUF_MEM_grow line is gone in favor of a fixed CBB like the
other functions ported thus far. This line was never necessary as
init_buf is initialized to 16k and none of our key exchanges get that
large. (The largest one can get is DHE_RSA. Even so, it'd take a roughly
30k-bit DH group with a 30k-bit RSA key.)

Having such limits and tight assumptions on init_buf's initial size is
poor (but on par for the old code which usually just blindly assumed the
message would not get too large) and the size of the certificate chain
is much less obviously bounded, so those BUF_MEM_grows can't easily go.

My current plan is convert everything but those which legitimately need
BUF_MEM_grow to CBB, then atomically convert the rest, remove init_buf,
and switch everything to non-fixed CBBs. This will hopefully also
simplify async resumption. In the meantime, having a story for
resumption means the future atomic change is smaller and, more
importantly, relieves some complexity budget in the ServerKeyExchange
code for adding Curve25519.

Change-Id: I1de6af9856caaed353453d92a502ba461a938fbd
Reviewed-on: https://boringssl-review.googlesource.com/6770
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 17:23:58 +00:00
David Benjamin d16bf3421c Add a -lldb flag to runner.go.
Apple these days ships lldb without gdb. Teach runner how to launch it
too.

Change-Id: I25f845f84f1c87872a9e3bc4b7fe3e7344e8c1f7
Reviewed-on: https://boringssl-review.googlesource.com/6769
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 17:05:50 +00:00
David Benjamin af21bcf91f Remove other unnecessary BN_CTX allocations.
Functions which take a BN_CTX also accept NULL. Allocating a BN_CTX is
only useful if doing multiple operations, which we aren't.

Change-Id: Ib31113f214707cce6283e090ded0bf93ae5e7c12
Reviewed-on: https://boringssl-review.googlesource.com/6768
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 17:01:58 +00:00
David Benjamin ae0eaaa397 Convert ssl3_send_client_key_exchange to CBB.
This relieves some complexity budget for adding Curve25519 to this
code.

This also adds a BN_bn2cbb_padded helper function since this seems to be a
fairly common need.

Change-Id: Ied0066fdaec9d02659abd6eb1a13f33502c9e198
Reviewed-on: https://boringssl-review.googlesource.com/6767
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 17:00:56 +00:00
Adam Langley 3ac4b3a391 Remove NO_ASM define that I accidently included in the previous commit.
Change-Id: I0000e51930cd1e286173f96f79dbb18d33cd294a
Reviewed-on: https://boringssl-review.googlesource.com/6811
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 16:34:33 +00:00
Adam Langley e6c540290d Don't build X25519 asm code when NO_ASM is set.
Change-Id: I6c7188648d81ab11a43b5491a850fb1d74e40986
Reviewed-on: https://boringssl-review.googlesource.com/6810
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 16:32:53 +00:00
Adam Langley 77a173efed Add x86-64 assembly for X25519.
This assembly is in gas syntax so is not built on Windows nor when
OPENSSL_SMALL is defined.

Change-Id: I1050cf1b16350fd4b758e4c463261b30a1b65390
Reviewed-on: https://boringssl-review.googlesource.com/6782
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 16:22:38 +00:00
Matt Braithwaite c75c0ae088 Add #defines for ED25519 key and signature lengths.
Change-Id: I3299f8fc4602c24688339dbffb1d7939282ad6b3
Reviewed-on: https://boringssl-review.googlesource.com/6723
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 16:06:07 +00:00
David Benjamin 48cce66aac Tidy up ssl3_get_server_key_exchange slightly.
Single-use BN_CTXs are unnecessary.

Change-Id: I2d59aae2168e43937c5d527794c335ed2809d547
Reviewed-on: https://boringssl-review.googlesource.com/6766
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 00:25:45 +00:00
David Benjamin c1cc858af2 Check for EC_KEY_set_public_key error.
This function may fail on malloc error.

Change-Id: I8631b1763dac5a3801fcaca81bdfcb8d24d3728c
Reviewed-on: https://boringssl-review.googlesource.com/6765
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 00:24:24 +00:00
David Benjamin 4cc671cbf4 Add CBB_reserve and CBB_did_write.
These will be needed when we start writing variable-length things to a
CBB.

Change-Id: Ie7b9b140f5f875b43adedc8203ce9d3f4068dfea
Reviewed-on: https://boringssl-review.googlesource.com/6764
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 00:23:52 +00:00
David Benjamin e13263d5e4 Resolve a few old TODOs.
A lot of commented-out code we haven't had to put them back, so these
can go now. Also remove the TODO about OAEP having a weird API. The API
is wrong, but upstream's shipped it with the wrong API, so that's what
it is now.

Change-Id: I7da607cf2d877cbede41ccdada31380f812f6dfa
Reviewed-on: https://boringssl-review.googlesource.com/6763
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 00:14:35 +00:00
David Benjamin 841934f079 Remove stack macros for nonexistent types.
There's a few that can't work since the types don't even exist.

Change-Id: Idf860b146439c95d33814d25bbc9b8f61774b569
Reviewed-on: https://boringssl-review.googlesource.com/6762
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 00:12:38 +00:00
David Benjamin 70ab223490 Remove ASN1_R_MALLOC_FAILURE.
There was a TODO to remove it once asn1_mac.h was trimmed. This has now
happened. Remove it and reset error codes for crypto/asn1.

Change-Id: Iaf2f3e75741914415372939471b135618910f95d
Reviewed-on: https://boringssl-review.googlesource.com/6761
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 00:12:24 +00:00
David Benjamin b965c63acb Reject calls to X509_verify_cert that have not been reinitialised
The function X509_verify_cert checks the value of |ctx->chain| at the
beginning, and if it is NULL then it initialises it, along with the value
of |ctx->untrusted|. The normal way to use X509_verify_cert() is to first
call X509_STORE_CTX_init(); then set up various parameters etc; then call
X509_verify_cert(); then check the results; and finally call
X509_STORE_CTX_cleanup(). The initial call to X509_STORE_CTX_init() sets
|ctx->chain| to NULL. The only place in the OpenSSL codebase  where
|ctx->chain| is set to anything other than a non NULL value is in
X509_verify_cert itself. Therefore the only ways that |ctx->chain| could be
non NULL on entry to X509_verify_cert is if one of the following occurs:
1) An application calls X509_verify_cert() twice without re-initialising
in between.
2) An application reaches inside the X509_STORE_CTX structure and changes
the value of |ctx->chain| directly.

With regards to the second of these, we should discount this - it should
not be supported to allow this.

With regards to the first of these, the documentation is not exactly
crystal clear, but the implication is that you must call
X509_STORE_CTX_init() before each call to X509_verify_cert(). If you fail
to do this then, at best, the results would be undefined.

Calling X509_verify_cert() with |ctx->chain| set to a non NULL value is
likely to have unexpected results, and could be dangerous. This commit
changes the behaviour of X509_verify_cert() so that it causes an error if
|ctx->chain| is anything other than NULL (because this indicates that we
have not been initialised properly). It also clarifies the associated
documentation.

(Imported from upstream's 692f07c3e0c04180b56febc2feb57cd94395a7a2.)

Change-Id: I971f1a305f12bbf9f4ae955313d5557368f0d374
Reviewed-on: https://boringssl-review.googlesource.com/6760
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 00:12:00 +00:00
David Benjamin 3f5b43df07 Simplify RSA key exchange padding check.
This check was fixed a while ago, but it could have been much simpler.

In the RSA key exchange, the expected size of the output is known, making the
padding check much simpler. There isn't any use in exporting the more general
RSA_message_index_PKCS1_type_2. (Without knowing the expected size, any
integrity check or swap to randomness or other mitigation is basically doomed
to fail.)

Verified with the valgrind uninitialized memory trick that we're still
constant-time.

Also update rsa.h to recommend against using the PKCS#1 v1.5 schemes.

Thanks to Ryan Sleevi for the suggestion.

Change-Id: I4328076b1d2e5e06617dd8907cdaa702635c2651
Reviewed-on: https://boringssl-review.googlesource.com/6613
Reviewed-by: Adam Langley <agl@google.com>
2015-12-22 00:10:14 +00:00
Luke Granger-Brown 3ef608594d Refuse to parse RSA pubkeys with invalid exponents.
We should reject RSA public keys with exponents of less than 3.

This change also rejects even exponents, although the usefulness
of such a public key is somewhat questionable.

BUG=chromium:541257

Change-Id: I1499e9762ba40a7cf69155d21d55bc210cd6d273
Reviewed-on: https://boringssl-review.googlesource.com/6710
Reviewed-by: Adam Langley <agl@google.com>
2015-12-21 23:49:02 +00: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
Piotr Sikora d7421ebf6c Remove condition which always evaluates to true (size_t >= 0).
Found with -Wtype-limits.

Change-Id: I5580f179425bc6b09ff2a8559fce121b0cc8ae14
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
Reviewed-on: https://boringssl-review.googlesource.com/6463
Reviewed-by: Adam Langley <agl@google.com>
2015-11-11 22:20:19 +00:00
Piotr Sikora d386394aad Test for underflow before subtraction.
Found with -Wtype-limits.

Change-Id: I41cdbb7e6564b715dfe445877a89594371fdeef0
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
Reviewed-on: https://boringssl-review.googlesource.com/6462
Reviewed-by: Adam Langley <agl@google.com>
2015-11-11 22:20:04 +00:00
David Benjamin ef14b2d86e Remove stl_compat.h.
Chromium's toolchains may now assume C++11 library support, so we may freely
use C++11 features. (Chromium's still in the process of deciding what to allow,
but we use Google's style guide directly, toolchain limitations aside.)

Change-Id: I1c7feb92b7f5f51d9091a4c686649fb574ac138d
Reviewed-on: https://boringssl-review.googlesource.com/6465
Reviewed-by: Adam Langley <agl@google.com>
2015-11-11 22:19:36 +00:00
David Benjamin cd24a39f1b Limit DHE groups to 4096-bit.
dh.c had a 10k-bit limit but it wasn't quite correctly enforced. However,
that's still 1.12s of jank on the IO thread, which is too long. Since the SSL
code consumes DHE groups from the network, it should be responsible for
enforcing what sanity it needs on them.

Costs of various bit lengths on 2013 Macbook Air:
1024 - 1.4ms
2048 - 14ms
3072 - 24ms
4096 - 55ms
5000 - 160ms
10000 - 1.12s

UMA says that DHE groups are 0.2% 4096-bit and otherwise are 5.5% 2048-bit and
94% 1024-bit and some noise. Set the limit to 4096-bit to be conservative,
although that's already quite a lot of jank.

BUG=554295

Change-Id: I8e167748a67e4e1adfb62d73dfff094abfa7d215
Reviewed-on: https://boringssl-review.googlesource.com/6464
Reviewed-by: Adam Langley <agl@google.com>
2015-11-11 22:18:39 +00:00
David Benjamin 99fdfb9f22 Move curve check out of tls12_check_peer_sigalg.
The current check has two problems:

- It only runs on the server, where there isn't a curve list at all. This was a
  mistake in https://boringssl-review.googlesource.com/1843 which flipped it
  from client-only to server-only.

- It only runs in TLS 1.2, so one could bypass it by just negotiating TLS 1.1.
  Upstream added it as part of their Suite B mode, which requires 1.2.

Move it elsewhere. Though we do not check the entire chain, leaving that to the
certificate verifier, signatures made by the leaf certificate are made by the
SSL/TLS stack, so it's reasonable to check the curve as part of checking
suitability of a leaf.

Change-Id: I7c12f2a32ba946a20e9ba6c70eff23bebcb60bb2
Reviewed-on: https://boringssl-review.googlesource.com/6414
Reviewed-by: Adam Langley <agl@google.com>
2015-11-11 22:15:16 +00:00
Adam Langley 7104cc96b7 Update and fix fuzzing instructions.
It's easier to put libFuzzer.a into the source directory than to install
it globally.

Change-Id: I4dc7b56f81c7aa0371475c68d23368b025186505
Reviewed-on: https://boringssl-review.googlesource.com/6461
Reviewed-by: Adam Langley <agl@google.com>
2015-11-10 23:37:36 +00:00
Adam Langley 9a4beb8ad8 Add four, basic fuzz tests.
This change adds fuzzing tests for:
  ∙ Certificate parsing
  ∙ Private key parsing
  ∙ ClientHello parsing
  ∙ Server first flow (ServerHello, Certificate, etc) parsing.

Change-Id: I5f53282263eaaff69b1a03c819cca73750433653
Reviewed-on: https://boringssl-review.googlesource.com/6460
Reviewed-by: Adam Langley <agl@google.com>
2015-11-10 19:14:01 +00:00
Adam Langley 4ab254017c Add AArch64 Montgomery assembly.
The file armv8-mont.pl is taken from upstream. The speed ups are fairly
modest (~30%) but seem worthwhile.

Before:

Did 231 RSA 2048 signing operations in 1008671us (229.0 ops/sec)
Did 11208 RSA 2048 verify operations in 1036997us (10808.1 ops/sec)
Did 342 RSA 2048 (3 prime, e=3) signing operations in 1021545us (334.8 ops/sec)
Did 32000 RSA 2048 (3 prime, e=3) verify operations in 1016162us (31491.0 ops/sec)
Did 45 RSA 4096 signing operations in 1039805us (43.3 ops/sec)
Did 3608 RSA 4096 verify operations in 1060283us (3402.9 ops/sec)

After:

Did 300 RSA 2048 signing operations in 1009772us (297.1 ops/sec)
Did 12740 RSA 2048 verify operations in 1075413us (11846.6 ops/sec)
Did 408 RSA 2048 (3 prime, e=3) signing operations in 1016139us (401.5 ops/sec)
Did 33000 RSA 2048 (3 prime, e=3) verify operations in 1017510us (32432.1 ops/sec)
Did 52 RSA 4096 signing operations in 1067678us (48.7 ops/sec)
Did 3408 RSA 4096 verify operations in 1062863us (3206.4 ops/sec)

Change-Id: Ife74fac784067fce3668b5c87f51d481732ff855
Reviewed-on: https://boringssl-review.googlesource.com/6444
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-11-10 19:13:46 +00:00
Adam Langley ad38dc7452 Enable Montgomery optimisations on ARM.
These were accidently disabled for ARM.

Before:

Did 38 RSA 2048 signing operations in 1051209us (36.1 ops/sec)
Did 1500 RSA 2048 verify operations in 1069611us (1402.4 ops/sec)
Did 65 RSA 2048 (3 prime, e=3) signing operations in 1055664us (61.6 ops/sec)
Did 4719 RSA 2048 (3 prime, e=3) verify operations in 1029144us (4585.4 ops/sec)
Did 5 RSA 4096 signing operations in 1092346us (4.6 ops/sec)
Did 418 RSA 4096 verify operations in 1069977us (390.7 ops/sec)

After:

Did 156 RSA 2048 signing operations in 1000672us (155.9 ops/sec)
Did 6071 RSA 2048 verify operations in 1068512us (5681.7 ops/sec)
Did 84 RSA 2048 (3 prime, e=3) signing operations in 1068847us (78.6 ops/sec)
Did 11000 RSA 2048 (3 prime, e=3) verify operations in 1023620us (10746.2 ops/sec)
Did 26 RSA 4096 signing operations in 1028320us (25.3 ops/sec)
Did 1788 RSA 4096 verify operations in 1072479us (1667.2 ops/sec)

Change-Id: I448698f7d8e5b481a06f98d54d608f0278827cd1
Reviewed-on: https://boringssl-review.googlesource.com/6443
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-11-09 23:06:58 +00:00
Adam Langley 2e64f1b5d5 Check PKCS#8 pkey field is valid before cleansing.
(Imported from upstream's 52e028b9de371da62c1e51b46592517b1068d770.)

Change-Id: If980d774671b9b5ba997db3fd7d4043525a85609
Reviewed-on: https://boringssl-review.googlesource.com/6445
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-11-09 23:06:13 +00:00
David Benjamin f606f9831b bssl pkcs12 shouldn't crash on missing key.
PKCS#12 files may not necessarily include keys.

Change-Id: Ibb43b609783b02aa9cbb192fea377081169666ff
Reviewed-on: https://boringssl-review.googlesource.com/6456
Reviewed-by: Adam Langley <agl@google.com>
2015-11-09 23:05:20 +00:00
David Benjamin e348ff4a72 Fix build.
There seems to have been a merge error.

Change-Id: I72e5c2a45c148e31c90b28bedfff48f8ca6e3c8c
Reviewed-on: https://boringssl-review.googlesource.com/6455
Reviewed-by: Adam Langley <agl@google.com>
2015-11-06 22:58:14 +00:00
David Benjamin 6e80765774 Add SSL_get_server_key_exchange_hash.
This exposes the ServerKeyExchange signature hash type used in the most recent
handshake, for histogramming on the client.

BUG=549662

Change-Id: I8a4e00ac735b1ecd2c2df824112c3a0bc62332a7
Reviewed-on: https://boringssl-review.googlesource.com/6413
Reviewed-by: Adam Langley <agl@google.com>
2015-11-06 22:35:28 +00:00
David Benjamin 788be4a3f4 Remove the hard-coded SHA-1 exception for sigalgs.
This is completely a no-op as currently tls12_get_psigalgs always returns a
hardcoded list which always includes SHA-1. But if this were to be made
configurable in the future, we should reject SHA-1 when configured to do so.

Change-Id: I7ab188eeff850d1e5f70b9522304812bab2d941a
Reviewed-on: https://boringssl-review.googlesource.com/6411
Reviewed-by: Adam Langley <agl@google.com>
2015-11-06 22:31:48 +00:00
Brian Smith 5d5e39f5d2 Remove non-ASM version of |bn_mul_mont| in bn/generic.c.
When building in OPENSSL_NO_ASM mode, MSVC complains about unreachable
code. The redundant initialization of |i| is the main problem. The
skipping of the first test of the condition |i < num| with |goto| was
also confusing.

It turns out that |bn_mul_mont| is only called when assembly language
optimizations are available, but in that case the assmebly language
versions will always be used instead. Although this code will be
compiled in |OPENSSL_NO_ASM| builds, it is never called in
|OPENSSL_NO_ASM| builds. Thus, it can just be removed.

Change-Id: Id551899b2602824978edc1a1cb0703b76516808d
Reviewed-on: https://boringssl-review.googlesource.com/5550
Reviewed-by: Adam Langley <agl@google.com>
2015-11-06 22:28:58 +00:00
Adam Langley 59b0fccb51 Define BORINGSSL_201510.
I've used these defines to easy the update of BoringSSL in Android
because Android's external/boringssl is a different git repository from
the rest of Android and thus it's not possible to land changes the
atomically update several things at once.

For this I tended just to add this define in the Android copy of
BoringSSL, but we're starting to see that bleed into other situations
now so it's looking like this will be generally useful.

These defines may be added when useful but shouldn't build up: once the
change has been done, the #if'ed code elsewhere that uses it should be
cleaned up. So far, that's worked ok. (I.e. we've had a BORINGSSL_201509
that correctly disappeared.)

Change-Id: I8cbb4731efe840cc798c970d37bc040b16a4a755
Reviewed-on: https://boringssl-review.googlesource.com/6442
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-11-06 21:44:17 +00:00
David Benjamin e6d1e5a871 Use typedef names, not struct names.
Not sure if we want to leave bio.h and bytestring.h's instance as-is, but the
evp.h ones are just baffling.

Change-Id: I485c2e355ba93764da0c4c72c48af48b055a8500
Reviewed-on: https://boringssl-review.googlesource.com/6454
Reviewed-by: Adam Langley <agl@google.com>
2015-11-06 21:44:06 +00:00
David Benjamin 16285ea800 Rewrite DTLS handshake message sending logic.
This fixes a number of bugs with the original logic:

- If handshake messages are fragmented and writes need to be retried, frag_off
  gets completely confused.

- The BIO_flush call didn't set rwstate, so it wasn't resumable at that point.

- The msg_callback call gets garbage because the fragment header would get
  scribbled over the handshake buffer.

The original logic was also extremely confusing with how it handles init_off.
(init_off gets rewound to make room for the fragment header.  Depending on
where you pause, resuming may or may not have already been rewound.)

For simplicity, just allocate a new buffer to assemble the fragment in and
avoid clobbering the old one. I don't think it's worth the complexity to
optimize that. If we want to optimize this sort of thing, not clobbering seems
better anyway because the message may need to be retransmitted. We could avoid
doing a copy when buffering the outgoing message for retransmission later.

We do still need to track how far we are in sending the current message via
init_off, so I haven't opted to disconnect this function from
init_{buf,off,num} yet.

Test the fix to the retry + fragment case by having the splitHandshake option
to the state machine tests, in DTLS, also clamp the MTU to force handshake
fragmentation.

Change-Id: I66f634d6c752ea63649db8ed2f898f9cc2b13908
Reviewed-on: https://boringssl-review.googlesource.com/6421
Reviewed-by: Adam Langley <agl@google.com>
2015-11-06 21:43:32 +00:00
David Benjamin c81ee8b40c Add missing state to DTLS state machine.
This was a mistake from when we added async CertificateVerify support.
No test because the final state of each write state is semi-unreachable
due to the buffer BIO that gets installed on each handshake.

Change-Id: I0180926522113c8b1ca58b8c9c6dc37fb0dd8083
Reviewed-on: https://boringssl-review.googlesource.com/6412
Reviewed-by: Adam Langley <agl@google.com>
2015-11-06 20:34:48 +00:00
Brian Smith 2e24b9bf73 Allow SHA-512 unaligned data access in |OPENSSL_NO_ASM| mode.
The previous logic only defined
|SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA| when the assembly language
optimizations were enabled, but
|SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA| is also useful when the C
implementations are used.

If support for ARM processors that don't support unaligned access is
important, then it might be better to condition the enabling of
|SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA| on ARM based on more specific
flags.

Change-Id: Ie8c37c73aba308c3ccf79371ce5831512e419989
Reviewed-on: https://boringssl-review.googlesource.com/6402
Reviewed-by: Adam Langley <agl@google.com>
2015-11-06 20:06:54 +00:00
David Benjamin e82e6f6696 Constify more BN_MONT_CTX parameters.
Most functions can take this in as const. Note this changes an
RSA_METHOD hook, though one I would not expect anyone to override.

Change-Id: Ib70ae65e5876b01169bdc594e465e3e3c4319a8b
Reviewed-on: https://boringssl-review.googlesource.com/6419
Reviewed-by: Adam Langley <agl@google.com>
2015-11-06 20:04:36 +00:00
David Benjamin c7817d8ce2 Add SSL_CIPHER_get_min_version and tidy up SSL_TLSV1_2 logic.
Later when TLS 1.3 comes around, we'll need SSL_CIPHER_get_max_version too. In
the meantime, hide the SSL_TLSV1_2 messiness behind a reasonable API.

Change-Id: Ibcc17cccf48dd99e364d6defdfa5a87d031ecf0a
Reviewed-on: https://boringssl-review.googlesource.com/6452
Reviewed-by: Adam Langley <agl@google.com>
2015-11-06 19:56:29 +00:00
Brian Smith 9d94d5e4ae Remove untested, unnecessary big-endian SHA-1/SHA-256 optimizations.
Change-Id: I3939923d297b901719cb3fb4cff20e770f780c7a
Reviewed-on: https://boringssl-review.googlesource.com/6441
Reviewed-by: Adam Langley <agl@google.com>
2015-11-06 19:36:24 +00:00
Adam Langley 38feb990a1 Require that EC points are on the curve.
This removes a sharp corner in the API where |ECDH_compute_key| assumed
that callers were either using ephemeral keys, or else had already
checked that the public key was on the curve.

A public key that's not on the curve can be in a small subgroup and thus
the result can leak information about the private key.

This change causes |EC_POINT_set_affine_coordinates_GFp| to require that
points are on the curve. |EC_POINT_oct2point| already does this.

Change-Id: I77d10ce117b6efd87ebb4a631be3a9630f5e6636
Reviewed-on: https://boringssl-review.googlesource.com/5861
Reviewed-by: Adam Langley <agl@google.com>
2015-11-06 19:35:42 +00:00
David Benjamin ef793f4b6f Add various functions for SSL_CIPHER.
Change-Id: I21051a6d1594c2606e171449d377663f8eccc847
Reviewed-on: https://boringssl-review.googlesource.com/6450
Reviewed-by: Adam Langley <agl@google.com>
2015-11-06 19:26:22 +00:00
David Benjamin f93995be60 Test that the client doesn't offer TLS 1.2 ciphers when it shouldn't.
Change-Id: I20541e6eb5cfd48e53de5950bce312aae9801a54
Reviewed-on: https://boringssl-review.googlesource.com/6451
Reviewed-by: Adam Langley <agl@google.com>
2015-11-06 19:18:24 +00:00
Adam Langley 5f88999a1e Fix up several comments and detect problems in the future.
This change fixes up several comments (many of which were spotted by
Kenny Root) and also changes doc.go to detect cases where comments don't
start with the correct word. (This is a common error.)

Since we have docs builders now, these errors will be found
automatically in the future.

Change-Id: I58c6dd4266bf3bd4ec748763c8762b1a67ae5ab3
Reviewed-on: https://boringssl-review.googlesource.com/6440
Reviewed-by: Adam Langley <agl@google.com>
2015-11-05 20:12:45 +00:00
Adam Langley e57a19203f Add missing newline in aead.h.
c2d3280f was missing a newline before the trailer.

Change-Id: I0118259b7a8ab15aaaa55125a0f92f3a97794b81
2015-11-04 11:53:46 -08:00
Adam Langley c2d3280f0f Add SSL_get_ivs.
This function allows one to extract the current IVs from an SSL
connection. This is needed for the CBC cipher suites with implicit IVs
because, for those, the IV can't be extracted from the handshake key
material.

Change-Id: I247a1d0813b7a434b3cfc88db86d2fe8754344b6
Reviewed-on: https://boringssl-review.googlesource.com/6433
Reviewed-by: Adam Langley <agl@google.com>
2015-11-04 19:45:28 +00:00
David Benjamin a97b737fb0 Separate CCS and handshake writing in DTLS.
They run through completely different logic as only handshake is fragmented.
This'll make it easier to rewrite the handshake logic in a follow-up.

Change-Id: I9515feafc06bf069b261073873966e72fcbe13cb
Reviewed-on: https://boringssl-review.googlesource.com/6420
Reviewed-by: Adam Langley <agl@google.com>
2015-11-04 00:11:14 +00:00
Brian Smith ac9404c3a8 Improve crypto/digest/md32_common.h mechanism.
The documentation in md32_common.h is now (more) correct with respect
to the most important details of the layout of |HASH_CTX|. The
documentation explaining why sha512.c doesn't use md32_common.h is now
more accurate as well.

Before, the C implementations of HASH_BLOCK_DATA_ORDER took a pointer
to the |HASH_CTX| and the assembly language implementations took a
pointer to the hash state |h| member of |HASH_CTX|. (This worked
because |h| is always the first member of |HASH_CTX|.) Now, the C
implementations take a pointer directly to |h| too.

The definitions of |MD4_CTX|, |MD5_CTX|, and |SHA1_CTX| were changed to
be consistent with |SHA256_CTX| and |SHA512_CTX| in storing the hash
state in an array. This will break source compatibility with any
external code that accesses the hash state directly, but will not
affect binary compatibility.

The second parameter of |HASH_BLOCK_DATA_ORDER| is now of type
|const uint8_t *|; previously it was |void *| and all implementations
had a |uint8_t *data| variable to access it as an array of bytes.

This change paves the way for future refactorings such as automatically
generating the |*_Init| functions and/or sharing one I-U-F
implementation across all digest algorithms.

Change-Id: I6e9dd09ff057c67941021d324a4fa1d39f58b0db
Reviewed-on: https://boringssl-review.googlesource.com/6405
Reviewed-by: Adam Langley <agl@google.com>
2015-11-04 00:01:09 +00:00
David Benjamin 8fb0f525e1 Free BN_MONT_CTX in generic code.
Although those are only created by code owned by RSA_METHOD, custom RSA_METHODs
shouldn't be allowed to squat our internal fields and then change how you free
things.

Remove 'method' from their names now that they're not method-specific.

Change-Id: I9494ef9a7754ad59ac9fba7fd463b3336d826e0b
Reviewed-on: https://boringssl-review.googlesource.com/6423
Reviewed-by: Adam Langley <agl@google.com>
2015-11-03 23:39:41 +00:00
David Benjamin bb875350b3 Fix ASan bot.
This restores the original semantics of the finished hook.

Change-Id: I70da393c7e66fb6e3be1e2511e08b34bb54fc0b4
Reviewed-on: https://boringssl-review.googlesource.com/6422
Reviewed-by: Adam Langley <agl@google.com>
2015-11-03 23:28:56 +00:00
David Benjamin d93831d71a Make it possible for a static linker to discard unused RSA functions.
Having a single RSA_METHOD means they all get pulled in. Notably, RSA key
generation pulls in the primality-checking code.

Change-Id: Iece480113754da090ddf87b64d8769f01e05d26c
Reviewed-on: https://boringssl-review.googlesource.com/6389
Reviewed-by: Adam Langley <agl@google.com>
2015-11-03 23:02:38 +00:00
David Benjamin e8f783ac0d Unwind DH_METHOD and DSA_METHOD.
This will allow a static linker (with -ffunction-sections since things aren't
split into files) to drop unused parts of DH and DSA. Notably, the parameter
generation bits pull in primality-checking code.

Change-Id: I25087e4cb91bc9d0ab43bcb267c2e2c164e56b59
Reviewed-on: https://boringssl-review.googlesource.com/6388
Reviewed-by: Adam Langley <agl@google.com>
2015-11-03 22:54:36 +00:00
David Benjamin 3fc138eccd Don't bother sampling __func__.
Removing the function codes continued to sample __func__ for compatibility with
ERR_print_errors_cb, but not ERR_error_string_n. We can just emit
OPENSSL_internal for both. ERR_print_errors_cb already has the file and line
number available which is strictly more information than the function name.
(ERR_error_string_n does not, but we'd already turned that to
OPENSSL_internal.)

This shaves 100kb from a release build of the bssl tool.

In doing so, put an unused function code parameter back into ERR_put_error to
align with OpenSSL. We don't need to pass an additional string in anymore, so
OpenSSL compatibility with anything which uses ERR_LIB_USER or
ERR_get_next_error_library costs nothing. (Not that we need it.)

Change-Id: If6af34628319ade4145190b6f30a0d820e00b20d
Reviewed-on: https://boringssl-review.googlesource.com/6387
Reviewed-by: Adam Langley <agl@google.com>
2015-11-03 22:50:59 +00:00
Adam Langley 165248c24f Fix several MSVC warnings.
MSVC reports lots of:
warning C4090: 'function' : different 'const' qualifiers

Change-Id: If8184538c44e657f6234252d0147396d1a18b36c
2015-11-03 14:31:33 -08:00
Adam Langley 8f7ecb8f0c (Hopefully) fix a warning on Windows.
MSVC unhelpfuly says: warning C4146: unary minus operator applied to
unsigned type, result still unsigned.

Change-Id: Ia1e6b9fc415908920abb1bcd98fc7f7a5670c2c7
2015-11-03 14:29:01 -08:00
Adam Langley 466b9895ac Initialise variable before jump.
Clang finds:

crypto/ec/ec.c:420:7: error: variable 'ok' is used uninitialized
whenever 'if' condition is true [-Werror,-Wsometimes-uninitialized]
  if (ctx == NULL) {
        ^~~~~~~~~~~

Change-Id: I33fc4d74ff3a3bd52ab155f8273fbcd9c6256e35
2015-11-03 14:20:45 -08:00
Adam Langley 1895493868 Add Intel's P-256
This change incorporates Intel's P-256 implementation. The record of
Intel's submission under CLA is in internal bug number 25330687.

Before:
Did 3582 ECDH P-256 operations in 1049114us (3414.3 ops/sec)
Did 8525 ECDSA P-256 signing operations in 1028778us (8286.5 ops/sec)
Did 3487 ECDSA P-256 verify operations in 1008996us (3455.9 ops/sec)
build/tool/bssl is 1434704 bytes after strip -s

After:
Did 8618 ECDH P-256 operations in 1027884us (8384.2 ops/sec)
Did 21000 ECDSA P-256 signing operations in 1049490us (20009.7 ops/sec)
Did 8268 ECDSA P-256 verify operations in 1079481us (7659.2 ops/sec)
build/tool/bssl is 1567216 bytes after strip -s

Change-Id: I147971a8e19849779c8ed7e20310d41bd4962299
Reviewed-on: https://boringssl-review.googlesource.com/6371
Reviewed-by: Adam Langley <agl@google.com>
2015-11-03 22:08:47 +00:00
Adam Langley 27a0d086f7 Add ssl_renegotiate_ignore.
This option causes clients to ignore HelloRequest messages completely.
This can be suitable in cases where a server tries to perform concurrent
application data and handshake flow, e.g. because they are trying to
“renew” symmetric keys.

Change-Id: I2779f7eff30d82163f2c34a625ec91dc34fab548
Reviewed-on: https://boringssl-review.googlesource.com/6431
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-11-03 21:58:13 +00:00
Matt Braithwaite fa9eb568b0 Correct the spelling of "primitive".
Spotted by Matt Smart.

Change-Id: Id9c61ba6a293ddc52b2e2c93c427860765848c6d
Reviewed-on: https://boringssl-review.googlesource.com/6430
Reviewed-by: Adam Langley <agl@google.com>
2015-11-03 21:47:19 +00:00
Adam Langley f1c1cf8794 Revert "Improve crypto/digest/md32_common.h mechanism."
This reverts commit 00461cf201.

Sadly it broke wpa_supplicant.
2015-11-02 18:14:34 -08:00
Brian Smith 00461cf201 Improve crypto/digest/md32_common.h mechanism.
The documentation in md32_common.h is now (more) correct with respect
to the most important details of the layout of |HASH_CTX|. The
documentation explaining why sha512.c doesn't use md32_common.h is now
more accurate as well.

Before, the C implementations of HASH_BLOCK_DATA_ORDER took a pointer
to the |HASH_CTX| and the assembly language implementations tool a
pointer to the hash state |h| member of |HASH_CTX|. (This worked
because |h| is always the first member of |HASH_CTX|.) Now, the C
implementations take a pointer directly to |h| too.

The definitions of |MD4_CTX|, |MD5_CTX|, and |SHA1_CTX| were changed to
be consistent with |SHA256_CTX| and |SHA512_CTX| in storing the hash
state in an array. This will break source compatibility with any
external code that accesses the hash state directly, but will not
affect binary compatibility.

The second parameter of |HASH_BLOCK_DATA_ORDER| is now of type
|const uint8_t *|; previously it was |void *| and all implementations
had a |uint8_t *data| variable to access it as an array of bytes.

This change paves the way for future refactorings such as automatically
generating the |*_Init| functions and/or sharing one I-U-F
implementation across all digest algorithms.

Change-Id: I30513bb40b5f1d2c8932551d54073c35484b3f8b
Reviewed-on: https://boringssl-review.googlesource.com/6401
Reviewed-by: Adam Langley <agl@google.com>
2015-11-03 02:04:38 +00:00
David Benjamin ecc2591b6c Update link to Google style guide.
Change-Id: I0c9d86f188cd20d256620ccbb46546678714e081
Reviewed-on: https://boringssl-review.googlesource.com/6386
Reviewed-by: Adam Langley <agl@google.com>
2015-11-03 02:02:12 +00:00
Adam Langley efb42fbb60 Make BN_mod_exp_mont_consttime take a const context.
BN_mod_exp_mont_consttime does not modify its |BN_MONT_CTX| so that
value should be const.

Change-Id: Ie74e48eec8061899fd056fbd99dcca2a86b02cad
Reviewed-on: https://boringssl-review.googlesource.com/6403
Reviewed-by: Adam Langley <agl@google.com>
2015-11-03 01:58:12 +00:00
Adam Langley eb8be01f0c Add ciphers option to bssl.
This simply converts a cipher suite string to the list of cipher suites
that it implies.

Change-Id: Id8b31086715d619ea6601c40a6eb84dc0d8c500d
Reviewed-on: https://boringssl-review.googlesource.com/6370
Reviewed-by: Adam Langley <agl@google.com>
2015-11-03 01:17:02 +00:00
Adam Langley 09d68c98c0 Expand a comment.
As a follow up to https://boringssl-review.googlesource.com/#/c/6340,
this change expands a comment to note the reason for clearing a flag
that I missed.

Change-Id: Ib3cfecbb330f0ae7c46bf44286f4e6b407159fe8
Reviewed-on: https://boringssl-review.googlesource.com/6393
Reviewed-by: Adam Langley <agl@google.com>
2015-11-03 01:15:55 +00:00
David Benjamin 2e0901b75f Don't use ssl3_write_pending in DTLS.
That function doesn't do anything useful for DTLS. It's meant for tracking the
rest of the record we've already committed to by writing half of one. But one
cannot write half a datagram, so DTLS never tracks this. Just call
ssl_write_buffer_flush straight and don't touch wpend_*.

Change-Id: Ibe191907d64c955c7cfeefba26f5c11ad5e4b939
Reviewed-on: https://boringssl-review.googlesource.com/6418
Reviewed-by: Adam Langley <agl@google.com>
2015-11-02 23:17:24 +00:00
David Benjamin 13e81fc971 Fix DTLS asynchronous write handling.
Although the DTLS transport layer logic drops failed writes on the floor, it is
actually set up to work correctly. If an SSL_write fails at the transport,
dropping the buffer is fine. Arguably it works better than in TLS because we
don't have the weird "half-committed to data" behavior. Likewise, the handshake
keeps track of how far its gotten and resumes the message at the right point.

This broke when the buffering logic was rewritten because I didn't understand
what the DTLS code was doing. The one thing that doesn't work as one might
expect is non-fatal write errors during rexmit are not recoverable. The next
timeout must fire before we try again.

This code is quite badly sprinkled in here, so add tests to guard it against
future turbulence. Because of the rexmit issues, the tests need some hacks
around calls which may trigger them. It also changes the Go DTLS implementation
from being completely strict about sequence numbers to only requiring they be
monotonic.

The tests also revealed another bug. This one seems to be upstream's fault, not
mine. The logic to reset the handshake hash on the second ClientHello (in the
HelloVerifyRequest case) was a little overenthusiastic and breaks if the
ClientHello took multiple tries to send.

Change-Id: I9b38b93fff7ae62faf8e36c4beaf848850b3f4b9
Reviewed-on: https://boringssl-review.googlesource.com/6417
Reviewed-by: Adam Langley <agl@google.com>
2015-11-02 23:16:22 +00:00
David Benjamin ebda9b3736 Make recordingconn emit more useful things for DTLS.
It's somewhat annoying to have to parse out the packetAdaptor mini-language.
Actually seeing those is only useful when debugging the adaptor itself, rather
than DTLS. Switch the order of the two middleware bits and add an escape hatch
to log the funny opcodes.

Change-Id: I249c45928a76b747d69f3ab972ea4d31e0680a62
Reviewed-on: https://boringssl-review.googlesource.com/6416
Reviewed-by: Adam Langley <agl@google.com>
2015-11-02 23:01:01 +00:00
Torbjörn Granlund 069bedfe0c Fix documentation typo.
Change-Id: Ia060a9f8c30ea7446ddffcc2221a8f5a37f14d8c
Reviewed-on: https://boringssl-review.googlesource.com/6415
Reviewed-by: Adam Langley <agl@google.com>
2015-11-02 22:53:27 +00:00
Adam Langley ce514698f5 Fix a missing initializer that only Clang warns about.
89d4a68c introduced -Wmissing-field-initializers because it seemed
generally useful. However, Clang and GCC have differing opinions about
what counts as missing. This change should make Clang happy too.

Change-Id: I070c719f5c47f537207200d5399e093cc083e58f
2015-10-30 17:24:03 -07:00
Adam Langley d9e817309a Fix several warnings that arise in Android.
Android is now using Ninja so it doesn't spew so much to the terminal
and thus any warnings in BoringSSL (which builds really early in the
process) and much more obvious.

Thus this change fixes a few warnings that appear in the Android build.

Change-Id: Id255ace90fece772a1c3a718c877559ce920b960
Reviewed-on: https://boringssl-review.googlesource.com/6400
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-10-30 21:11:48 +00:00
Adam Langley bb85f3d655 Reorganise |SSL_SESSION| and |SSL| to save a little memory.
This is a fairly timid, first step at trying to pack common structures a
little better.

This change reorders a couple of structures a little and turns some
variables into bit-fields. Much more can still be done.

Change-Id: Idbe0f54d66559c0ad654bf7e8dea277a771a568f
Reviewed-on: https://boringssl-review.googlesource.com/6394
Reviewed-by: Adam Langley <agl@google.com>
2015-10-30 21:01:09 +00:00
Adam Langley dff504d39a Make the instructions for downloading the ARM compiler easier to copy and paste.
Change-Id: If78cba6abc36999488981db2a12b039024c757df
Reviewed-on: https://boringssl-review.googlesource.com/6391
Reviewed-by: Brian Smith <brian@briansmith.org>
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-10-30 20:47:08 +00:00
David Benjamin 51a01a5cd4 Revert most of "Refactor ChaCha20-Poly1305 AEAD nonce handling."
This reverts most of commit 271777f5ac. The old
ChaCha20-Poly1305, though being transitioned to the old name, should not change
in behavior. This also avoids adding a special-case to SSL_AEAD_CTX.

Also revert the name change to SSL_CIPHER_is_CHACHA20POLY1305. The one consumer
for that function doesn't need to distinguish the old and new variants, so
avoid unnecessary turbulence.

Change-Id: I5a6f97fccc5839d4d25e74e304dc002329d21b4b
Reviewed-on: https://boringssl-review.googlesource.com/6385
Reviewed-by: Adam Langley <agl@google.com>
2015-10-29 18:40:33 +00:00
Piotr Sikora 7063b6d062 Fix assert in SSL_set_shutdown.
Added in https://boringssl-review.googlesource.com/#/c/6312/.

Change-Id: I95f0c8d3a119513c50d1d62a78443c6445507bd4
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
Reviewed-on: https://boringssl-review.googlesource.com/6395
Reviewed-by: Adam Langley <agl@google.com>
2015-10-29 13:19:53 +00:00
Brian Smith 96b9f3b68c Switch rsa_test.cc to use the new RSA encrypt/decrypt API.
Change-Id: I799e289a402612446e08f64f59e0243f164cf695
Reviewed-on: https://boringssl-review.googlesource.com/6372
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-10-28 23:36:44 +00:00
David Benjamin 8e4db8b1c2 Fix even more ChaCha20 rename deadlocks.
QUIC code references the TXT macro. Also get rid of
TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305 which wasn't renamed for some reason.

Change-Id: I0308e07104b3cec394d748f3f1146bd786d2ace2
Reviewed-on: https://boringssl-review.googlesource.com/6384
Reviewed-by: Adam Langley <agl@google.com>
2015-10-28 21:09:46 +00:00
David Benjamin 278d34234f Get rid of all compiler version checks in perlasm files.
Since we pre-generate our perlasm, having the output of these files be
sensitive to the environment the run in is unhelpful. It would be bad to
suddenly change what features we do or don't compile in whenever workstations'
toolchains change or if developers do or don't have CC variables set.

Previously, all compiler-version-gated features were turned on in
https://boringssl-review.googlesource.com/6260, but this broke the build. I
also wasn't thorough enough in gathering performance numbers. So, flip them all
to off instead. I'll enable them one-by-one as they're tested.

This should result in no change to generated assembly.

Change-Id: Ib4259b3f97adc4939cb0557c5580e8def120d5bc
Reviewed-on: https://boringssl-review.googlesource.com/6383
Reviewed-by: Adam Langley <agl@google.com>
2015-10-28 19:33:04 +00:00
Piotr Sikora 3f5fe608c8 Support Bazel builds on other platforms.
This change causes the generated Bazel files to include the assembly
file lists for other platforms.

Change-Id: Ic474b6900f8c109393baac1ec9cc2d112f155a56
Reviewed-on: https://boringssl-review.googlesource.com/6390
Reviewed-by: Adam Langley <agl@google.com>
2015-10-28 19:26:57 +00:00
David Benjamin 87cfcdb6df Resolve another ChaCha20-Poly1305 rename deadlock.
WebRTC can't roll into Chromium without picking up the iOS build fix, but we
can't roll BoringSSL forwards because WebRTC also depends on the previously
exposed ChaCha20-Poly1305 cipher suite constants.

Define the old constants again.

Change-Id: If8434a0317e42b3aebe1bc1c5a58ed97a89a0230
Reviewed-on: https://boringssl-review.googlesource.com/6382
Reviewed-by: Adam Langley <agl@google.com>
2015-10-28 19:25:36 +00:00
David Benjamin 7dd3f77256 Fix aead.h header typo.
EVP_aead_chacha20_poly1305_old is listed twice instead of
EVP_aead_chacha20_poly1305.

Change-Id: I281eee7a8359cd2a2b04047c829ef351ea4a7b82
Reviewed-on: https://boringssl-review.googlesource.com/6381
Reviewed-by: Adam Langley <agl@google.com>
2015-10-28 17:50:23 +00:00
David Benjamin f8e9dcaeea iOS builds use the static ARM CPU configuration.
The other codepath is Linux-specific. This should get tidied up a bit but, in
the meantime, fix the Chromium iOS (NO_ASM) build. Even when the assembly gets
working, it seems iOS prefers you make fat binaries rather than detect features
at runtime, so this is what we want anyway.

BUG=548539

Change-Id: If19b2e380a96918b07bacc300a3a27b885697b99
Reviewed-on: https://boringssl-review.googlesource.com/6380
Reviewed-by: Adam Langley <agl@google.com>
2015-10-28 17:25:25 +00:00
Adam Langley d84b5aec7e Don't build with OPENSSL_SMALL.
This was submitted to check that it worked on all the builders but, in
normal usage, we should build without OPENSSL_SMALL so that everything
is compiled.

Change-Id: I31ac899862e3b31c55bf265a7ec5ff0cc9770b48
2015-10-27 18:34:44 -07:00
Adam Langley de659cdc2e Fix PKCS#8 on 32-bit systems.
The previous commit fixed a signed/unsigned warning but, on 32-bit
systems, long is only 32 bits, so the fix was incorrect there.

Change-Id: I6afe340164de0e176c7f710fcdd095b2a4cddee4
2015-10-27 16:18:51 -07:00
Adam Langley 13f1dd497f Fix a couple more signed/unsigned compares.
Different compilers find different problems.

Change-Id: I732611005ae1cbfcb4bc70c3f98af2c18b0a04da
2015-10-27 16:07:26 -07:00
Adam Langley 96c2a28171 Fix all sign/unsigned warnings with Clang and GCC.
Change-Id: If2a83698236f7b0dcd46701ccd257a85463d6ce5
Reviewed-on: https://boringssl-review.googlesource.com/4992
Reviewed-by: Adam Langley <agl@google.com>
2015-10-27 22:48:00 +00:00
Brian Smith 0dc2a8aee2 Clean up |ECDH_compute_key|.
1. Check for the presence of the private key before allocating or
   computing anything.
2. Check the return value of |BN_CTX_get|.
3. Don't bother computing the Y coordinate since it is not used.
4. Remove conditional logic in cleanup section.

Change-Id: I4d8611603363c7e5d16a8e9f1d6c3a56809f27ae
Reviewed-on: https://boringssl-review.googlesource.com/6171
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-27 17:00:25 +00:00
Brian Smith 274341dd6e Change the type of |EC_GROUP_get_degree| and friends to |unsigned|.
These functions ultimately return the result of |BN_num_bits|, and that
function's return type is |unsigned|. Thus, these functions' return
type should also be |unsigned|.

Change-Id: I2cef63e6f75425857bac71f7c5517ef22ab2296b
Reviewed-on: https://boringssl-review.googlesource.com/6170
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-27 16:48:04 +00:00
David Benjamin e93ffa5da7 Clarify that SSL_get_peer_cert_chain returns the unverified chain.
This came up and I wasn't sure which it was without source-diving.

Change-Id: Ie659096e0f42a7448f81dfb1006c125d292fd7fd
Reviewed-on: https://boringssl-review.googlesource.com/6354
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-27 16:42:30 +00:00
Adam Langley 05ee4fda1c Add no-op functions |CRYPTO_malloc_init| and |ENGINE_load_builtin_engines|.
This reduces the impact on Netty. See
https://github.com/Scottmitch/netty-tcnative/commit/904b84ce41fc44dd1d3955df69912d91906c9877#commitcomment-12159877

Change-Id: I22f9e1edaeb9e721326867ae2b4f3da2c5441437
Reviewed-on: https://boringssl-review.googlesource.com/5535
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-27 16:41:40 +00:00
Adam Langley 2e3c978d14 Add OPENSSL_SMALL.
Intel's P-256 code has very large tables and things like Chromium just
don't need that extra size. However, servers generally do so this change
adds an OPENSSL_SMALL define that currently just drops the 64-bit P-224
but will gate Intel's P-256 in the future too.

Change-Id: I2e55c6e06327fafabef9b96d875069d95c0eea81
Reviewed-on: https://boringssl-review.googlesource.com/6362
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-27 16:40:20 +00:00
Adam Langley 5dbdad9c33 For now, give the unsuffixed ChaCha20 AEAD name to the old version.
QUIC has a complex relationship with BoringSSL owing to it living both
in Chromium and the Google-internal repository. In order for it to
handle the ChaCha20-Poly1305 AEAD switch more easily this change gives
the unsuffixed name to the old AEAD, for now.

Once QUIC has moved to the “_old” version the unsuffixed name can be
given to the new version.

Change-Id: Id8a77be6e3fe2358d78e022413fe088e5a274dca
Reviewed-on: https://boringssl-review.googlesource.com/6361
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-27 16:39:12 +00:00
Brian Smith f0523e9f20 Avoid hard-coded linkage of WNAF-based multiplication.
If the application is only using the P-256 implementation in p256-64.c,
then the WNAF code would all be dead code. The change reorganizes the
code so that all modern toolchains should be able to recognize that
fact and eliminate the WNAF-based code when it is unused.

Change-Id: I9f94bd934ca7d2292de4c29bb89e17c940c7cd2a
Reviewed-on: https://boringssl-review.googlesource.com/6173
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-27 16:38:25 +00:00
Brian Smith 80c5fabc63 Simplify |EC_METHOD| by removing invariant methods.
None of these methods vary per group. Factoring these out of
|EC_METHOD| should help some toolchains to do a better job optimizing
the code for size.

Change-Id: Ibd22a52992b4d549f12a8d22bddfdb3051aaa891
Reviewed-on: https://boringssl-review.googlesource.com/6172
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-27 15:55:47 +00:00
Brian Smith f15e075b73 Add more tests for the RFC 7539 ChaCha20-Poly1305 AEAD.
The tests in crypto/cipher/test/chacha20_poly1305_deprecated_tests.txt
were adapted to the RFC 7539 AEAD construction by recalculating the tags.
Also a few additional vectors were added. These vectors were verified
against nettle. See
https://github.com/briansmith/nettle/commit/feb7292bf19dfc635f126b9f3c0d147cdee30c87.

Change-Id: Ib3f2797d5825bc1e32c55f845b5070b6993e4aff
Reviewed-on: https://boringssl-review.googlesource.com/6144
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-27 01:34:33 +00:00
Brian Smith 271777f5ac Refactor ChaCha20-Poly1305 AEAD nonce handling.
This change reduces unnecessary copying and makes the pre-RFC-7539
nonces 96 bits just like the AES-GCM, AES-CCM, and RFC 7539
ChaCha20-Poly1305 cipher suites. Also, all the symbols related to
the pre-RFC-7539 cipher suites now have "_OLD" appended, in
preparation for adding the RFC 7539 variants.

Change-Id: I1f85bd825b383c3134df0b6214266069ded029ae
Reviewed-on: https://boringssl-review.googlesource.com/6103
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-27 01:01:42 +00:00
Brian Smith 3e23e4cb58 Add the RFC 7539 ChaCha20-Poly1305 AEAD.
Change-Id: I07dfde7cc304d903c2253600905cc3e6257716c5
Reviewed-on: https://boringssl-review.googlesource.com/6101
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-27 00:46:36 +00:00
Brian Smith e80a2ecd0d Change |CRYPTO_chacha_20| to use 96-bit nonces, 32-bit counters.
The new function |CRYPTO_chacha_96_bit_nonce_from_64_bit_nonce| can be
used to adapt code from that uses 64 bit nonces, in a way that is
compatible with the old semantics.

Change-Id: I83d5b2d482e006e82982f58c9f981e8078c3e1b0
Reviewed-on: https://boringssl-review.googlesource.com/6100
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 23:58:46 +00:00
David Benjamin da084a3ebd Fix shared library build on OS X.
It seems OS X actually cares about symbol resolution and dependencies
when you create a dylib. Probably because they do two-level name
resolution.

(Obligatory disclaimer: BoringSSL does not have a stable ABI and is thus
not suitable for a traditional system-wide library.)

BUG=539603

Change-Id: Ic26c4ad23840fe6c1f4825c44671e74dd2e33870
Reviewed-on: https://boringssl-review.googlesource.com/6131
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 23:39:47 +00:00
William Hesse 6dc1851f30 Fix aarch64 (64-bit ARM) guard on chacha_vec_arm.S.
Change-Id: Ia3632639daa8655ea5e2f81ba2a5163949f522b2
Reviewed-on: https://boringssl-review.googlesource.com/6110
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 23:32:38 +00:00
Brian Smith 953cfc837f Document how to regenerate crypto/chacha/chacha_vec_arm.S.
Also, organize the links in BUILDING.md sensibly.

Change-Id: Ie9c65750849fcdab7a6a6bf11d1c9cdafb53bc00
Reviewed-on: https://boringssl-review.googlesource.com/6140
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 23:29:57 +00:00
Adam Langley 0f9f0ead2e Fix the shared builders by exporting GCM symbols.
gcm_test.cc needs to access the internal GCM symbols. This is
unfortunate because it means that they have to be marked OPENSSL_EXPORT
just for this.

To compensate, modes.h is removed and its contents copied into
crypto/modes/internal.h.

Change-Id: I1777b2ef8afd154c43417137673a28598a7ec30e
Reviewed-on: https://boringssl-review.googlesource.com/6360
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 23:26:40 +00:00
David Benjamin 75885e29c4 Revert "Get rid of all compiler version checks in perlasm files."
This reverts commit b9c26014de.

The win64 bot seems unhappy. Will sniff at it tomorrow. In
the meantime, get the tree green again.

Change-Id: I058ddb3ec549beee7eabb2f3f72feb0a4a5143b2
Reviewed-on: https://boringssl-review.googlesource.com/6353
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 23:12:39 +00:00
Brian Smith 0f8bfdeb33 Make |gcm128_context| memcpy-safe.
This removes the confusion about whether |gcm128_context| copies the
key (it didn't) or whether the caller is responsible for keeping the
key alive for the lifetime of the |gcm128_context| (it was).

Change-Id: Ia0ad0a8223e664381fbbfb56570b2545f51cad9f
Reviewed-on: https://boringssl-review.googlesource.com/6053
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 22:05:33 +00:00
Brian Smith 3f3f25d8a2 Fix constness of |gcm128_context.key|.
The key is never modified through the key pointer member, and the
calling code relies on that fact for maintaining its own
const-correctness.

Change-Id: I63946451aa7c400cd127895a61c30d9a647b1b8c
Reviewed-on: https://boringssl-review.googlesource.com/6040
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 21:40:04 +00:00
Brian Smith eca509c8da Clarify confusing conditionals in crypto/gcm/gcm.c.
MSVC was warning about the assignment in the |if| condition. Also, the
formatting of the negative number made it look like a subtraction.
Finally, what was being calculated was unclear.

Change-Id: If56c672302c638aac6a87f715e8dcbb87ecb56ed
Reviewed-on: https://boringssl-review.googlesource.com/6212
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 21:37:00 +00:00
Brian Smith 9383eab5e9 Avoid signed/unsigned comparison in crypto/bn's |probable_prime|.
Change-Id: I768a348e1e34207bca55c7d093c1ba8975e304ab
Reviewed-on: https://boringssl-review.googlesource.com/6213
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 21:27:12 +00:00
Brian Smith 659806d7ff Don't default to SHA-1 in |EVP_DigestSignInit|/|EVP_DigestVerifyInit|.
This removes a hard link-time dependency on the SHA-1 code. The code
was self-contradictory in whether it defaulted to SHA-1 or refused to
default to SHA-1.

Change-Id: I5ad7949bdd529df568904f87870313e3d8a57e72
Reviewed-on: https://boringssl-review.googlesource.com/5833
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 21:26:51 +00:00
Matt Braithwaite e564a5ba6e |assert| → |OPENSSL_STATIC_ASSERT| where possible.
Change-Id: If8643c7308e6c3666de4104d097458187dbe268c
Reviewed-on: https://boringssl-review.googlesource.com/6057
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 21:07:31 +00:00
Matt Braithwaite 29d8adbdc6 Better handle IPv6.
∙ host:port parsing, where unavoidable, is now IPv6-friendly.
  ∙ |BIO_C_GET_CONNECT| is simply removed.
  ∙ bssl -accept now listens on both IPv6 and IPv4.

Change-Id: I1cbd8a79c0199bab3ced4c4fd79d2cc5240f250c
Reviewed-on: https://boringssl-review.googlesource.com/6214
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 21:06:01 +00:00
David Benjamin 301afaf223 Add a run_tests target to run all tests.
It's very annoying having to remember the right incant every time I want
to switch around between my build, build-release, build-asan, etc.,
output directories.

Unfortunately, this target is pretty unfriendly without CMake 3.2+ (and
Ninja 1.5+). This combination gives a USES_TERMINAL flag to
add_custom_target which uses Ninja's "console" pool, otherwise the
output buffering gets in the way. Ubuntu LTS is still on an older CMake,
so do a version check in the meantime.

CMake also has its own test mechanism (CTest), but this doesn't use it.
It seems to prefer knowing what all the tests are and then tries to do
its own output management and parallelizing and such. We already have
our own runners. all_tests.go could actually be converted tidily, but
generate_build_files.py also needs to read it, and runner.go has very
specific needs.

Naming the target ninja -C build test would be nice, but CTest squats
that name and CMake grumps when you use a reserved name, so I've gone
with run_tests.

Change-Id: Ibd20ebd50febe1b4e91bb19921f3bbbd9fbcf66c
Reviewed-on: https://boringssl-review.googlesource.com/6270
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 20:33:44 +00:00
David Benjamin b9c26014de Get rid of all compiler version checks in perlasm files.
Since we pre-generate our perlasm, having the output of these files be
sensitive to the environment the run in is unhelpful. It would be bad to
suddenly change what features we do or don't compile in whenever workstations'
toolchains change.

Enable all compiler-version-gated features as they should all be runtime-gated
anyway. This should align with what upstream's files would have produced on
modern toolschains. We should assume our assemblers can take whatever we'd like
to throw at them. (If it turns out some can't, we'd rather find out and
probably switch the problematic instructions to explicit byte sequences.)

This actually results in a fairly significant change to the assembly we
generate. I'm guessing upstream's buildsystem sets the CC environment variable,
while ours doesn't and so the version checks were all coming out conservative.

diffstat of generated files:

 linux-x86/crypto/sha/sha1-586.S              | 1176 ++++++++++++
 linux-x86/crypto/sha/sha256-586.S            | 2248 ++++++++++++++++++++++++
 linux-x86_64/crypto/bn/rsaz-avx2.S           | 1644 +++++++++++++++++
 linux-x86_64/crypto/bn/rsaz-x86_64.S         |  638 ++++++
 linux-x86_64/crypto/bn/x86_64-mont.S         |  332 +++
 linux-x86_64/crypto/bn/x86_64-mont5.S        | 1130 ++++++++++++
 linux-x86_64/crypto/modes/aesni-gcm-x86_64.S |  754 ++++++++
 linux-x86_64/crypto/modes/ghash-x86_64.S     |  475 +++++
 linux-x86_64/crypto/sha/sha1-x86_64.S        | 1121 ++++++++++++
 linux-x86_64/crypto/sha/sha256-x86_64.S      | 1062 +++++++++++
 linux-x86_64/crypto/sha/sha512-x86_64.S      | 2241 ++++++++++++++++++++++++
 mac-x86/crypto/sha/sha1-586.S                | 1174 ++++++++++++
 mac-x86/crypto/sha/sha256-586.S              | 2248 ++++++++++++++++++++++++
 mac-x86_64/crypto/bn/rsaz-avx2.S             | 1637 +++++++++++++++++
 mac-x86_64/crypto/bn/rsaz-x86_64.S           |  638 ++++++
 mac-x86_64/crypto/bn/x86_64-mont.S           |  331 +++
 mac-x86_64/crypto/bn/x86_64-mont5.S          | 1130 ++++++++++++
 mac-x86_64/crypto/modes/aesni-gcm-x86_64.S   |  750 ++++++++
 mac-x86_64/crypto/modes/ghash-x86_64.S       |  475 +++++
 mac-x86_64/crypto/sha/sha1-x86_64.S          | 1121 ++++++++++++
 mac-x86_64/crypto/sha/sha256-x86_64.S        | 1062 +++++++++++
 mac-x86_64/crypto/sha/sha512-x86_64.S        | 2241 ++++++++++++++++++++++++
 win-x86/crypto/sha/sha1-586.asm              | 1173 ++++++++++++
 win-x86/crypto/sha/sha256-586.asm            | 2248 ++++++++++++++++++++++++
 win-x86_64/crypto/bn/rsaz-avx2.asm           | 1858 +++++++++++++++++++-
 win-x86_64/crypto/bn/rsaz-x86_64.asm         |  638 ++++++
 win-x86_64/crypto/bn/x86_64-mont.asm         |  352 +++
 win-x86_64/crypto/bn/x86_64-mont5.asm        | 1184 ++++++++++++
 win-x86_64/crypto/modes/aesni-gcm-x86_64.asm |  933 ++++++++++
 win-x86_64/crypto/modes/ghash-x86_64.asm     |  515 +++++
 win-x86_64/crypto/sha/sha1-x86_64.asm        | 1152 ++++++++++++
 win-x86_64/crypto/sha/sha256-x86_64.asm      | 1088 +++++++++++
 win-x86_64/crypto/sha/sha512-x86_64.asm      | 2499 ++++++

SHA* gets faster. RSA and AES-GCM seem to be more of a wash and even slower
sometimes!  This is a little concerning. Though when I repeated the latter two,
it's definitely noisy (RSA in particular), so we may wish to repeat in a more
controlled environment. We could also flip some of these toggles to something
other than the highest setting if it seems some of the variants aren't
desirable. We just shouldn't have them enabled or disabled on accident. This
aligns us closer to upstream though.

$ /tmp/bssl.old speed SHA-
Did 5028000 SHA-1 (16 bytes) operations in 1000048us (5027758.7 ops/sec): 80.4 MB/s
Did 1708000 SHA-1 (256 bytes) operations in 1000257us (1707561.2 ops/sec): 437.1 MB/s
Did 73000 SHA-1 (8192 bytes) operations in 1008406us (72391.5 ops/sec): 593.0 MB/s
Did 3041000 SHA-256 (16 bytes) operations in 1000311us (3040054.5 ops/sec): 48.6 MB/s
Did 779000 SHA-256 (256 bytes) operations in 1000820us (778361.7 ops/sec): 199.3 MB/s
Did 26000 SHA-256 (8192 bytes) operations in 1009875us (25745.8 ops/sec): 210.9 MB/s
Did 1837000 SHA-512 (16 bytes) operations in 1000251us (1836539.0 ops/sec): 29.4 MB/s
Did 803000 SHA-512 (256 bytes) operations in 1000969us (802222.6 ops/sec): 205.4 MB/s
Did 41000 SHA-512 (8192 bytes) operations in 1016768us (40323.8 ops/sec): 330.3 MB/s
$ /tmp/bssl.new speed SHA-
Did 5354000 SHA-1 (16 bytes) operations in 1000104us (5353443.2 ops/sec): 85.7 MB/s
Did 1779000 SHA-1 (256 bytes) operations in 1000121us (1778784.8 ops/sec): 455.4 MB/s
Did 87000 SHA-1 (8192 bytes) operations in 1012641us (85914.0 ops/sec): 703.8 MB/s
Did 3517000 SHA-256 (16 bytes) operations in 1000114us (3516599.1 ops/sec): 56.3 MB/s
Did 935000 SHA-256 (256 bytes) operations in 1000096us (934910.2 ops/sec): 239.3 MB/s
Did 38000 SHA-256 (8192 bytes) operations in 1004476us (37830.7 ops/sec): 309.9 MB/s
Did 2930000 SHA-512 (16 bytes) operations in 1000259us (2929241.3 ops/sec): 46.9 MB/s
Did 1008000 SHA-512 (256 bytes) operations in 1000509us (1007487.2 ops/sec): 257.9 MB/s
Did 45000 SHA-512 (8192 bytes) operations in 1000593us (44973.3 ops/sec): 368.4 MB/s

$ /tmp/bssl.old speed RSA
Did 820 RSA 2048 signing operations in 1017008us (806.3 ops/sec)
Did 27000 RSA 2048 verify operations in 1015400us (26590.5 ops/sec)
Did 1292 RSA 2048 (3 prime, e=3) signing operations in 1008185us (1281.5 ops/sec)
Did 65000 RSA 2048 (3 prime, e=3) verify operations in 1011388us (64268.1 ops/sec)
Did 120 RSA 4096 signing operations in 1061027us (113.1 ops/sec)
Did 8208 RSA 4096 verify operations in 1002717us (8185.8 ops/sec)
$ /tmp/bssl.new speed RSA
Did 760 RSA 2048 signing operations in 1003351us (757.5 ops/sec)
Did 25900 RSA 2048 verify operations in 1028931us (25171.8 ops/sec)
Did 1320 RSA 2048 (3 prime, e=3) signing operations in 1040806us (1268.2 ops/sec)
Did 63000 RSA 2048 (3 prime, e=3) verify operations in 1016042us (62005.3 ops/sec)
Did 104 RSA 4096 signing operations in 1008718us (103.1 ops/sec)
Did 6875 RSA 4096 verify operations in 1093441us (6287.5 ops/sec)

$ /tmp/bssl.old speed GCM
Did 5316000 AES-128-GCM (16 bytes) seal operations in 1000082us (5315564.1 ops/sec): 85.0 MB/s
Did 712000 AES-128-GCM (1350 bytes) seal operations in 1000252us (711820.6 ops/sec): 961.0 MB/s
Did 149000 AES-128-GCM (8192 bytes) seal operations in 1003182us (148527.4 ops/sec): 1216.7 MB/s
Did 5919750 AES-256-GCM (16 bytes) seal operations in 1000016us (5919655.3 ops/sec): 94.7 MB/s
Did 800000 AES-256-GCM (1350 bytes) seal operations in 1000951us (799239.9 ops/sec): 1079.0 MB/s
Did 152000 AES-256-GCM (8192 bytes) seal operations in 1000765us (151883.8 ops/sec): 1244.2 MB/s
$ /tmp/bssl.new speed GCM
Did 5315000 AES-128-GCM (16 bytes) seal operations in 1000125us (5314335.7 ops/sec): 85.0 MB/s
Did 755000 AES-128-GCM (1350 bytes) seal operations in 1000878us (754337.7 ops/sec): 1018.4 MB/s
Did 151000 AES-128-GCM (8192 bytes) seal operations in 1005655us (150150.9 ops/sec): 1230.0 MB/s
Did 5913500 AES-256-GCM (16 bytes) seal operations in 1000041us (5913257.6 ops/sec): 94.6 MB/s
Did 782000 AES-256-GCM (1350 bytes) seal operations in 1001484us (780841.2 ops/sec): 1054.1 MB/s
Did 121000 AES-256-GCM (8192 bytes) seal operations in 1006389us (120231.8 ops/sec): 984.9 MB/s

Change-Id: I0efb32f896c597abc7d7e55c31d038528a5c72a1
Reviewed-on: https://boringssl-review.googlesource.com/6260
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 20:31:30 +00:00
David Benjamin e189c86bc7 Consistently disable the Intel SHA Extensions code.
We haven't tested it yet, but it was only disabled on 64-bit. Disable it on
32-bit as well until we're ready to turn it on.

Change-Id: I50e74aef2c5c3ba539a868c2bb6fb90fdf28a5f0
Reviewed-on: https://boringssl-review.googlesource.com/6271
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 20:27:52 +00:00
David Benjamin 178a88c26f Synchronize sha512-x86_64.pl with upstream.
We missed 7eb9680ae1bf5dd9aeb61c401f2c3bd900ac9aeb. This is a no-op as we don't
set shaext right now anyway. This also includes some cosmetic changes to
minimize the diff with upstream. ("cosmetic". Upstream's perl doesn't like
spaces.)

Change-Id: I17fa663ddaa38c27854d4f59fb83960528d9ba78
Reviewed-on: https://boringssl-review.googlesource.com/6250
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 20:27:28 +00:00
David Benjamin ccf25177bd Only emit RSA_R_BAD_VERSION on bad RSAPrivateKey versions.
I was a little bit too lazy in error handling here.

Change-Id: I9954957d41d610e715c1976a921dedeb8cb49d40
Reviewed-on: https://boringssl-review.googlesource.com/6240
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 20:27:01 +00:00
nagendra modadugu 3398dbf279 Add server-side support for asynchronous RSA decryption.
Change-Id: I6df623f3e9bc88acc52043f16b34649b7af67663
Reviewed-on: https://boringssl-review.googlesource.com/5531
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 20:26:20 +00:00
David Benjamin 091c4b9869 Add an option to disable NPN on a per-SSL basis.
Right whether NPN is advertised can only be configured globally on the SSL_CTX.
Rather than adding two pointers to each SSL*, add an options bit to disable it
so we may plumb in a field trial to disable NPN.

Chromium wants to be able to route a bit in to disable NPN, but it uses SSL_CTX
incorrectly and has a global one, so it can't disconnect the callback. (That
really needs to get fixed. Although it's not clear this necessarily wants to be
lifted up to SSL_CTX as far as Chromium's SSLClientSocket is concerned since
NPN doesn't interact with the session cache.)

BUG=526713

Change-Id: I49c86828b963eb341c6ea6a442557b7dfa190ed3
Reviewed-on: https://boringssl-review.googlesource.com/6351
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 19:56:52 +00:00
David Benjamin ff905b09fc Avoid sticking -1 into a size_t.
There's still a size_t/int cast due to the mass of legacy code, but at
least avoid the most egregious case.

Change-Id: Icc1741366e09190216e762ca7ef42ecfc3215edc
Reviewed-on: https://boringssl-review.googlesource.com/6345
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 19:50:53 +00:00
David Benjamin 0a870c2f7e Correctly free SSL_SESSIONs in ssl_test.
That was silly.

Change-Id: I375c04f725cbb75f9e04fce386e20c4de5e7ae0c
Reviewed-on: https://boringssl-review.googlesource.com/6352
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 19:49:16 +00:00
David Benjamin 12f7737d32 Remove BN_MONT_CTX_init.
One less exported function. Nothing ever stack-allocates them, within BoringSSL
or in consumers. This avoids the slightly odd mechanism where BN_MONT_CTX_free
might or might not free the BN_MONT_CTX itself based on a flag.

(This is also consistent with OpenSSL 1.1.x which does away with the _init
variants of both this and BIGNUM so it shouldn't be a compatibility concern
long-term either.)

Change-Id: Id885ae35a26f75686cc68a8aa971e2ea6767ba88
Reviewed-on: https://boringssl-review.googlesource.com/6350
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 19:47:26 +00:00
David Benjamin 911cfb7e6e Unnecessary NULL checks.
Missed a few the last time around.

Change-Id: I42fd57566d64fa1c41cba14573742d42468cc07d
Reviewed-on: https://boringssl-review.googlesource.com/6349
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 19:45:25 +00:00
David Benjamin 17dd904eb9 do_dirname: Don't change gen on failures
It would set gen->d.dirn to a freed pointer in case X509V3_NAME_from_section
failed.

(Imported from upstream's ea9de25f2f577db69d67c39e5cf60be7da17c931.)

This only affects the various config file parsing bits.

Change-Id: I530c09be81bfb40bca931c064c39cbc93dfd454f
Reviewed-on: https://boringssl-review.googlesource.com/6348
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 19:44:09 +00:00
David Benjamin dc4a554b2c Remove dead code in x509_lu.c.
See also upstream's b62a2f8a373d1889672599834acf95161f2883ce, though
upstream left the lock calls in by accident. Otherwise, the change
appears to be correct. I see no side effects of x509_object_idx_cnt
beyond the return value and *pnmatch, both of which are discarded.

Change-Id: Ic2124a733a61591bd1b264164726ce6c69ce10c9
Reviewed-on: https://boringssl-review.googlesource.com/6347
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 19:41:58 +00:00
David Benjamin 79680ffaed Fix various malloc failure codepaths.
CRYPTO_MUTEX_init needs a CRYPTO_MUTEX_cleanup. Also a pile of problems
with x509_lu.c I noticed trying to import some upstream change.

Change-Id: I029a65cd2d30aa31f4832e8fbfe5b2ea0dbc66fe
Reviewed-on: https://boringssl-review.googlesource.com/6346
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 19:41:01 +00:00
David Benjamin 68b4e8933e Slightly simplify some DSA logic.
See also upstream's b62a2f8a373d1889672599834acf95161f2883ce.

Change-Id: I430be5ec21198484b8a874460b224e15bafafe48
Reviewed-on: https://boringssl-review.googlesource.com/6344
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 19:28:50 +00:00
David Benjamin 471abb1f21 Update PORTING.md for the new renego API.
SSL_set_renegotiate_mode to avoid my original double-negative confusion.

Change-Id: I23537aeac53c4969fd81307a676f33d6768da55f
Reviewed-on: https://boringssl-review.googlesource.com/6322
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 19:27:56 +00:00
David Benjamin 1269ddd377 Never use the internal session cache for a client.
The internal session cache is keyed on session ID, so this is completely
useless for clients (indeed we never look it up internally). Along the way,
tidy up ssl_update_cache to be more readable. The slight behavior change is
that SSL_CTX_add_session's return code no longer controls the external
callback. It's not clear to me what that could have accomplished. (It can only
fail on allocation error. We only call it for new sessions, so the duplicate
case is impossible.)

The one thing of value the internal cache might have provided is managing the
timeout. The SSL_CTX_flush_sessions logic would flip the not_resumable bit and
cause us not to offer expired sessions (modulo SSL_CTX_flush_sessions's delay
and any discrepancies between the two caches). Instead, just check expiration
when deciding whether or not to offer a session.

This way clients that set SSL_SESS_CACHE_CLIENT blindly don't accidentally
consume gobs of memory.

BUG=531194

Change-Id: If97485beab21874f37737edc44df24e61ce23705
Reviewed-on: https://boringssl-review.googlesource.com/6321
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 19:27:28 +00:00
David Benjamin 415660b26b Tidy up SSL_CTX_add_session.
The original logic was rather confusing.

Change-Id: I097e57817ea8ec2dd65a413c8751fba1682e928b
Reviewed-on: https://boringssl-review.googlesource.com/6320
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 19:22:40 +00:00
David Benjamin 0f653957c1 Add tests for the internal session cache behavior.
In doing so, fix the documentation for SSL_CTX_add_session and
SSL_CTX_remove_session. I misread the code and documented the behavior
on session ID collision wrong.

Change-Id: I6f364305e1f092b9eb0b1402962fd04577269d30
Reviewed-on: https://boringssl-review.googlesource.com/6319
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 19:18:44 +00:00
David Benjamin dc2aea2231 Remove all the logic around custom session IDs and retrying on collisions.
A random 32-byte (so 256-bit) session ID is never going to collide with
an existing one. (And, if it does, SSL_CTX_add_session does account for
this, so the server won't explode. Just attempting to resume some
session will fail.)

That logic didn't completely work anyway as it didn't account for
external session caches or multiple connections picking the same ID in
parallel (generation and insertion happen at different times) or
multiple servers sharing one cache. In theory one could fix this by
passing in a sufficiently clever generate_session_id, but no one does
that.

I found no callers of these functions, so just remove them altogether.

Change-Id: I8500c592cf4676de6d7194d611b99e9e76f150a7
Reviewed-on: https://boringssl-review.googlesource.com/6318
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 19:00:14 +00:00
David Benjamin 60be027625 Style: fix some header guards
Change-Id: I86c30c7fe489c720f83f744696df0a0a20268531
Reviewed-on: https://boringssl-review.googlesource.com/6317
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 18:47:51 +00:00
David Benjamin f91fa5cfc6 Documentation typo.
Change-Id: Iedcba0ac15bc14def9c2dc2407ed29d130133c0c
Reviewed-on: https://boringssl-review.googlesource.com/6315
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 18:47:31 +00:00
David Benjamin dfa9c4a074 Linkify pipe words.
This required switching anchors from <a name> to id attributes, which
also works. HTML gets unhappy when you nest <a> tags inside each other
and tagging the elements is somewhat tidier.

Change-Id: I64094d35a0e820e37be9e5dc8db013a50774190f
Reviewed-on: https://boringssl-review.googlesource.com/6314
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 18:46:53 +00:00
David Benjamin 5ef619ef2a Hide some sections from the docs.
Private structs shouldn't be shown. Also there's a few sections that are
really more implementation details than anything else.

Change-Id: Ibc5a23ba818ab0531d9c68e7ce348f1eabbcd19a
Reviewed-on: https://boringssl-review.googlesource.com/6313
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 18:44:27 +00:00
David Benjamin 63006a913b Document the rest of ssl.h.
Although Chromium actually uses SSL_(get_)state as part of its fallback
reason heuristic, that function really should go in the deprecated
bucket. I kept SSL_state_string_long since having a human-readable
string is probably useful for logging.

SSL_set_SSL_CTX was only half-documented as the behavior of this
function is very weird. This warrants further investigation and
rethinking.

SSL_set_shutdown is absurd. I added an assert to trip up clearing bits
and set it to a bitwise OR since clearing bits may mess up the state
machine. Otherwise there's enough consumers and it's not quite the same
as SSL_CTX_set_quiet_shutdown that I've left it alone for now.

Change-Id: Ie35850529373a5a795f6eb04222668ff76d84aaa
Reviewed-on: https://boringssl-review.googlesource.com/6312
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 18:43:38 +00:00
David Benjamin 7a1eefd3cd Deprecate SSL_library_init.
It just calls CRYPTO_library_init and doesn't do anything else. If
anything, I'd like to make CRYPTO_library_init completely go away too.
We have CRYPTO_once now, so I think it's safe to assume that, if ssl/
ever grows initialization needs beyond that of crypto/, we can hide it
behind a CRYPTO_once and not burden callers.

Change-Id: I63dc362e0e9e98deec5516f4620d1672151a91b6
Reviewed-on: https://boringssl-review.googlesource.com/6311
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 18:36:23 +00:00
David Benjamin 5d8b128095 Document the (formerly) SSL_state wrapper macros.
SSL_in_connect_init and SSL_in_accept_init are removed as they're unused
both within the library and externally. They're also kind of silly.

Expand on how False Start works at the API level in doing so.

Change-Id: Id2a8e34b5bb8f28329e3b87b4c64d41be3f72410
Reviewed-on: https://boringssl-review.googlesource.com/6310
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 18:35:01 +00:00
David Benjamin 449c3c7b7b Take some definitions out of the Android compatibility layer.
They were since added to crypto.h and implemented in the library proper.

Change-Id: Idaa2fe2d9b213e67cf7ef61ff8bfc636dfa1ef1f
Reviewed-on: https://boringssl-review.googlesource.com/6309
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 18:33:10 +00:00
David Benjamin 6e0c17aa3a Private (and deprecated) types.
Change-Id: Ia66e485cb2de45c9fb0a1ecd9a703863ad24d9c9
Reviewed-on: https://boringssl-review.googlesource.com/6308
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 18:32:35 +00:00
David Benjamin da86cccaf6 Deprecate all the string macros.
They're really not all that helpful, considering they're each used
exactly once. They're also confusing as it is ALMOST the case that
SSL_TXT_FOO expands to "FOO", but SSL_TXT_AES_GCM expand "AESGCM" and
the protocol versions have lowercase v's and dots.

Change-Id: If78ad8edb0c024819219f61675c60c2a7f3a36b0
Reviewed-on: https://boringssl-review.googlesource.com/6307
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 18:15:33 +00:00
David Benjamin 6d5ea9225d Private constants are private.
Change-Id: Id20fcf357d4a0fc28734a7f2ea1fe077d4b34f1e
Reviewed-on: https://boringssl-review.googlesource.com/6306
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 18:12:57 +00:00
David Benjamin 82170248e7 Document the info callback.
This callback is some combination of arguably useful stuff (bracket
handshakes, alerts) and completely insane things (find out when the
state machine advances). Deprecate the latter.

Change-Id: Ibea5b32cb360b767b0f45b302fd5f1fe17850593
Reviewed-on: https://boringssl-review.googlesource.com/6305
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 18:12:22 +00:00
David Benjamin 1b92f64b71 Fix comment style in crypto/rand/rand.c.
This compiled, so I guess everything we care about can do C++-style
comments, but better be uniform.

Change-Id: I9950c2df93cd81bb2bddb3a1e14e2de02c7e4807
Reviewed-on: https://boringssl-review.googlesource.com/6304
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 17:58:08 +00:00
David Benjamin 7227990ef1 More SSL_SESSION serialization functions.
Change-Id: I2dd8d073521a230b2b0c4e74ec3d6eeb4899623e
Reviewed-on: https://boringssl-review.googlesource.com/6303
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 17:57:50 +00:00
David Benjamin 066fe0a679 Document fd-based SSL APIs.
Also clean up the code slightly.

Change-Id: I066a389242c46cdc7d41b1ae9537c4b7716c92a2
Reviewed-on: https://boringssl-review.googlesource.com/6302
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 17:56:25 +00:00
David Benjamin cef1eb4c1c Put renego functions together.
Change-Id: I3bfbf90a790a10e4464e0e39bbd7c0c2bee9fe35
Reviewed-on: https://boringssl-review.googlesource.com/6301
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 17:52:22 +00:00
David Benjamin d5635d476c Fix ssl3.h / ssl.h circular dependency.
Like tls1.h, ssl3.h is now just a bundle of protocol constants.
Hopefully we can opaquify this struct in due time, but for now it's
still public.

Change-Id: I68366eb233702e149c92e21297f70f8a4a45f060
Reviewed-on: https://boringssl-review.googlesource.com/6300
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 17:50:32 +00:00
David Benjamin 8370bfd6d1 Remove unhelpful warning about changing state numbers.
This dates all the way to SSLeay 0.9.0b. At this point the
application/handshake interleave logic in ssl3_read_bytes was already
present:

((
  (s->state & SSL_ST_CONNECT) &&
  (s->state >= SSL3_ST_CW_CLNT_HELLO_A) &&
  (s->state <= SSL3_ST_CR_SRVR_HELLO_A)
 ) || (
  (s->state & SSL_ST_ACCEPT) &&
  (s->state <= SSL3_ST_SW_HELLO_REQ_A) &&
  (s->state >= SSL3_ST_SR_CLNT_HELLO_A)
 )

The comment is attached to SSL3_ST_SR_CLNT_HELLO_A, so I suspect this is
what it was about. This logic is gone now, so let's remove that scary
warning.

Change-Id: I45f13b53b79e35d80e6074b0942600434deb0684
Reviewed-on: https://boringssl-review.googlesource.com/6299
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 17:48:57 +00:00
David Benjamin 9f6b5266d9 Fix typo.
(Imported from upstream's ec3a7c9b3729cd45c550222556100666aedc5bbc.)

Change-Id: I9f281fc03e6ece628d46344cf2c0850dd3bcd703
Reviewed-on: https://boringssl-review.googlesource.com/6343
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 17:48:24 +00:00
David Benjamin 036152e6a5 Fix incorrect error-handling in BN_div_recp.
See upstream's e90f1d9b74275c11e3492e521e46f4b1afa6f883.

Change-Id: I68470acb97dac59e586b1c72aad50de6bd0156cb
Reviewed-on: https://boringssl-review.googlesource.com/6342
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 17:48:10 +00:00
David Benjamin 0ea470fdb2 Fix self-signed handling.
Don't mark a certificate as self-signed if keyUsage is present and
certificate signing is not asserted.

PR#3979

(Imported from upstream's e272f8ef8f63298466494adcd29512797ab1eece.)

Change-Id: I3120832f32455e8e099708fa2491d85d3d4a3930
Reviewed-on: https://boringssl-review.googlesource.com/6341
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 17:46:22 +00:00
David Benjamin dd6fed9704 Explicitly handle empty NewSessionTickets on the client.
RFC 5077 explicitly allows the server to change its mind and send no
ticket by sending an empty NewSessionTicket. See also upstream's
21b538d616b388fa0ce64ef54da3504253895cf8.

CBS_stow handles this case somewhat, so we won't get confused about
malloc(0) as upstream did. But we'll still fill in a bogus SHA-256
session ID, cache the session, and send a ClientHello with bogus session
ID but empty ticket extension. (The session ID field changes meaning
significantly when the ticket is or isn't empty. Non-empty means "ignore
the session ID, but echo if it resuming" while empty means "I support
tickets, but am offering this session ID".

The other behavior change is that a server which changes its mind on a
resumption handshake will no longer override the client's session cache
with a ticket-less session.

(This is kind of silly. Given that we don't get completely confused due
to CBS_stow, it might not be worth bothering with the rest. Mostly it
bugged me that we send an indicator session ID with no ticket.)

Change-Id: Id6b5bde1fe51aa3e1f453a948e59bfd1e2502db6
Reviewed-on: https://boringssl-review.googlesource.com/6340
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 17:44:54 +00:00
David Benjamin 07e138425d Move remaining functions out of tls1.h.
Now tls1.h is just a pile of protocol constants with no more circular
dependency problem.

I've preserved SSL_get_servername's behavior where it's simultaneously a
lookup of handshake state and local configuration.  I've removed it from
SSL_get_servername_type. It got the logic wrong anyway with the order of
the s->session check.

(Searching through code, neither is used on the client, but the
SSL_get_servername one is easy.)

Change-Id: I61bb8fb0858b07d76a7835bffa6dc793812fb027
Reviewed-on: https://boringssl-review.googlesource.com/6298
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-26 17:38:40 +00:00
Adam Langley 10a1a9d32e Update references to the padding draft.
The padding draft is now RFC 7685:
https://www.rfc-editor.org/rfc/rfc7685.txt

Change-Id: I26945b10e7923e75c016232c663baac11c4389ae
2015-10-21 14:49:23 -07:00
Adam Langley 6a7cfbe06a Allow ARM capabilities to be set at compile time.
Some ARM environments don't support |getauxval| or signals and need to
configure the capabilities of the chip at compile time. This change adds
defines that allow them to do so.

Change-Id: I4e6987f69dd13444029bc7ac7ed4dbf8fb1faa76
Reviewed-on: https://boringssl-review.googlesource.com/6280
Reviewed-by: Adam Langley <agl@google.com>
2015-10-20 22:40:15 +00:00
David Benjamin c2ae53db6d Document alert handling.
SSL_alert_desc_string_long was kept in the undeprecated bucket and one missing
alert was added. We have some uses and it's not completely ridiculous for
logging purposes.

The two-character one is ridiculous though and gets turned into a stub
that returns a constant string ("!" or "!!") because M2Crypto expects
it.

Change-Id: Iaf8794b5d953630216278536236c7113655180af
Reviewed-on: https://boringssl-review.googlesource.com/6297
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-20 19:03:24 +00:00
David Benjamin b86847c24b Clean up ssl_stat.c slightly.
(Documentation/deprecation will come in later commits.)

Change-Id: I3aba26e32b2e47a1afb5cedd44d09115fc193bce
Reviewed-on: https://boringssl-review.googlesource.com/6296
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-20 18:49:51 +00:00
David Benjamin 1a1b34d759 Deprecate SSL_get_(peer_)finished.
The only reason you'd want it is to tls_unique, and we have a better API
for that. (It has one caller and that is indeed what that caller uses it
for.)

Change-Id: I39f8e353f56f18becb63dd6f7205ad31f4192bfd
Reviewed-on: https://boringssl-review.googlesource.com/6295
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-20 18:48:41 +00:00
David Benjamin 93d17499e9 Deprecate SSL_want*.
This is redundant with SSL_get_error. Neither is very good API, but
SSL_get_error is more common. SSL_get_error also takes a return code
which makes it harder to accidentally call it at some a point other than
immediately after an operation. (Any other point is confusing since you
can have SSL_read and SSL_write operations going on in parallel and
they'll get mixed up.)

Change-Id: I5818527c30daac28edb552c6c550c05c8580292d
Reviewed-on: https://boringssl-review.googlesource.com/6294
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-20 18:42:15 +00:00
David Benjamin 7f393f72a5 Unexport SSL_SESSION_ASN1_VERSION.
It's pretty clearly pointless to put in the public header.

Change-Id: I9527aba09b618f957618e653c4f2ae379ddd0fdb
Reviewed-on: https://boringssl-review.googlesource.com/6293
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-20 18:41:08 +00:00
David Benjamin 79a0589dc4 Ditch remaining filename comments from public headers and ssl/
Change-Id: I8fc795d18aacb0c929b82e7d58514b22103e2106
Reviewed-on: https://boringssl-review.googlesource.com/6292
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-20 18:40:05 +00:00
David Benjamin d4c2bceaab Document early callback functions.
Also added a SSL_CTX_set_select_certificate_cb setter for
select_certificate_cb so code needn't access SSL_CTX directly. Plus it
serves as a convenient anchor for the documentation.

Change-Id: I23755b910e1d77d4bea7bb9103961181dd3c5efe
Reviewed-on: https://boringssl-review.googlesource.com/6291
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-20 18:29:33 +00:00
David Benjamin cfdee213f8 Add use counters for SSL_OP_TLS_D5_BUG and SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER.
These are theh two remaining quirks (SSL_OP_LEGACY_SERVER_CONNECT
aside). Add counters so we can determine whether there are still clients
that trip up these cases.

Change-Id: I7e92f42f3830c1df675445ec15a852e5659eb499
Reviewed-on: https://boringssl-review.googlesource.com/6290
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-20 18:22:47 +00:00
David Benjamin 96e97b1bf1 Convert ssl3_send_channel_id to CBB.
In doing so, simplify the mess around serializing the public key.
Channel ID specifies that you write x and y concatenated. Rather than
using the X9.62 serialization and chopping bits off, get the affine
coordinates and write them out in the same way we write r and s.

Also unify the P-256 sanity check around SSL_set1_tls_channel_id and
actually check the curve NID.

BUG=468889

Change-Id: I228877b736c9722e368d315064ce3ae6893adfc0
Reviewed-on: https://boringssl-review.googlesource.com/6201
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-20 18:16:46 +00:00
David Benjamin e97b96224c Convert ssl3_send_next_proto to CBB.
BUG=468889

Change-Id: I841b2816ba47c8c1129e333012272902a52cafd3
Reviewed-on: https://boringssl-review.googlesource.com/6200
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-20 18:08:28 +00:00
David Benjamin 5638046cd7 Convert ssl3_send_server_hello to CBB.
BUG=468889

Change-Id: I899d67addbff01c64175f47b19ca2b688626405b
Reviewed-on: https://boringssl-review.googlesource.com/6191
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-20 18:04:48 +00:00
David Benjamin e8d53508ca Convert ssl3_send_client_hello to CBB.
Start converting the ones we can right now. Some of the messier ones
resize init_buf rather than assume the initial size is sufficient, so
those will probably wait until init_buf is gone and the handshake's
undergone some more invasive surgery. The async ones will also require
some thought. But some can be incrementally converted now.

BUG=468889

Change-Id: I0bc22e4dca37d9d671a488c42eba864c51933638
Reviewed-on: https://boringssl-review.googlesource.com/6190
Reviewed-by: Adam Langley <alangley@gmail.com>
2015-10-20 17:56:19 +00:00
Matt Braithwaite 978f16ea08 size_t RSA functions.
This extends 79c59a30 to |RSA_public_encrypt|, |RSA_private_encrypt|,
and |RSA_public_decrypt|.  It benefits Conscrypt, which expects these
functions to have the same signature as |RSA_public_private_decrypt|.

Change-Id: Id1ce3118e8f20a9f43fd4f7bfc478c72a0c64e4b
Reviewed-on: https://boringssl-review.googlesource.com/6286
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-10-19 23:54:47 +00:00
Eric Roman 63fa118f3a Reject iterations=0 when calling PKCS5_PBKDF2_HMAC().
BUG=https://crbug.com/534961

Change-Id: I69e2434bf8d5564711863c393ee3bafe3763cf24
Reviewed-on: https://boringssl-review.googlesource.com/5932
Reviewed-by: Adam Langley <agl@google.com>
2015-10-13 19:40:55 +00:00
David Benjamin c617413527 Remove SSL_SESSION_print*.
It's missing fields and no one ever calls it.

Change-Id: I450edc1e29bb48edffb5fd3df8da19a03e4185ce
Reviewed-on: https://boringssl-review.googlesource.com/5821
Reviewed-by: Adam Langley <agl@google.com>
2015-10-13 19:24:14 +00:00
Brian Smith e5ae760a96 Silence MSVC warning C4210.
The warning is:

    C4210: nonstandard extension used : function given file scope.

It is caused by function declarations that aren't at the top level in a
file.

Change-Id: Ib1c2ae64e15e66eb0a7255a29c0e560fbf55c2b2
Reviewed-on: https://boringssl-review.googlesource.com/6210
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-10-13 18:20:29 +00:00
David Benjamin b735b1b6e4 Document that SSL_CTX_sess_set_get_cb's id parameter should be const.
See also upstream's bf0fc41266f17311c5db1e0541d3dd12eb27deb6.

Change-Id: Ib692b0ad608f2e3291f2aeab2ad98a7e177d5851
Reviewed-on: https://boringssl-review.googlesource.com/6150
Reviewed-by: Adam Langley <agl@google.com>
2015-10-13 18:19:28 +00:00
David Benjamin f88b81aa75 Put OCSP and SCT accessors with SSL_get_peer_certificate.
Grouping along two axes is weird. Doesn't hugely matter which one, but
we should be consistent.

Change-Id: I80fb04d3eff739c08fda29515ce81d101d8542cb
Reviewed-on: https://boringssl-review.googlesource.com/6120
Reviewed-by: Adam Langley <agl@google.com>
2015-10-13 18:19:06 +00:00
David Benjamin 8ac00cafbf Document DTLS-specific retransmit and MTU functions.
The caller obligations for retransmit are messy, so I've peppered a few
other functions with mentions of it. There's only three functions, so
they're lumped in with the other core functions. They're irrelevant for
TLS, but important for DTLS.

Change-Id: Ifc995390952eef81370b58276915dcbe4fc7e3b5
Reviewed-on: https://boringssl-review.googlesource.com/6093
Reviewed-by: Adam Langley <agl@google.com>
2015-10-13 18:18:54 +00:00
David Benjamin fd8e69f26d Better document the callbacks around client certificates.
Deprecate the client_cert_cb variant since you can't really configure
intermediates with it. (You might be able to by configuring the
intermediates without the leaf or key and leaving the SSL stack to
configure those, but that's really weird. cert_cb is simpler.)

Also document the two functions the callbacks may use to query the
CertificateRequest on the client.

Change-Id: Iad6076266fd798cd74ea4e09978e7f5df5c8a670
Reviewed-on: https://boringssl-review.googlesource.com/6092
Reviewed-by: Adam Langley <agl@google.com>
2015-10-13 18:18:40 +00:00
David Benjamin 9f85949baf Document a few more miscellaneous things.
Change-Id: Ib4829bf9344341e3d4fe90c7cea66e217366fe97
Reviewed-on: https://boringssl-review.googlesource.com/6091
Reviewed-by: Adam Langley <agl@google.com>
2015-10-13 18:18:19 +00:00
David Benjamin 9f4913f4a8 Remove the ifdef around ec.h's ec_key.h compatibility include
It doesn't actually do anything.

Change-Id: I8a5748dc86b842406cc656a5b251e1a7c0092377
Reviewed-on: https://boringssl-review.googlesource.com/6090
Reviewed-by: Adam Langley <alangley@gmail.com>
Reviewed-by: Adam Langley <agl@google.com>
2015-10-13 18:14:52 +00:00
Brian Smith a655c73b93 Switch rsa_test.cc to use new RSA private key parsing API.
Change-Id: I48885402b88309bb514554d209e1827d31738756
Reviewed-on: https://boringssl-review.googlesource.com/6211
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <alangley@gmail.com>
Reviewed-by: Adam Langley <agl@google.com>
2015-10-13 18:14:41 +00:00
Brian Smith b8c1446c1f Fix comment typo in poly1305_test.txt.
Change-Id: Id7391502f08651d018d88400057b18aae9e514e3
Reviewed-on: https://boringssl-review.googlesource.com/6102
Reviewed-by: Adam Langley <alangley@gmail.com>
Reviewed-by: Adam Langley <agl@google.com>
2015-10-13 18:14:26 +00:00
David Benjamin 03bad147b6 Links in README.md, take two.
gitiles seems to mangle the links when viewed from
https://boringssl.googlesource.com/boringssl/+/master/README.md, but not
https://boringssl.googlesource.com/boringssl/.

This document suggests that it handles absolute and relative links to files
specially. I guess it didn't interpret 'README.md' as either and failed to adjust
it accordingly. Let's see if this works instead.

https://gerrit.googlesource.com/gitiles/+/master/Documentation/markdown.md#Links

Change-Id: Ic181919140f968c88c69ea8f3c21c70f63e4b467
Reviewed-on: https://boringssl-review.googlesource.com/6230
Reviewed-by: Adam Langley <agl@google.com>
2015-10-13 18:04:43 +00:00
David Benjamin 1d5ef3bb1e Add SSL_set_renegotiate_mode.
Add a slightly richer API. Notably, one can configure ssl_renegotiate_once to
only accept the first renego.

Also, this API doesn't repeat the mistake I made with
SSL_set_reject_peer_renegotiations which is super-confusing with the negation.

Change-Id: I7eb5d534e3e6c553b641793f4677fe5a56451c71
Reviewed-on: https://boringssl-review.googlesource.com/6221
Reviewed-by: Adam Langley <agl@google.com>
2015-10-13 18:02:28 +00:00
David Benjamin 324dce4fd7 Unbreak SSL_total_renegotiations.
The logic to update that got removed in
https://boringssl-review.googlesource.com/4825. Add tests.

Change-Id: Idc550e8fa3ce6f69a76fa65d7651adde281edba6
Reviewed-on: https://boringssl-review.googlesource.com/6220
Reviewed-by: Matt Braithwaite <mab@google.com>
Reviewed-by: Adam Langley <alangley@gmail.com>
Reviewed-by: Adam Langley <agl@google.com>
2015-10-13 17:53:30 +00:00
Adam Langley 6a2c512a7b Add a README.
Change-Id: I77b1d0efa6cddfcb162be693d53276822780540f
Reviewed-on: https://boringssl-review.googlesource.com/5790
Reviewed-by: Adam Langley <agl@google.com>
2015-10-13 17:52:28 +00:00
David Benjamin 617eac6a21 Align BIO_get_fd with upstream.
OpenSSL's BIO_get_fd returns the fd or -1, not a boolean.

Change-Id: I12a3429c71bb9c9064f9f91329a88923025f1fb5
Reviewed-on: https://boringssl-review.googlesource.com/6080
Reviewed-by: Adam Langley <agl@google.com>
2015-10-12 22:18:17 +00:00
David Benjamin c7ce977fb9 Ignore all extensions but renegotiation_info in SSL 3.0.
SSL 3.0 used to have a nice and simple rule around extensions. They don't
exist. And then RFC 5746 came along and made this all extremely confusing.

In an SSL 3.0 server, rather than blocking ServerHello extension
emission when renegotiation_info is missing, ignore all ClientHello
extensions but renegotiation_info. This avoids a mismatch between local
state and the extensions with emit.

Notably if, for some reason, a ClientHello includes the session_ticket
extension, does NOT include renegotiation_info or the SCSV, and yet the
client or server are decrepit enough to negotiate SSL 3.0, the
connection will fail due to unexpected NewSessionTicket message.

See https://crbug.com/425979#c9 for a discussion of something similar
that came up in diagnosing https://poodle.io/'s buggy POODLE check.
This is analogous to upstream's
5a3d8eebb7667b32af0ccc3f12f314df6809d32d.

(Not supporting renego as a server in any form anyway, we may as well
completely ignore extensions, but then our extensions callbacks can't
assume the parse hooks are always called. This way the various NULL
handlers still function.)

Change-Id: Ie689a0e9ffb0369ef7a20ab4231005e87f32d5f8
Reviewed-on: https://boringssl-review.googlesource.com/6180
Reviewed-by: Adam Langley <agl@google.com>
2015-10-11 20:47:19 +00:00
Adam Langley 7bd538d94d Remove an unreachable expression.
The goto always jumps into the loop so the for's initialisation
expression can never be executed. Clang warns about this.

Change-Id: I3c3d4b8430754099e9ca6fd20101868c40165245
2015-10-09 13:04:03 -07:00
Adam Langley f0258fe956 Add optimised version of P-224.
This imports the Google-authored P-224 implementation by Emilia Käsper
and Bodo Möller that is also in upstream OpenSSL.

Change-Id: I16005c74a2a3e374fb136d36f3f6569dab9d8919
Reviewed-on: https://boringssl-review.googlesource.com/6145
Reviewed-by: Adam Langley <agl@google.com>
2015-10-08 20:29:22 +00:00
Adam Langley 82aa28fa81 Make |BUF_memdup| look for zero length, not NULL.
BUF_memdup tries to avoid mallocing zero bytes (and thus unduly
returning an error for a NULL return value) by testing whether the input
buffer is NULL. This goes back to the original OpenSSL code.

However, when |ext_npn_parse_serverhello| tries to use |BUF_memdup| to
copy an NPN value returned by a callback, some callbacks just set the
output /length/ to zero to indicate an empty value. Thus, when
|BUF_memdup| tests the pointer, it's an uninitialised value and MSan
throws an error.

Since passing a NULL pointer to |BUF_memdup| better imply that the
length is zero, while the reverse empirically isn't true, testing the
length seems safer.

Change-Id: I06626f7dfb761de631fd997bda60057b76b8da94
2015-10-06 18:11:33 -07:00
Chuck Hays c608d6b02b Updating Bazel outputs to work on other platforms.
Bazel on Mac requires some alterations to the generated build files.
This change updates generate_build_files.py to emit suitable Bazel
files. This will require some tweaks to projects that build with Bazel.

Change-Id: I3d68ec754b8abaa41a348f86c32434477f2c5e1c
Reviewed-on: https://boringssl-review.googlesource.com/6146
Reviewed-by: Adam Langley <agl@google.com>
2015-10-07 00:57:20 +00:00
Eric Roman 1aec2cbad2 Reject iterationCount == 0 when parsing PBKDF2-params.
Previously a value of 0 would be accepted and intepreted as equivalent
to 1. This contradicts RFC 2898 which defines:

     iterationCount INTEGER (1..MAX),

BUG=https://crbug.com/534961

Change-Id: I89623980f99fde3ca3780880d311955d3f6fe0b5
Reviewed-on: https://boringssl-review.googlesource.com/5971
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-10-02 16:19:04 +00:00
David Benjamin 20c0e90d11 Allow NULL inputs in SSL_SESSION_get_time.
Some code relies on OpenSSL's behavior where it allowed for NULL. But this time
add a comment so people don't think this is the convention for new functions.

BUG=538292

Change-Id: I66566e0e24566fafe17e05369276248be3b05591
Reviewed-on: https://boringssl-review.googlesource.com/6070
Reviewed-by: Adam Langley <agl@google.com>
2015-10-01 20:16:49 +00:00
Brian Smith 20605684e8 Fix |max_tag_len| for TLS CBC AEADs.
Change-Id: Iba21583a4de08039fab78e526c91003fbd327592
Reviewed-on: https://boringssl-review.googlesource.com/6058
Reviewed-by: Adam Langley <agl@google.com>
2015-09-30 23:59:22 +00:00
Brian Smith d4ebc99122 Remove always-zero |bulk| variables in crypto/cipher/e_aes.c.
Change-Id: I36b2bb0e10c627ae6efa9d133df53b814922e652
Reviewed-on: https://boringssl-review.googlesource.com/6051
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-09-30 23:12:45 +00:00
Brian Smith bc41cdf327 Add tests from cipher_test.txt to the AEAD test suite.
Change-Id: I819b5473e35e1f71192d3a336252ae4506c4230b
Reviewed-on: https://boringssl-review.googlesource.com/6055
Reviewed-by: Adam Langley <agl@google.com>
2015-09-30 23:11:40 +00:00
Adam Langley 0dd93002dd Revert section changes for ASM.
This change reverts the following commits:
  72d9cba7cb
  5b61b9ebc5
  3f85e04f40
  2ab24a2d40

Change-Id: I669b83f2269cf96aa71a649a346147b9407a811e
Reviewed-on: https://boringssl-review.googlesource.com/6056
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-09-30 22:09:52 +00:00
Adam Langley f4e554e438 Bitwise-or, not logical-or, when hashing.
This didn't actually break anything, but it does make session lookup
quite slow.

Change-Id: I13615e8ccf6a46683a21774eb7c073318ae8c28c
Reviewed-on: https://boringssl-review.googlesource.com/6054
Reviewed-by: Matt Braithwaite <mab@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2015-09-30 20:50:18 +00:00
Adam Langley 72d9cba7cb Move .align directives next to their labels for ARM.
2ab24a2d40 added sections to ARM assembly
files. However, in cases where .align directives were not next to the
labels that they were intended to apply to, the section directives would
cause them to be ignored.

Change-Id: I32117f6747ff8545b80c70dd3b8effdc6e6f67e0
Reviewed-on: https://boringssl-review.googlesource.com/6050
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-09-30 18:35:29 +00:00
David Benjamin 3b27843b7c Go's darwin filenames have changed.
32-bit is gone (wasn't being used anyway) and the -osx10.8 suffix is gone.
Still looking into why the Linux bots are unhappy.

Change-Id: If3a35d20fb1cc6f1e3f023d792dc78b5c5aac72a
Reviewed-on: https://boringssl-review.googlesource.com/6061
Reviewed-by: Adam Langley <agl@google.com>
2015-09-30 18:32:05 +00:00
David Benjamin 3fc9fe3f4a Move the bots to Go 1.5.1.
Nothing in particular, but probably good to match the version of Go on our
workstations.

Change-Id: I5f4828299d56d25cd8c0dadfa91e9f18212a178d
Reviewed-on: https://boringssl-review.googlesource.com/6060
Reviewed-by: Adam Langley <agl@google.com>
2015-09-30 18:23:19 +00:00
Adam Langley dc7e9c4043 Make the runner tests a go “test”
This change makes the runner tests (in ssl/test/runner) act like a
normal Go test rather than being a Go binary. This better aligns with
some internal tools.

Thus, from this point onwards, one has to run the runner tests with `go
test` rather than `go run` or `go build && ./runner`.

This will break the bots.

Change-Id: Idd72c31e8e0c2b7ed9939dacd3b801dbd31710dd
Reviewed-on: https://boringssl-review.googlesource.com/6009
Reviewed-by: Matt Braithwaite <mab@google.com>
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-09-30 17:10:45 +00:00
David Benjamin 368ef1aa51 Take thread.h out of the documentation.
There's nothing in there that isn't deprecated, since BoringSSL is thread-safe
by default now.

Change-Id: Idfd9de8bd3a6544b1d4176b2d115eef9eefa63d0
Reviewed-on: https://boringssl-review.googlesource.com/6031
Reviewed-by: Adam Langley <agl@google.com>
2015-09-29 23:38:09 +00:00
David Benjamin 9a798ecc0e Document the hexadecimal casing thing in PORTING.md.
mab@ seems to be dealing with a fair number of these, so it's probably worth
adding to the list.

Change-Id: Ifaea3c96e7b089f28a87c7728ceb8c671786eb27
Reviewed-on: https://boringssl-review.googlesource.com/6030
Reviewed-by: Adam Langley <agl@google.com>
2015-09-29 23:37:50 +00:00
Matt Braithwaite 4d11aff33a Don't record handshake hashes if no Channel ID
Change-Id: Ic0dcde436024e8d11f9b5986998cf6e808ff036b
Reviewed-on: https://boringssl-review.googlesource.com/6007
Reviewed-by: Adam Langley <agl@google.com>
2015-09-29 21:47:05 +00:00
Adam Langley 2492586058 Add |PKCS12_verify_mac|.
This utility function is provided for API-compatibility and simply calls
|PKCS12_parse| internally.

BUG=536939

Change-Id: I86c548e5dfd64b6c473e497b95adfa5947fe9529
Reviewed-on: https://boringssl-review.googlesource.com/6008
Reviewed-by: Adam Langley <agl@google.com>
2015-09-29 20:30:35 +00:00
Adam Langley 5b61b9ebc5 Update ChaCha20 ARM asm with sections.
The ChaCha20 ARM asm is generated from GCC. This change updates the GCC
command line to include -ffunction-sections, which causes GCC to put
each function in its own section so that the linker with --gc-sections
can trim unused functions.

Since the file only has a single function, this is a bit useless, but
it'll now be consistent with the other ARM asm.

Change-Id: If12c675700310ea55af817b5433844eeffc9d029
Reviewed-on: https://boringssl-review.googlesource.com/6006
Reviewed-by: Adam Langley <agl@google.com>
2015-09-29 18:07:54 +00:00
Adam Langley 3f85e04f40 Add sections to Poly1305 ARM asm code.
This code isn't generated by perlasm and so the section directives need
to be added manually.

Change-Id: I46158741743859679decbce99097fe6071bf8012
Reviewed-on: https://boringssl-review.googlesource.com/6005
Reviewed-by: Adam Langley <agl@google.com>
2015-09-29 18:04:14 +00:00
Adam Langley 5f005ccd9d Make dummy functions static.
To avoid too much #if soup, e_aes.c uses a lot of dummy functions that
just call |abort|. This change makes them all static, which they should
have been all along.

Change-Id: I696f8a0560cf99631ed7adb42d1af10003db4a63
Reviewed-on: https://boringssl-review.googlesource.com/6004
Reviewed-by: Adam Langley <agl@google.com>
2015-09-29 18:03:04 +00:00
Adam Langley 2ab24a2d40 Put arm/aarch64 assembly functions in their own section.
This change causes each global arm or aarch64 asm function to be put
into its own section by default. This matches the behaviour of the
-ffunction-sections option to GCC and allows the --gc-sections option to
the linker to discard unused asm functions on a function-by-function
basis.

Sometimes several asm functions will share the same data an, in that
situation, the data is put into the section of one of the functions and
the section of the other function is merged with the added
“.global_with_section” directive.

Change-Id: I12c9b844d48d104d28beb816764358551eac4456
Reviewed-on: https://boringssl-review.googlesource.com/6003
Reviewed-by: Adam Langley <agl@google.com>
2015-09-29 18:02:14 +00:00
David Benjamin 502ca43fc8 Fix up pkcs8.h.
Somehow we ended up with duplicate 'Deprecated functions' sections.
PKCS12_get_key_and_certs ended up in one of them was probably an oversight.

Change-Id: Ia6d6a44132cb2730ee1f92a6bbcfa8ce168e7d08
Reviewed-on: https://boringssl-review.googlesource.com/6020
Reviewed-by: Adam Langley <agl@google.com>
2015-09-28 23:17:01 +00:00
David Benjamin 43a58ad436 Fix SSL_set_session documentation comment.
I put an extra space in there. Also document ownership and return value.

Change-Id: I0635423be7774a7db54dbf638cc548d291121529
Reviewed-on: https://boringssl-review.googlesource.com/6010
Reviewed-by: Adam Langley <agl@google.com>
2015-09-28 22:40:30 +00:00
David Benjamin dbb0321014 Clarify that only top-level CBBs get CBB_cleanup.
Also add an assert to that effect.

Change-Id: I1bd0571e3889f1cba968fd99041121ac42ee9e89
Reviewed-on: https://boringssl-review.googlesource.com/5990
Reviewed-by: Adam Langley <agl@google.com>
2015-09-28 22:40:01 +00:00
David Benjamin df6a3f8b95 Move SSL_CIPHER section just above cipher suite configuration.
Putting it at the top was probably a mistake? Even though SSL_CIPHER
(like SSL_SESSION) doesn't depend on SSL, if you're reading through the
header, SSL_CTX and SSL are the most important types. You could even use
the library without touch cipher suite configs if you don't care since
the default is decently reasonable, though it does include a lot of
ciphers. (Hard to change that if we wanted to because DEFAULT is often
used somewhat like ALL and then people subtract from it.)

Change-Id: Ic9ddfc921858f7a4c141972fe0d1e465ca196b9d
Reviewed-on: https://boringssl-review.googlesource.com/5963
Reviewed-by: Adam Langley <agl@google.com>
2015-09-28 22:39:39 +00:00
David Benjamin 32876b3dbb Document cipher suite configuration.
The cipher suite rules could also be anchored on SSL_TXT_* if desired. I
currently documented them in prose largely because SSL_TXT_* also
defines protocol version strings and those are weird; SSL_TXT_TLSV1_1
isn't even a cipher rule. (And, in fact, those are the only SSL_TXT_*
macros that we can't blindly remove. I found some code that #ifdef's the
version SSL_TXT_* macros to decide if version-locked SSL_METHODs are
available.)

Also they clutter the header. I was thinking maybe we should dump a lot
of the random constants into a separate undocumented header or perhaps
just unexport them.

I'm slightly torn on this though and could easily be convinced in the
other direction. (Playing devil's advocate, anchoring on SSL_TXT_* means
we're less likely to forget to document one so long as adding a
SSL_TXT_* macro is the convention.)

Change-Id: Ide2ae44db9d6d8f29c24943090c210da0108dc37
Reviewed-on: https://boringssl-review.googlesource.com/5962
Reviewed-by: Adam Langley <agl@google.com>
2015-09-28 22:36:22 +00:00
David Benjamin d3a53c8fd9 OCSP stapling and SCT extensions go under certificate verification.
This mirrors how the server halves fall under configuring certificates.

Change-Id: I9bde85eecfaff6487eeb887c88cb8bb0c36b83d8
Reviewed-on: https://boringssl-review.googlesource.com/5961
Reviewed-by: Adam Langley <agl@google.com>
2015-09-28 22:27:01 +00:00
David Benjamin 0cfea3411a Move a few more functions to the catch-all 'obscure' bucket.
Change-Id: I493f26561db2bc8510963a0da5032a758bb1f3ef
Reviewed-on: https://boringssl-review.googlesource.com/5960
Reviewed-by: Adam Langley <agl@google.com>
2015-09-28 22:19:04 +00:00
David Benjamin 1cee7da07e Documentation typo.
Change-Id: I2dc4253a2456625057c8188c6cb9b0b7300d6c79
Reviewed-on: https://boringssl-review.googlesource.com/5951
Reviewed-by: Adam Langley <agl@google.com>
2015-09-28 22:18:40 +00:00
David Benjamin 93d8cf557f Add various tests for d2i_PrivateKey.
Change-Id: I030022c240d17df08cf6f59eede0e94373152c40
Reviewed-on: https://boringssl-review.googlesource.com/5950
Reviewed-by: Adam Langley <agl@google.com>
2015-09-28 22:18:23 +00:00
David Benjamin 382bc29251 Defensively avoid assuming d2i functions don't advance on error.
Although the previous commit should ensure this doesn't happen, the
uint8_t** pattern is very error-prone and we're trying to avoid doing
much to the legacy ASN.1 stack. To that end, maintaining the strong
exception guarantee w.r.t. the input pointer-pointer is best effort and
we won't rely on it, so we needn't spend our time chasing down problems.

Change-Id: Ib78974eb94377fe0b0b379f57d9695dc81f344bb
Reviewed-on: https://boringssl-review.googlesource.com/5949
Reviewed-by: Adam Langley <agl@google.com>
2015-09-28 22:15:42 +00:00
David Benjamin 15e4deb165 d2i: don't update input pointer on failure
(Imported from upstream's 728bcd59d3d41e152aead0d15acc51a8958536d3.)

Actually this one was reported by us, but the commit message doesn't
mention this.

This is slightly modified from upstream's version to fix some problems
noticed in import. Specifically one of d2i_X509_AUX's success paths is
bust and d2i_PrivateKey still updates on one error path. Resolve the
latter by changing both it and d2i_AutoPrivateKey to explicitly hit the
error path on ret == NULL. This lets us remove the NULL check in
d2i_AutoPrivateKey.

We'll want to report the problems back upstream.

Change-Id: Ifcfc965ca6d5ec0a08ac154854bd351cafbaba25
Reviewed-on: https://boringssl-review.googlesource.com/5948
Reviewed-by: Adam Langley <agl@google.com>
2015-09-28 22:15:17 +00:00
David Benjamin 97a33939a3 Deprecate basically the entire base64 implementation.
The IUF functions were added for PEM and internally are very lenient to
whitespace and include other PEM-specific behaviors (notably they treat
hyphens as EOF). They also decode a ton of invalid input (see upstream's
RT #3757).

Upstream has a rewrite with tests that resolves the latter issue which
we should review and import. But this is still a very PEM-specific
interface. As this code has basically no callers outside the PEM code
(and any such callers likely don't want a PEM-specific API), it's
probably not worth the trouble to massage this and PEM into a strict IUF
base64 API with PEM whitespace and hyphen bits outside. Just deprecate
it all and leave it in a corner.

Change-Id: I5b98111e87436e287547829daa65e9c1efc95119
Reviewed-on: https://boringssl-review.googlesource.com/5952
Reviewed-by: Adam Langley <agl@google.com>
2015-09-28 21:53:39 +00:00
Adam Langley 6daa8268a6 Move the ARM-AES functions inside an #if block.
This fixes an issue with Clang, which doesn't like static functions that
aren't used (to its eyes).

Change-Id: I7cb055aa9f0ab3934352c105abe45f9c30990250
2015-09-25 15:21:34 -07:00
Arve Hjønnevåg 7f64706e37 Use armv8 functions for of AES_[en|de]crypt and AES_set_[en|de]crypt_key, if available.
This change causes ARM and Aarch64 to use the ARMv8 AES instructions, if
provided by the current CPU.

Change-Id: I50cb36270139fcf4ce42e5ebb8afe24ffcab22e3
Reviewed-on: https://boringssl-review.googlesource.com/6002
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-09-25 22:08:29 +00:00
Adam Langley d75545600d Merge hwrand.c into rand.c.
By doing this the compiler can notice that much of the code is unused in
the case that we know that we can't have a hardware RNG (i.e. ARM).

Change-Id: I72d364a30080364d700f855640e0164c2c62f0de
Reviewed-on: https://boringssl-review.googlesource.com/6001
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-09-25 22:07:42 +00:00
Adam Langley c8e664b70a Fix several minor points noticed by Kenny.
∙ Some comments had the wrong function name at the beginning.
  ∙ Some ARM asm ended up with two #if defined(__arm__) lines – one from
    the .pl file and one inserted by the translation script.

Change-Id: Ia8032cd09f06a899bf205feebc2d535a5078b521
Reviewed-on: https://boringssl-review.googlesource.com/6000
Reviewed-by: Adam Langley <agl@google.com>
2015-09-24 22:08:50 +00:00
Eric Roman 8c9b8783e2 Change some "int" variables to "size_t" in ssl3_handshake_mac().
BUG=https://crbug.com/535039

Change-Id: I94d35ae5acee510b1e6874c37f35eddda9906e71
Reviewed-on: https://boringssl-review.googlesource.com/5974
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-09-24 00:04:59 +00:00
Eric Roman f0e8d537de Update comments in digest.h to consistently mention that digest size and block size are measured in bytes.
Change-Id: Ie75c68132fd501549b2ad5203663f6e99867eed6
Reviewed-on: https://boringssl-review.googlesource.com/5970
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-09-24 00:04:12 +00:00
David Benjamin b50c91b5df Cleaner handling of "cnid" in do_x509_check
Avoid using cnid = 0, use NID_undef instead, and return early instead of
trying to find an instance of that in the subject DN.

(Imported from upstrea's 40d5689458593aeca0d1a7f3591f7ccb48e459ac.)

Change-Id: I1bdf6bf7a4b1f4774a8dbec7e5df421b3a27c7e4
Reviewed-on: https://boringssl-review.googlesource.com/5947
Reviewed-by: Adam Langley <agl@google.com>
2015-09-23 23:59:43 +00:00
David Benjamin 5e4158fe12 Fix the comment for POINT_CONVERSION_UNCOMPRESSED
The |z| value should be 0x04 not 0x02

RT#3838

(Imported from upstream's 41fe7d2380617da515581503490f1467ee75a521.)

Change-Id: I35745cd2a5a32bd726cb4d3c0613cef2bcbef35b
Reviewed-on: https://boringssl-review.googlesource.com/5946
Reviewed-by: Adam Langley <agl@google.com>
2015-09-23 23:57:01 +00:00
David Benjamin b86b0f2824 RT 3493: fix RSA test
- Pass in the right ciphertext length to ensure we're indeed testing
  ciphertext corruption (and not truncation).
- Only test one mutation per byte to not make the test too slow.
- Add a separate test for truncated ciphertexts.

(Imported from upstream's 5f623eb61655688501cb1817a7ad0592299d894a.)

Change-Id: I425a77668beac9d391387e3afad8d15ae387468f
Reviewed-on: https://boringssl-review.googlesource.com/5945
Reviewed-by: Adam Langley <agl@google.com>
2015-09-23 23:56:40 +00:00
David Benjamin 79c59a30b5 size_t RSA_private_decrypt's input.
Change-Id: If05761052e235b38d9798b2fe4d8ba44293af891
Reviewed-on: https://boringssl-review.googlesource.com/5944
Reviewed-by: Adam Langley <agl@google.com>
2015-09-23 23:55:18 +00:00
Adam Langley d98dc1311e Upstream Android-specific things under |BORINGSSL_ANDROID_SYSTEM|
The Android system BoringSSL has a couple of changes:
  ∙ ChaCha20-Poly1305 is disabled because it's not an offical
    cipher suite.
  ∙ P-521 is offered in the ClientHello.

These changes were carried in the Android BoringSSL repo directly. This
change upstreams them when BORINGSSL_ANDROID_SYSTEM is defined.

Change-Id: If3e787c6694655b56e7701118aca661e97a5f26c
2015-09-23 16:41:33 -07:00
David Benjamin 907bd30dcd Banish more deprecated flags to the bottom.
Change-Id: I7959fc65afae8860804ab9f038e3b5a9c2c8ec7b
Reviewed-on: https://boringssl-review.googlesource.com/5943
Reviewed-by: Adam Langley <agl@google.com>
2015-09-23 23:33:02 +00:00
David Benjamin 59937045ec Document certificate verification functions in SSL.
Or at least group them together and make a passing attempt to document
them. The legacy X.509 stack itself remains largely untouched and most
of the parameters have to do with it.

Change-Id: I9e11e2ad1bbeef53478c787344398c0d8d1b3876
Reviewed-on: https://boringssl-review.googlesource.com/5942
Reviewed-by: Adam Langley <agl@google.com>
2015-09-23 23:31:18 +00:00
David Benjamin df0905a803 Don't pretend to account for RSA_PSK.
RSA_PSK is really weird in that it takes a Certificate, but you're not
expected to verify it. It's just a funny way to transmit an RSA key.
(They probably should have used the RSA_EXPORT ServerKeyExchange
spelling.) Some code now already doesn't account for it right around
certificate verification.

Given ECDHE_PSK exists, hopefully there will never be any need to add
this.

Change-Id: Ia64dac28099eaa9021f8d915d45ccbfd62872317
Reviewed-on: https://boringssl-review.googlesource.com/5941
Reviewed-by: Adam Langley <agl@google.com>
2015-09-23 23:18:44 +00:00
David Benjamin 42fea37227 Document Channel ID functions and a few random extras.
Change-Id: I34a6352d265615ee08bb18fd537acf70a558f014
Reviewed-on: https://boringssl-review.googlesource.com/5940
Reviewed-by: Adam Langley <agl@google.com>
2015-09-23 23:08:59 +00:00
Adam Langley 67251f2da9 Use |strtok| rather than |strtok_r|.
As ever, Windows doesn't support the correct function.

Change-Id: If16c979e591abda01ce3bf591b9162c210f03932
2015-09-23 15:01:07 -07:00
Steven Valdez 0d62f26c36 Adding more options for signing digest fallback.
Allow configuring digest preferences for the private key. Some
smartcards have limited support for signing digests, notably Windows
CAPI keys and old Estonian smartcards. Chromium used the supports_digest
hook in SSL_PRIVATE_KEY_METHOD to limit such keys to SHA1. However,
detecting those keys was a heuristic, so some SHA256-capable keys
authenticating to SHA256-only servers regressed in the switch to
BoringSSL. Replace this mechanism with an API to configure digest
preference order. This way heuristically-detected SHA1-only keys may be
configured by Chromium as SHA1-preferring rather than SHA1-requiring.

In doing so, clean up the shared_sigalgs machinery somewhat.

BUG=468076

Change-Id: I996a2df213ae4d8b4062f0ab85b15262ca26f3c6
Reviewed-on: https://boringssl-review.googlesource.com/5755
Reviewed-by: Adam Langley <agl@google.com>
2015-09-23 21:55:01 +00:00
David Benjamin 4c60d356a9 Work around even more Estonian ID card misissuances.
Not content with signing negative RSA moduli, still other Estonian IDs have too
many leading zeros. Work around those too.

This workaround will be removed in six months.

BUG=534766

Change-Id: Ica23b1b1499f9dbe39e94cf7b540900860e8e135
Reviewed-on: https://boringssl-review.googlesource.com/5980
Reviewed-by: Adam Langley <agl@google.com>
2015-09-23 20:35:47 +00:00
Adam Langley d7fe75ca5f Add |SSL_CIPHER_is_RC4|.
We wish to be able to detect the use of RC4 so that we can flag it and
investigate before it's disabled.

Change-Id: I6dc3a5d2211b281097531a43fadf08edb5a09646
Reviewed-on: https://boringssl-review.googlesource.com/5930
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-09-18 23:03:40 +00:00
David Benjamin 306ece31bc Fix some malloc failure crashes.
EVP_MD_CTX_copy_ex was implemented with a memcpy, which doesn't work well when
some of the pointers need to be copied, and ssl_verify_cert_chain didn't
account for set_ex_data failing.

Change-Id: Ieb556aeda6ab2e4c810f27012fefb1e65f860023
Reviewed-on: https://boringssl-review.googlesource.com/5911
Reviewed-by: Adam Langley <agl@google.com>
2015-09-18 19:30:09 +00:00
David Benjamin c71567dd50 Update the Estonian workaround comments.
Target date for removal of the workaround is 6 months.

BUG=532048

Change-Id: I402f75e46736936725575559cd8eb194115ab0df
Reviewed-on: https://boringssl-review.googlesource.com/5910
Reviewed-by: Adam Langley <agl@google.com>
2015-09-18 18:42:34 +00:00
David Benjamin 3fb1ebc541 Deprecated things are deprecated.
Get them out of the way when reading through the header.

Change-Id: Ied3f3601262e74570769cb7f858dcff4eff44813
Reviewed-on: https://boringssl-review.googlesource.com/5898
Reviewed-by: Adam Langley <agl@google.com>
2015-09-18 18:41:27 +00:00
David Benjamin 977547b6f9 Group NPN functions in their own section.
Existing documentation was moved to the header, very slightly tweaked.

Change-Id: Ife3c2351e2d7e6a335854284f996918039414446
Reviewed-on: https://boringssl-review.googlesource.com/5897
Reviewed-by: Adam Langley <agl@google.com>
2015-09-18 18:39:53 +00:00
David Benjamin 8984f1f6e5 Group ALPN functions into their own section.
These were already documented, though some of the documentation was
expanded on slightly.

Change-Id: I04c6276a83a64a03ab9cce9b9c94d4dea9ddf638
Reviewed-on: https://boringssl-review.googlesource.com/5896
Reviewed-by: Adam Langley <agl@google.com>
2015-09-17 22:19:58 +00:00
David Benjamin 58fcfc18f0 ECDHE and DHE functions get grouped into sections.
All these functions were already documented, just not grouped. I put
these above DTLS-SRTP and PSK as they're considerably less niche of
features.

Change-Id: I610892ce9763fe0da4f65ec87e5c7aaecb10388b
Reviewed-on: https://boringssl-review.googlesource.com/5895
Reviewed-by: Adam Langley <agl@google.com>
2015-09-17 22:17:12 +00:00
Matt Braithwaite cd6f54b193 Add method to query Extended Master Secret support
Change-Id: I4c285f4b3dd77f8fc7249c7504b5e4eb9b62959f
Reviewed-on: https://boringssl-review.googlesource.com/5920
Reviewed-by: Adam Langley <agl@google.com>
2015-09-17 21:18:28 +00:00
Paul Lietar 62be8ac8da Skip the SCT and OCSP extensions in ServerHello when resuming sessions.
SCT and OCSP are part of the session data and as such shouldn't be sent
again to the client when resuming.

Change-Id: Iaee3a3c4c167ea34b91504929e38aadee37da572
Reviewed-on: https://boringssl-review.googlesource.com/5900
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-09-17 21:15:00 +00:00
David Benjamin e8814df699 Document PSK functions in ssl.h.
Change-Id: Iac58d28570d429236de1d2bc40b631e252b8e710
Reviewed-on: https://boringssl-review.googlesource.com/5893
Reviewed-by: Adam Langley <agl@google.com>
2015-09-15 23:34:12 +00:00
David Benjamin 9e4e01ee14 Align the SSL stack on #include style.
ssl.h should be first. Also two lines after includes and the rest of the
file.

Change-Id: Icb7586e00a3e64170082c96cf3f8bfbb2b7e1611
Reviewed-on: https://boringssl-review.googlesource.com/5892
Reviewed-by: Adam Langley <agl@google.com>
2015-09-15 23:32:07 +00:00
David Benjamin 1ac08feed6 Fix SSL and SSL_CTX ex_data variable names.
Forgot to fix these when I fixed the headers.

Change-Id: Ie45e624abc993e16e2d5a872ef00dba9029a38df
Reviewed-on: https://boringssl-review.googlesource.com/5891
Reviewed-by: Adam Langley <agl@google.com>
2015-09-15 23:22:07 +00:00
David Benjamin 2079ee70c6 Fix minor documentation mistake.
Change-Id: Ia31c0c04c0dbb00cf55db7fdf2c4641a2287f012
Reviewed-on: https://boringssl-review.googlesource.com/5890
Reviewed-by: Adam Langley <agl@google.com>
2015-09-15 23:19:57 +00:00
Brian Smith 1f5e9456a9 Remove superfluous SHA-1 dependency from EVP ECDSA code.
The documentation for |ECDSA_sign| and |ECDSA_verify| says that the
|type| parameter should be zero.

Change-Id: I875d3405455c5443f5a5a5c2960a9a9f486ca5bb
Reviewed-on: https://boringssl-review.googlesource.com/5832
Reviewed-by: Adam Langley <agl@google.com>
2015-09-15 23:18:44 +00:00
David Benjamin 231cb82145 Work around broken Estonian smart cards. Again.
Estonian IDs issued between September 2014 to September 2015 are broken and use
negative moduli. They last five years and are common enough that we need to
work around this bug.

Add parallel "buggy" versions of BN_cbs2unsigned and RSA_parse_public_key which
tolerate this mistake, to align with OpenSSL's previous behavior. This code is
currently hooked up to rsa_pub_decode in RSA_ASN1_METHOD so that d2i_X509 is
tolerant. (This isn't a huge deal as the rest of that stack still uses the
legacy ASN.1 code which is overly lenient in many other ways.)

In future, when Chromium isn't using crypto/x509 and has more unified
certificate handling code, we can put client certificates under a slightly
different codepath, so this needn't hold for all certificates forever. Then in
September 2019, when the broken Estonian certificates all expire, we can purge
this codepath altogether.

BUG=532048

Change-Id: Iadb245048c71dba2eec45dd066c4a6e077140751
Reviewed-on: https://boringssl-review.googlesource.com/5894
Reviewed-by: Adam Langley <agl@google.com>
2015-09-15 21:18:15 +00:00
David Benjamin cfd65b60a6 Fold srtp.h into ssl.h.
This gets the documentation into the ssl.h documentation, and removes
one of the circularly-dependent headers hanging off ssl.h. Also fixes
some typos; there were a few instances of "SSL *ctx".

Change-Id: I2a41c6f518f4780af84d468ed220fe7b0b8eb0d3
Reviewed-on: https://boringssl-review.googlesource.com/5883
Reviewed-by: Adam Langley <agl@google.com>
2015-09-14 23:59:37 +00:00
David Benjamin dafbdd49c7 Document session cache functions.
Also switch to the new variable names (SSL_CTX *ctx, SSL *ssl,
SSL_SESSION *session) for all documented functions.

Change-Id: I15e15a703b96af1727601108223c7ce3b0691f1d
Reviewed-on: https://boringssl-review.googlesource.com/5882
Reviewed-by: Adam Langley <agl@google.com>
2015-09-14 23:58:48 +00:00
David Benjamin 14e2b5070b const-correct a few SSL_SESSION functions.
Change-Id: I64d1e29d1e414add4ae522fd9603c550d426a557
Reviewed-on: https://boringssl-review.googlesource.com/5881
Reviewed-by: Adam Langley <agl@google.com>
2015-09-14 23:41:36 +00:00
David Benjamin abb6c1c191 Reorder ssl_session.c slightly to match the header.
Change-Id: I43138057689a479ff7aba1543118af4b52bb821b
Reviewed-on: https://boringssl-review.googlesource.com/5880
Reviewed-by: Adam Langley <agl@google.com>
2015-09-14 23:40:55 +00:00
David Benjamin 190ab7f179 Move ex_data functions in ssl.h to a section.
Change-Id: Ie3b7c1956cc9d62091f649d0e621d84fce1d26ec
Reviewed-on: https://boringssl-review.googlesource.com/5879
Reviewed-by: Adam Langley <agl@google.com>
2015-09-14 23:40:34 +00:00
David Benjamin 8f3cc26812 Rename ssl_sess.c to ssl_session.c.
Change-Id: Ib730ffe49b30c79b3f30acae4070f6055081a0a3
Reviewed-on: https://boringssl-review.googlesource.com/5878
Reviewed-by: Adam Langley <agl@google.com>
2015-09-14 23:37:52 +00:00
David Benjamin a6b8cdfbe9 Document functions acting on an SSL_SESSION.
Change-Id: I0b4386d1972af0ac10db397716de8161810a87f4
Reviewed-on: https://boringssl-review.googlesource.com/5877
Reviewed-by: Adam Langley <agl@google.com>
2015-09-14 23:37:42 +00:00
David Benjamin 79c117a4ac Move structs to a 'Private structures' section in ssl.h.
To be consistent with some of the other headers and because SSL_METHOD
no longer has a place to anchor documentation, move the type
documentation up to the corresponding section headers, rather than
attached to a convenient function.

Also document thread-safety properties of SSL and SSL_CTX.

Change-Id: I7109d704d28dda3f5d83c72d86fe31bc302b816e
Reviewed-on: https://boringssl-review.googlesource.com/5876
Reviewed-by: Adam Langley <agl@google.com>
2015-09-14 23:35:18 +00:00
David Benjamin 361ecc0236 Replace skipPast with strings.TrimPrefix.
There was a bug in skipPast; it was skipping to the start of the string,
rather than the end of it. But more of an issue is that it would skip if
it was in the middle of the string, which caused problems when
STACK_OF(FOO) was used as a parameter.

At some point, we'll probably need to give this a real C declaration
parser. We still have declarations (like those that return function
pointers) which we can't parse. But for now let's clear the low-hanging
fruit.

Change-Id: Ic2cee452cc8cf6887a6ff1b00cea353cec361955
Reviewed-on: https://boringssl-review.googlesource.com/5875
Reviewed-by: Adam Langley <agl@google.com>
2015-09-14 23:31:43 +00:00
David Benjamin ee0c82789a Move SSL_get_peer_* to Connection information.
This is arguably more commonly queried connection information than the
tls-unique.

Change-Id: I1f080536153ba9f178af8e92cb43b03df37110b5
Reviewed-on: https://boringssl-review.googlesource.com/5874
Reviewed-by: Adam Langley <agl@google.com>
2015-09-14 23:30:54 +00:00
David Benjamin 27bbae4682 Reorder functions in ssl_lib.c to match ssl.h.
Just the stuff that has been pulled out into sections already.

Change-Id: I3da6bc61d79ccfe2b18d888075dc32026a656464
Reviewed-on: https://boringssl-review.googlesource.com/5873
Reviewed-by: Adam Langley <agl@google.com>
2015-09-14 23:30:23 +00:00
David Benjamin 3c1ccc017c Document a bunch of core functions in ssl.h.
Unfortunately, these are also some of the worst APIs in the SSL stack.
I've tried to capture all the things they expose to the caller. 0 vs -1
is intentionally left unexpanded on for now. Upstream's documentation
says 0 means transport EOF, which is a nice idea but isn't true. (A lot
of random functions return 0 on error and pass it up to the caller.)
https://crbug.com/466303 tracks fixing that.

SSL_set_bio is intentionally documented to NOT be usable when they're
already configured. The function tries to behave in this case and even
with additional cases when |rbio| and/or |wbio| are unchanged, but this
is buggy. For instance, this will explode:

     SSL_set_bio(ssl, bio1, bio1);
     SSL_set_bio(ssl, bio2, SSL_get_wbio(ssl));

As will this, though it's less clear this is part of the API contract
due to SSL taking ownership.

     SSL_set_bio(ssl, bio1, bio2);
     SSL_set_bio(ssl, bio2, bio1);

It also tries to handle ssl->bbio already existing, but I doubt it quite
works. Hopefully we can drop ssl->bbio eventually. (Why is this so
complicated...)

Change-Id: I5f9f3043915bffc67e2ebd282813e04afbe076e6
Reviewed-on: https://boringssl-review.googlesource.com/5872
Reviewed-by: Adam Langley <agl@google.com>
2015-09-14 23:29:18 +00:00
David Benjamin 72d8693ef2 No-op change to kick the documentation bot.
Change-Id: I8300ab8c4adda2ef4fb0f8b01d73469be6b8851a
2015-09-14 19:15:09 -04:00
David Benjamin c0577626cb Run go fmt over runner.
Last set of changes didn't do that.

Change-Id: Iae24e75103529ce4d50099c5cbfbcef0e10ba663
Reviewed-on: https://boringssl-review.googlesource.com/5871
Reviewed-by: Adam Langley <agl@google.com>
2015-09-14 22:26:06 +00:00
David Benjamin c99807d843 Tidy up dtls1_hm_fragment_new and fix (unreachable) memory leak.
clang scan-build found a memory leak if the overflow codepath in
dtls1_hm_fragment is hit. Along the way, tidy up that function.

Change-Id: I3c4b88916ee56ab3ab63f93d4a967ceae381d187
Reviewed-on: https://boringssl-review.googlesource.com/5870
Reviewed-by: Adam Langley <agl@google.com>
2015-09-14 22:25:17 +00:00
Adam Langley 626c68601c Initialise |supports_digest|.
We were getting this because of C's defaults, but it's fragile to leave
it like this because someone may add another field at the end in the
future.

Change-Id: I8b2dcbbc7cee8062915d15101f99f5a1aae6ad87
Reviewed-on: https://boringssl-review.googlesource.com/5860
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-09-14 21:51:18 +00:00
David Benjamin 1d128f369c Make SSL_get_client_CA_list slightly more OpenSSL-compatible.
SSL_get_client_CA_list is one of those dreaded functions which may query either
configuration state or handshake state. Moreover, it does so based on
|ssl->server|, which may not be configured until later. Also check
|ssl->handshake_func| to make sure |ssl| is not in an indeterminate state.

This also fixes a bug where SSL_get_client_CA_list wouldn't work in DTLS due to
the incorrect |ssl->version| check.

Change-Id: Ie564dbfeecd2c8257fd6bcb148bc5db827390c77
Reviewed-on: https://boringssl-review.googlesource.com/5827
Reviewed-by: Adam Langley <agl@google.com>
2015-09-11 22:30:55 +00:00
Matt Braithwaite af096751e8 Restore the NULL-SHA ciphersuite. (Alas.)
Change-Id: Ia5398f3b86a13fb20dba053f730b51a0e57b9aa4
Reviewed-on: https://boringssl-review.googlesource.com/5791
Reviewed-by: Adam Langley <agl@google.com>
2015-09-11 22:18:08 +00:00
Paul Lietar 4fac72e638 Add server-side support for Signed Certificate Timestamps.
Change-Id: Ifa44fef160fc9d67771eed165f8fc277f28a0222
Reviewed-on: https://boringssl-review.googlesource.com/5840
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-09-11 21:52:26 +00:00
David Benjamin 1bfce80b44 Generate stable URL fragments.
Using numbers is sensitive to moving things around. Instead, use the
names and enforce, for sections, that they are unique. Names would be
enforced too, but there's a table-of-contents bug around #ifdefs to
resolve first.

Change-Id: I8822e8ba8da9ed3ee4984365b8a64932d16d5baf
Reviewed-on: https://boringssl-review.googlesource.com/5826
Reviewed-by: Adam Langley <agl@google.com>
2015-09-11 21:03:50 +00:00
David Benjamin 7e40d4e584 Deprecated functions get their own sections.
A small handful of functions got a 'Deprecated:' prefix instead in
documentation.

Change-Id: Ic151fb7d797514add66bc6465b6851b666a471bc
Reviewed-on: https://boringssl-review.googlesource.com/5825
Reviewed-by: Adam Langley <agl@google.com>
2015-09-11 20:57:36 +00:00
David Benjamin 6fad7bc586 Some documentation fixes.
We had a few duplicate section names.

Change-Id: I0c9b2a1669ac14392fd577097d5ee8dd80f7c73c
Reviewed-on: https://boringssl-review.googlesource.com/5824
Reviewed-by: Adam Langley <agl@google.com>
2015-09-11 20:56:53 +00:00
David Benjamin c0125ef8f3 Fix SSL_CIPHER_is_AESGCM.
It was checking algorithm_mac rather than algorithm_enc.
(Coincidentally, it gave the right answer if you compiled out the
ChaCha20 ciphers since SSL_AES128GCM and SSL_AEAD shared a value.)

Change-Id: I17047425ef7fabb98969144965d8db9528ef8497
Reviewed-on: https://boringssl-review.googlesource.com/5850
Reviewed-by: Adam Langley <agl@google.com>
2015-09-09 17:56:59 +00:00
Adam Langley a0a8dc208f Move large stack buffer in bssl_shim to heap.
The size of the stack caused by this object is problematic for systems
that have smaller stacks because they expect many threads.

Change-Id: Ib8f03741f9dd96bf474126f001947f879e50a781
Reviewed-on: https://boringssl-review.googlesource.com/5831
Reviewed-by: Matt Braithwaite <mab@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2015-09-09 17:54:24 +00:00
Adam Langley f673831272 Drop urandom_test.
It didn't do too much and I didn't notice that CRYPTO_sysrand wasn't
OPENSSL_EXPORTed, which makes the test impossible on shared-library
builds.

Change-Id: I38986572aa34fa9c0f30075d562b8ee4e1a0c8b8
2015-09-08 18:10:15 -07:00
David Benjamin 7c6d09b9e5 Fold ssl_algs.c into ssl_lib.c.
There's not enough in that file to really justify its own file now.

Change-Id: I6130cfce6c40fe9d46aa83dd83e6f38d87fdcf64
Reviewed-on: https://boringssl-review.googlesource.com/5823
Reviewed-by: Adam Langley <agl@google.com>
2015-09-09 01:05:25 +00:00
Matt Braithwaite cc2c7aa91c Buffer reads of urandom, if you promise no forking.
Callers that lack hardware random may obtain a speed improvement by
calling |RAND_enable_fork_unsafe_buffering|, which enables a
thread-local buffer around reads from /dev/urandom.

Change-Id: I46e675d1679b20434dd520c58ece0f888f38a241
Reviewed-on: https://boringssl-review.googlesource.com/5792
Reviewed-by: Adam Langley <agl@google.com>
2015-09-09 01:02:54 +00:00
David Benjamin 443a1f65e2 Toss file-related convenience bits of ssl/ into a corner.
Quite a lot of consumers of the SSL stack will never need to touch files from
the SSL stack, but enough do that we can't just ditch them. Toss that all into
their own file so a static linker can drop it.

Change-Id: Ia07de939889eb09e3ab16aebcc1b6869ca8b75a0
Reviewed-on: https://boringssl-review.googlesource.com/5820
Reviewed-by: Adam Langley <agl@google.com>
2015-09-08 23:34:40 +00:00
Adam Langley 06fa67c8d3 Stop using |ERR_peek_last_error| in RSA blinding.
History has shown there are bugs in not setting the error code
appropriately, which makes any decision making based on
|ERR_peek_last_error|, etc. suspect. Also, this call was interfering
with the link-time optimizer's ability to discard the implementations of
many functions in crypto/err during dead code elimination.

Change-Id: Iba9e553bf0a72a1370ceb17ff275f5a20fca31ec
Reviewed-on: https://boringssl-review.googlesource.com/5748
Reviewed-by: Adam Langley <agl@google.com>
2015-09-08 23:32:48 +00:00
Paul Lietar 8f1c268692 Wait for CertificateStatus message to verify certificate.
Applications may require the stapled OCSP response in order to verify
the certificate within the verification callback.

Change-Id: I8002e527f90c3ce7b6a66e3203c0a68371aac5ec
Reviewed-on: https://boringssl-review.googlesource.com/5730
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-09-08 19:04:43 +00:00
Adam Langley 8748920ca7 Don't forget to free the TLS 1.0 ciphers.
Change-Id: I38517e0b13c9fc75b3964bc980d16daee9aed5b5
2015-09-03 15:52:29 -07:00
Adam Langley cef7583633 Add cipher suite settings for TLS ≥ 1.0.
This change adds the ability to configure ciphers specifically for
TLS ≥ 1.0. This compliments the existing ability to specify ciphers
for TLS ≥ 1.1.

This is useful because TLS 1.0 is the first version not to suffer from
POODLE. (Assuming that it's implemented correctly[1].) Thus one might
wish to reserve RC4 solely for SSLv3.

[1] https://www.imperialviolet.org/2014/12/08/poodleagain.html

Change-Id: I774d5336fead48f03d8a0a3cf80c369692ee60df
Reviewed-on: https://boringssl-review.googlesource.com/5793
Reviewed-by: Adam Langley <agl@google.com>
2015-09-03 22:44:36 +00:00
Paul Lietar 23b185a3cf Allow out_present to be NULL in CBS_get_optional_asn1
This is useful to skip an optional element, and mirrors the behaviour of
CBS_get_optional_asn1_octet_string.

Change-Id: Icb538c5e99a1d4e46412cae3c438184a94fab339
Reviewed-on: https://boringssl-review.googlesource.com/5800
Reviewed-by: Adam Langley <agl@google.com>
2015-09-03 18:46:17 +00:00
David Benjamin c9d40ba5b0 Remove unnecessary field initializations.
SSL_CTX gets memset to zero, so many of the values needn't be explicitly
initialized.

Change-Id: I0e707a0dcc052cd6f0a5dc8d037400170bd75594
Reviewed-on: https://boringssl-review.googlesource.com/5812
Reviewed-by: Adam Langley <agl@google.com>
2015-09-03 18:39:54 +00:00
David Benjamin 95aaf4a61c Markdown-ify BUILDING.
Change-Id: Icd3cba6522ce47a4dfe699204982b5b692d3d62e
Reviewed-on: https://boringssl-review.googlesource.com/5811
Reviewed-by: Adam Langley <agl@google.com>
2015-09-03 18:38:21 +00:00
David Benjamin 0e3f1d80f8 Markdown-ify STYLE.
Since we're able to render it fancy, may as well.

Change-Id: Ia1ab4b7ad0cdd78c8ffb75342ee62365843e7d5f
Reviewed-on: https://boringssl-review.googlesource.com/5810
Reviewed-by: Adam Langley <agl@google.com>
2015-09-03 18:37:39 +00:00
David Benjamin 809829ee9f Fix a typo in PORTING.md and mention one more renego restriction.
Change-Id: I59b30882178222000dd90b051856bb2816eeb9fd
Reviewed-on: https://boringssl-review.googlesource.com/5789
Reviewed-by: Adam Langley <agl@google.com>
2015-09-03 18:37:14 +00:00
David Benjamin 65703b45c4 Add a PORTING document which describes some major API differences.
There are a few things that differ in ways that are not source-compatible, so
it's probably worth documenting them.

Change-Id: I4ef26173a9347d9fd517c1b5215e08ced660b79d
Reviewed-on: https://boringssl-review.googlesource.com/5788
Reviewed-by: Adam Langley <agl@google.com>
2015-09-02 21:58:35 +00:00
David Benjamin ac8302a092 Don't set need_record_splitting until aead_write_ctx is set.
setup_key_block is called when the first CCS resolves, but for resumptions this
is the incoming CCS (see ssl3_do_change_cipher_spec). Rather than set
need_record_splitting there, it should be set in the write case of
tls1_change_cipher_state.

This fixes a crash from the new record layer code in resumption when
record-splitting is enabled. Tweak the record-splitting tests to cover this
case.

This also fixes a bug where renego from a cipher which does require record
splitting to one which doesn't continues splitting. Since version switches are
not allowed, this can only happen after a renego from CBC to RC4.

Change-Id: Ie4e1b91282b10f13887b51d1199f76be4fbf09ad
Reviewed-on: https://boringssl-review.googlesource.com/5787
Reviewed-by: Adam Langley <agl@google.com>
2015-09-01 22:30:48 +00:00
David Benjamin 4f75aaf661 Test various cases where plaintexts and ciphertexts are too large.
Note that DTLS treats oversized ciphertexts different from everything else.

Change-Id: I71cba69ebce0debdfc96a7fdeb2666252e8d28ed
Reviewed-on: https://boringssl-review.googlesource.com/5786
Reviewed-by: Adam Langley <agl@google.com>
2015-09-01 22:11:39 +00:00
David Benjamin 76c2efc0e9 Forbid a server from negotiating both ALPN and NPN.
If the two extensions select different next protocols (quite possible since one
is server-selected and the other is client-selected), things will break. This
matches the behavior of NSS (Firefox) and Go.

Change-Id: Ie1da97bf062b91a370c85c12bc61423220a22f36
Reviewed-on: https://boringssl-review.googlesource.com/5780
Reviewed-by: Adam Langley <agl@google.com>
2015-09-01 20:46:42 +00:00
David Benjamin 2c99d289fd Fix buffer size computation.
The maximum buffer size computation wasn't quite done right in
ssl_buffer.c, so we were failing with BUFFER_TOO_SMALL for sufficiently
large records. Fix this and, as penance, add 103 tests.

(Test that we can receive maximum-size records in all cipher suites.
Also test SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER while I'm here.)

BUG=526998

Change-Id: I714c16dda2ed13f49d8e6cd1b48adc5a8491f43c
Reviewed-on: https://boringssl-review.googlesource.com/5785
Reviewed-by: Adam Langley <agl@google.com>
2015-09-01 20:18:21 +00:00
David Benjamin 43c4d17230 Add X509_CRL_up_ref.
(Imported from upstream's 65cbf983ca4f69b8954f949c2edaaa48824481b3.)

Change-Id: I1e5d26ed8da5a44f68d22385b31d413628229c50
Reviewed-on: https://boringssl-review.googlesource.com/5784
Reviewed-by: Adam Langley <agl@google.com>
2015-09-01 19:12:56 +00:00
David Benjamin 5148345282 BN_mod_exp_mont_consttime: check for zero modulus.
Don't dereference |d| when |top| is zero. Also test that various BIGNUM
methods behave correctly on zero/even inputs.

(Imported from upstream's cf633fa00244e39eea2f2c0b623f7d5bbefa904e.)

We already had the BN_div and BN_MONT_CTX_set tests, but align them with
upstream's for consistency.

Change-Id: Ice5d04f559b4d5672e23c400637c07d8ee401727
Reviewed-on: https://boringssl-review.googlesource.com/5783
Reviewed-by: Adam Langley <agl@google.com>
2015-09-01 19:12:28 +00:00
David Benjamin fe71f1d4a5 Fix spurious bn_test failures.
BN_rand generates a single-word zero BIGNUM with quite a large
probability.

A zero BIGNUM in turn will end up having a NULL |d|-buffer, which we
shouldn't dereference without checking.

(Imported from upstream's 9c989aaa749d88b63bef5d5beeb3046eae62d836.)

Change-Id: Ic4d113e4fcf4ea4c0a4e905a1c4ba3fb758d9fc6
Reviewed-on: https://boringssl-review.googlesource.com/5782
Reviewed-by: Adam Langley <agl@google.com>
2015-09-01 19:10:01 +00:00
David Benjamin 8d100366e5 Fix dsa keygen for too-short seed
If the seed value for dsa key generation is too short (< qsize),
return an error.

(Imported from upstream's 1d7df236dcb4f7c95707110753e5e77b19b9a0aa and
df1565ed9cebb6933ee7c6e762abcfefd1cd3846.)

This switches the trigger for random seed from seed_len = 0 to seed_in =
NULL.

Change-Id: I2e07abed754c57ef9d96b02a52ba6d260c3f5fb9
Reviewed-on: https://boringssl-review.googlesource.com/5781
Reviewed-by: Adam Langley <agl@google.com>
2015-09-01 19:09:22 +00:00
David Benjamin ee0b02a10d Don't confuse TLS bidirectional shutdown on record type zero.
The bidi shutdown code uses type = 0 as a special signal value, but code
elsewhere doesn't account for this.

BUG=526437

Change-Id: I090cee421633d70ef3b84f4daa811608031b9ed9
Reviewed-on: https://boringssl-review.googlesource.com/5771
Reviewed-by: Adam Langley <agl@google.com>
2015-08-31 19:08:24 +00:00
David Benjamin e9cb2ec832 Don't support bidirectional shutdown over DTLS.
Bidirectional shutdown doesn't make sense over DTLS; you can't reuse the
underlying channel after receiving close_notify because the channel is
unordered. This removes one caller of dtls1_read_bytes.

Really close_notify makes no sense in DTLS. It can't even protect
against some kind of truncation because it's all unordered. But continue
to send it in case anything is (unreliably since the channel is lossy)
relying on close_notify to signal some kind of session end. This only
makes SSL_shutdown stop trying to wait for one once we've already
decided to shut down the connection.

BUG=526437

Change-Id: I6afad7cb7209c4aba0b96f9246b04c81d90987a9
Reviewed-on: https://boringssl-review.googlesource.com/5770
Reviewed-by: Adam Langley <agl@google.com>
2015-08-31 19:08:06 +00:00
David Benjamin 30789da28e Add tests for bidirectional shutdown.
Now that it even works at all (type = 0 bug aside), add tests for it.
Test both close_notify being received before and after SSL_shutdown is
called. In the latter case, have the peer send some junk to be ignored
to test that works.

Also test that SSL_shutdown fails on unclean shutdown and that quiet
shutdowns ignore it.

BUG=526437

Change-Id: Iff13b08feb03e82f21ecab0c66d5f85aec256137
Reviewed-on: https://boringssl-review.googlesource.com/5769
Reviewed-by: Adam Langley <agl@google.com>
2015-08-31 19:06:50 +00:00
David Benjamin aa9361bc66 Fix discarding records in bidirectional shutdown.
When discarding a record, it's important to start reading the next one,
or the state machine retry signaling doesn't work.

BUG=526437

Change-Id: I5e4a5155310d097c0033cdf5d06712410a01ee08
Reviewed-on: https://boringssl-review.googlesource.com/5768
Reviewed-by: Adam Langley <agl@google.com>
2015-08-31 18:55:49 +00:00
David Benjamin 885fc046a5 Fix memory leaks on error in x_x509a.c.
See also upstream's c8491de393639dbc4508306b7dbedb3872b74293.

Change-Id: I017fb137d6d93b6abb82fdb03f02be8292963d0d
Reviewed-on: https://boringssl-review.googlesource.com/5767
Reviewed-by: Adam Langley <agl@google.com>
2015-08-31 18:54:17 +00:00
David Benjamin 1f9f9c4b51 Tidy up the ssl3_send_server_key_exchange slightly.
The handshake state machine is still rather messy (we should switch to CBB,
split the key exchanges apart, and also pull reading and writing out), but this
version makes it more obvious to the compiler that |p| and |sig_len| are
initialized. The old logic created a synchronous-only state which, if enterred
directly, resulted in some variables being uninitialized.

Change-Id: Ia3ac9397d523fe299c50a95dc82a9b26304cea96
Reviewed-on: https://boringssl-review.googlesource.com/5765
Reviewed-by: Adam Langley <agl@google.com>
2015-08-28 22:53:43 +00:00
David Benjamin 6ca9355f25 runner: check bounds on packets in skipPacket.
Our tests shouldn't panic if the program misbehaves.

Change-Id: I113e050222bcf48e5f25883f860dbc1c5c77e77e
Reviewed-on: https://boringssl-review.googlesource.com/5764
Reviewed-by: Adam Langley <agl@google.com>
2015-08-28 22:49:43 +00:00
David Benjamin ed50cee007 Check fread's return value in tool/server.cc.
Some compilers complain and it's worth checking. Maybe the file changed in size
between ftell and fread.

Change-Id: I7898b8517556ec6899bd6e8866ba3d1cd7efd5f4
Reviewed-on: https://boringssl-review.googlesource.com/5763
Reviewed-by: Adam Langley <agl@google.com>
2015-08-28 22:47:26 +00:00
David Benjamin ffadb3969f fread returns a size_t, not int.
Change-Id: I305fd40a887b1dedf23eeddfb5231fc61b355ea8
Reviewed-on: https://boringssl-review.googlesource.com/5762
Reviewed-by: Adam Langley <agl@google.com>
2015-08-28 22:46:40 +00:00
David Benjamin 26416e9dde Remove the last of SESS_CERT.
Move cert_chain to the SSL_SESSION. Now everything on an SSL_SESSION is
properly serialized. The cert_chain field is, unfortunately, messed up
since it means different things between client and server.

There exists code which calls SSL_get_peer_cert_chain as both client and
server and assumes the existing semantics for each. Since that function
doesn't return a newly-allocated STACK_OF(X509), normalizing between the
two formats is a nuisance (we'd either need to store both cert_chain and
cert_chain_full on the SSL_SESSION or create one of the two variants
on-demand and stash it into the SSL).

This CL does not resolve this and retains the client/server difference
in SSL_SESSION. The SSL_SESSION serialization is a little inefficient
(two copies of the leaf certificate) for a client, but clients don't
typically serialize sessions. Should we wish to resolve it in the
future, we can use a different tag number. Because this was historically
unserialized, existing code must already allow for cert_chain not being
preserved across i2d/d2i.

In keeping with the semantics of retain_only_sha256_of_client_certs,
cert_chain is not retained when that flag is set.

Change-Id: Ieb72fc62c3076dd59750219e550902f1ad039651
Reviewed-on: https://boringssl-review.googlesource.com/5759
Reviewed-by: Adam Langley <agl@google.com>
2015-08-28 22:45:59 +00:00
David Benjamin a1fadd399f Fix MSVC build.
The difference of two pointers is signed, even though it's always
non-negative here, so MSVC is complaining about signedness mismatch.

Change-Id: I5a042d06ed348540706b93310af3f60f3ab5f303
Reviewed-on: https://boringssl-review.googlesource.com/5766
Reviewed-by: Adam Langley <agl@google.com>
2015-08-28 22:27:33 +00:00
David Benjamin 8be79a3355 Slightly refactor SSL_SESSION parsing.
Rather than parse the fields in two passes, group the code relating to
one field together. Somewhat less annoying to add new fields. To keep
this from getting too unwieldy, add a few more helper functions for the
common field types.

Change-Id: Ia86c6bbca9dd212d5c35029363ea4d6b6426164a
Reviewed-on: https://boringssl-review.googlesource.com/5758
Reviewed-by: Adam Langley <agl@google.com>
2015-08-28 22:18:17 +00:00
David Benjamin b1bdc5b325 Remove peer_cert from SESS_CERT.
It's completely redundant with the copy in the SSL_SESSION except it
isn't serialized.

Change-Id: I1d95a14cae064c599e4bab576df1dd156da4b81c
Reviewed-on: https://boringssl-review.googlesource.com/5757
Reviewed-by: Adam Langley <agl@google.com>
2015-08-28 22:06:21 +00:00
David Benjamin 6505567172 Move peer_dh_tmp and peer_ecdh_tmp out of SESS_CERT.
Gets another field out of the SSL_SESSION.

Change-Id: I9a27255533f8e43e152808427466ec1306cfcc60
Reviewed-on: https://boringssl-review.googlesource.com/5756
Reviewed-by: Adam Langley <agl@google.com>
2015-08-28 22:05:53 +00:00
David Benjamin 621f95a3ea Add -session-in and -session-out to bssl client.
This is analogous to openssl s_client's -sess_in and -sess_out. Use PEM to
align with OpenSSL. This is useful for debugging session resumption and also
generating things to test serialization against.

Change-Id: Idc58e8fa3dd4c2385f6a2d647e66ef11427be60d
Reviewed-on: https://boringssl-review.googlesource.com/5761
Reviewed-by: Adam Langley <agl@google.com>
2015-08-28 22:04:30 +00:00
David Benjamin ba13402c1b Fix the type of ASN1_i2d_bio's last argument.
It's supposed to be void*. The only reason this was working was that it was
only called in C which happily casts from void* to T*. (But if called in C++ in
a macro, it breaks.)

Change-Id: I7f765c3572b9b4815ae58da852be1e742de1bd96
Reviewed-on: https://boringssl-review.googlesource.com/5760
Reviewed-by: Adam Langley <agl@google.com>
2015-08-28 22:03:54 +00:00
David Benjamin 4cf369b920 Reject empty records of unexpected type.
The old empty record logic discarded the records at a very low-level.
Let the error bubble up to ssl3_read_bytes so the type mismatch logic
may kick in before the empty record is skipped.

Add tests for when the record in question is application data, before
before the handshake and post ChangeCipherSpec.

BUG=521840

Change-Id: I47dff389cda65d6672b9be39d7d89490331063fa
Reviewed-on: https://boringssl-review.googlesource.com/5754
Reviewed-by: Adam Langley <agl@google.com>
2015-08-28 22:03:00 +00:00
David Benjamin b8d28cf532 Factor out the buffering and low-level record code.
This begins decoupling the transport from the SSL state machine. The buffering
logic is hidden behind an opaque API. Fields like ssl->packet and
ssl->packet_length are gone.

ssl3_get_record and dtls1_get_record now call low-level tls_open_record and
dtls_open_record functions that unpack a single record independent of who owns
the buffer. Both may be called in-place. This removes ssl->rstate which was
redundant with the buffer length.

Future work will push the buffer up the stack until it is above the handshake.
Then we can expose SSL_open and SSL_seal APIs which act like *_open_record but
return a slightly larger enum due to other events being possible. Likewise the
handshake state machine will be detached from its buffer. The existing
SSL_read, SSL_write, etc., APIs will be implemented on top of SSL_open, etc.,
combined with ssl_read_buffer_* and ssl_write_buffer_*. (Which is why
ssl_read_buffer_extend still tries to abstract between TLS's and DTLS's fairly
different needs.)

The new buffering logic does not support read-ahead (removed previously) since
it lacks a memmove on ssl_read_buffer_discard for TLS, but this could be added
if desired. The old buffering logic wasn't quite right anyway; it tried to
avoid the memmove in some cases and could get stuck too far into the buffer and
not accept records. (The only time the memmove is optional is in DTLS or if
enough of the record header is available to know that the entire next record
would fit in the buffer.)

The new logic also now actually decrypts the ciphertext in-place again, rather
than almost in-place when there's an explicit nonce/IV. (That accidentally
switched in https://boringssl-review.googlesource.com/#/c/4792/; see
3d59e04bce96474099ba76786a2337e99ae14505.)

BUG=468889

Change-Id: I403c1626253c46897f47c7ae93aeab1064b767b2
Reviewed-on: https://boringssl-review.googlesource.com/5715
Reviewed-by: Adam Langley <agl@google.com>
2015-08-28 22:01:02 +00:00
Matt Braithwaite e000472166 pkcs8.c: Add PBES2 to list of password-based encryption methods.
This consists mostly of re-adding OpenSSL's implementation of PBKDF2
(very loosely based upon e0d26bb3).  The meat of it, namely
|PKCS5_PBKDF2_HMAC|, was already present, but unused.

In addition, |PKCS8_encrypt| and |PKCS8_decrypt| must be changed to
not perform UCS-2 conversion in the PBES2 case.

Change-Id: Id170ecabc43c79491600051147d1d6d3c7273dbc
Reviewed-on: https://boringssl-review.googlesource.com/5745
Reviewed-by: Adam Langley <agl@google.com>
2015-08-28 20:33:33 +00:00
Adam Langley 73415b6aa0 Move arm_arch.h and fix up lots of include paths.
arm_arch.h is included from ARM asm files, but lives in crypto/, not
openssl/include/. Since the asm files are often built from a different
location than their position in the source tree, relative include paths
are unlikely to work so, rather than having crypto/ be a de-facto,
second global include path, this change moves arm_arch.h to
include/openssl/.

It also removes entries from many include paths because they should be
needed as relative includes are always based on the locations of the
source file.

Change-Id: I638ff43d641ca043a4fc06c0d901b11c6ff73542
Reviewed-on: https://boringssl-review.googlesource.com/5746
Reviewed-by: Adam Langley <agl@google.com>
2015-08-26 01:57:59 +00:00
David Benjamin 61821bf149 Add EVP_AEAD_CTX_zero.
Match the other stack-allocated types in that we expose a wrapper function to
get them into the zero state. Makes it more amenable to templates like
ScopedOpenSSLContext.

Change-Id: Ibc7b2b1bc0421ce5ccc84760c78c0b143441ab0f
Reviewed-on: https://boringssl-review.googlesource.com/5753
Reviewed-by: Adam Langley <agl@google.com>
2015-08-24 23:37:58 +00:00
David Benjamin be8a869d96 Fill in alg_bits for CHACHA20_POLY1305 ciphers.
Apparently we left those as zero. Oh well. This only affects
SSL_CIPHER_get_bits, but so long as we have the field, it ought to be correct.

Change-Id: I2878ec22c2f5a6263f805e04d9fd8448994639b7
Reviewed-on: https://boringssl-review.googlesource.com/5752
Reviewed-by: Adam Langley <agl@google.com>
2015-08-24 23:36:56 +00:00
David Benjamin f2aa1e1a71 Remove Go implementation of non-standard ECDHE_PSK_WITH_AES_128_GCM_SHA256.
The BoringSSL implementation was removed in
https://boringssl-review.googlesource.com/5051. No need to have the runner half
around.

Change-Id: I49857f4d01be161df89fb7df93a83240b6a8cb02
Reviewed-on: https://boringssl-review.googlesource.com/5751
Reviewed-by: Adam Langley <agl@google.com>
2015-08-24 23:35:43 +00:00
David Benjamin ec4353498c Remove DHE_RSA_WITH_CHACHA20_POLY1305.
This made sense when the cipher might have been standardized as-is, so a
DHE_RSA variant could appease the IETF. Since the standardized variant is going
to have some nonce tweaks anyway, there's no sense in keeping this around. Get
rid of one non-standard cipher suite value early. (Even if they were to be
standardized as-is, it's not clear we should implement new DHE cipher suites at
this point.)

Chrome UMA, unsurprisingly, shows that it's unused.

Change-Id: Id83d73a4294b470ec2e94d5308fba135d6eeb228
Reviewed-on: https://boringssl-review.googlesource.com/5750
Reviewed-by: Adam Langley <agl@google.com>
2015-08-24 23:35:25 +00:00
Matt Braithwaite c4ef5ff112 In |NCONF_load|, strdup section names rather than adding refs.
The fact that |value_free| expects to free() value->section is
inconsistent with the behavior of |add_string|, which adds a reference
to an existing string.

Along the way, add a |CONF_VALUE_new| method to simplify things a bit.

Change-Id: I438abc80575394e4d8df62a4fe2ff1050e3ba039
Reviewed-on: https://boringssl-review.googlesource.com/5744
Reviewed-by: Adam Langley <agl@google.com>
2015-08-24 22:08:08 +00:00
Matt Braithwaite 50485c7c0c Fix a memory leak in |NCONF_free|.
As I read it:

1. |_LHASH| contains
2.   buckets of |LHASH_ITEMS|, which contain
3.     |CONF_VALUE|s, which contain
4.       various bits of data.

The previous code was freeing #1 and #2 in |lh_free|, and #4 in
|value_free_contents|, but was failing to free the |CONF_VALUE|s
themselves.  The fix is to call |value_free| rather than
|value_free_contents|.

Change-Id: I1d5b48692ca9ac04df688e45d7fc113dc5cd6ddf
Reviewed-on: https://boringssl-review.googlesource.com/5742
Reviewed-by: Adam Langley <agl@google.com>
2015-08-24 20:30:06 +00:00
Matt Braithwaite 685402fadd Recognize PEM-encoded DSA private keys.
This change makes |EVP_PKEY_asn1_find_str|, which is used by
|PEM_read_bio_PrivateKey|, recognize "DSA" as well as "EC" and "RSA".

Change-Id: I39cce12f600cec6a71df75312a41f8395429af62
Reviewed-on: https://boringssl-review.googlesource.com/5743
Reviewed-by: Adam Langley <agl@google.com>
2015-08-21 17:39:05 +00:00
Matt Braithwaite e9c283025e Use |OPENSSL_strdup| instead of insane alternatives.
Change-Id: I1e6fd4abb7709d53f3663b1626f0bc147b9cd453
Reviewed-on: https://boringssl-review.googlesource.com/5741
Reviewed-by: Adam Langley <agl@google.com>
2015-08-21 00:58:28 +00:00
Adam Langley 28bc6eba28 Don't use the uint128_t P-256 code under MSAN.
MSAN appears to have a bug that causes this code to be miscompiled when
compiled with optimisations. In order to prevent that bug from holding
everything up, this change disables that code when MEMORY_SANITIZER is
defined. The generic elliptic-curve code can pick up the slack in that
case.

Change-Id: I7ce26969b3ee0bc0b0496506f06a8cf9b2523cfa
2015-08-20 15:15:30 -07:00
Matt Braithwaite 4838d8aa90 Add do-nothing function |ERR_load_SSL_strings|.
This benefits pyOpenSSL.

Change-Id: Ie7a35d6f9e9a1f0c7fe42ba105c68c327f7d0b0e
Reviewed-on: https://boringssl-review.googlesource.com/5740
Reviewed-by: Adam Langley <agl@google.com>
2015-08-20 21:33:50 +00:00
Matt Braithwaite d82a7b24be Re-add |EVP_des_ede|, which is ECB.
(I couldn't find an authoritative source of test data, including in
OpenSSL's source, so I used OpenSSL's implementation to produce the
test ciphertext.)

This benefits globalplatform.

Change-Id: Ifb79e77afb7efed1c329126a1a459bbf7ce6ca00
Reviewed-on: https://boringssl-review.googlesource.com/5725
Reviewed-by: Adam Langley <agl@google.com>
2015-08-20 21:33:21 +00:00
Matt Braithwaite 8c413a2d94 Re-add |EVP_des_ede_cbc|.
Note that while |DES_ede2_cbc_encrypt| exists, I didn't use it: I
think it's easier to see what's happening this way.

(I couldn't find an authoritative source of test data, including in
OpenSSL's source, so I used OpenSSL's implementation to produce the
test ciphertext.)

This benefits globalplatform.

Change-Id: I7e17ca0b69067d7b3f4bc213b4616eb269882ae0
Reviewed-on: https://boringssl-review.googlesource.com/5724
Reviewed-by: Adam Langley <agl@google.com>
2015-08-20 21:11:20 +00:00
Adam Langley 6a2de3c1d4 Don't use a C99 for loop.
Because it's 2015 and we can't depend on C99 support yet.

Change-Id: Ie33fddc2a27024d4d3d50dea725062b59670a060
2015-08-20 14:03:31 -07:00
Matt Braithwaite 98d2f1fbe0 Add |EVP_des_ecb| from OpenSSL at fd682e4c.
|DES_ecb_encrypt| was already present.

This benefits globalplatform.

Change-Id: I2ab41eb1936b3026439b5981fb27e29a12672b66
Reviewed-on: https://boringssl-review.googlesource.com/5723
Reviewed-by: Adam Langley <agl@google.com>
2015-08-20 20:57:00 +00:00
Paul Lietar aeeff2ceee Server-side OCSP stapling support.
This is a simpler implementation than OpenSSL's, lacking responder IDs
and request extensions support. This mirrors the client implementation
already present.

Change-Id: I54592b60e0a708bfb003d491c9250401403c9e69
Reviewed-on: https://boringssl-review.googlesource.com/5700
Reviewed-by: Adam Langley <agl@google.com>
2015-08-20 17:55:31 +00:00
2489 changed files with 106338 additions and 57565 deletions
+7
View File
@@ -0,0 +1,7 @@
Please do not send pull requests to the BoringSSL repository.
We do, however, take contributions gladly.
See https://boringssl.googlesource.com/boringssl/+/master/CONTRIBUTING.md
Thanks!
-97
View File
@@ -1,97 +0,0 @@
Build Prerequisites:
* CMake[1] 2.8.8 or later is required.
* Perl 5.6.1 or later is required. On Windows, Strawberry Perl and MSYS Perl
have both been reported to work. If not found by CMake, it may be configured
explicitly by setting PERL_EXECUTABLE.
* On Windows you currently must use Ninja[2] to build; on other platforms,
it is not required, but recommended, because it makes builds faster.
* If you need to build Ninja from source, then a recent version of
Python[3] is required (Python 2.7.5 works).
* On Windows only, Yasm[4] is required. If not found by CMake, it may be
configured explicitly by setting CMAKE_ASM_NASM_COMPILER.
* A C compiler is required. On Windows, MSVC 12 (Visual Studio 2013) or later
with Platform SDK 8.1 or later are supported. Recent versions of GCC and
Clang should work on non-Windows platforms, and maybe on Windows too.
* Go[5] is required. If not found by CMake, the go executable may be
configured explicitly by setting GO_EXECUTABLE.
Using Ninja (note the 'N' is capitalized in the cmake invocation):
mkdir build
cd build
cmake -GNinja ..
ninja
Using makefiles (does not work on Windows):
mkdir build
cd build
cmake ..
make
You usually don't need to run cmake again after changing CMakeLists.txt files
because the build scripts will detect changes to them and rebuild themselves
automatically.
Note that the default build flags in the top-level CMakeLists.txt are for
debugging - optimisation isn't enabled.
If you want to cross-compile then there is an example toolchain file for
32-bit Intel in util/. Wipe out the build directory, recreate it and run cmake
like this:
cmake -DCMAKE_TOOLCHAIN_FILE=../util/32-bit-toolchain.cmake -GNinja ..
If you want to build as a shared library, pass -DBUILD_SHARED_LIBS=1. On
Windows, where functions need to be tagged with "dllimport" when coming from a
shared library, define BORINGSSL_SHARED_LIBRARY in any code which #includes the
BoringSSL headers.
Building for Android:
It's possible to build BoringSSL with the Android NDK using CMake. This has
been tested with version 10d of the NDK.
Unpack the Android NDK somewhere and export ANDROID_NDK to point to the
directory. Clone https://github.com/taka-no-me/android-cmake into util/.
Then make a build directory as above and run CMake *twice* like this:
cmake -DANDROID_NATIVE_API_LEVEL=android-9 \
-DANDROID_ABI=armeabi-v7a \
-DCMAKE_TOOLCHAIN_FILE=../util/android-cmake/android.toolchain.cmake \
-DANDROID_NATIVE_API_LEVEL=16 \
-GNinja ..
Once you've run that twice, ninja should produce Android-compatible binaries.
You can replace "armeabi-v7a" in the above with "arm64-v8a" to build aarch64
binaries.
Known Limitations on Windows:
* Versions of cmake since 3.0.2 have a bug in its Ninja generator that causes
yasm to output warnings "yasm: warning: can open only one input file, only
the last file will be processed". These warnings can be safely ignored.
The cmake bug is http://www.cmake.org/Bug/view.php?id=15253.
* cmake can generate Visual Studio projects, but the generated project files
don't have steps for assembling the assembly language source files, so they
currently cannot be used to build BoringSSL.
[1] http://www.cmake.org/download/
[2] https://martine.github.io/ninja/
[3] https://www.python.org/downloads/
[4] http://yasm.tortall.net/
[5] https://golang.org/dl/
+141
View File
@@ -0,0 +1,141 @@
# Building BoringSSL
## Build Prerequisites
* [CMake](https://cmake.org/download/) 2.8.8 or later is required.
* Perl 5.6.1 or later is required. On Windows,
[Active State Perl](http://www.activestate.com/activeperl/) has been
reported to work, as has MSYS Perl.
[Strawberry Perl](http://strawberryperl.com/) also works but it adds GCC
to `PATH`, which can confuse some build tools when identifying the compiler
(removing `C:\Strawberry\c\bin` from `PATH` should resolve any problems).
If Perl is not found by CMake, it may be configured explicitly by setting
`PERL_EXECUTABLE`.
* On Windows you currently must use [Ninja](https://ninja-build.org/)
to build; on other platforms, it is not required, but recommended, because
it makes builds faster.
* If you need to build Ninja from source, then a recent version of
[Python](https://www.python.org/downloads/) is required (Python 2.7.5 works).
* On Windows only, [Yasm](http://yasm.tortall.net/) is required. If not found
by CMake, it may be configured explicitly by setting
`CMAKE_ASM_NASM_COMPILER`.
* A C compiler is required. On Windows, MSVC 12 (Visual Studio 2013) or later
with Platform SDK 8.1 or later are supported. Recent versions of GCC (4.8+)
and Clang should work on non-Windows platforms, and maybe on Windows too.
* [Go](https://golang.org/dl/) is required. If not found by CMake, the go
executable may be configured explicitly by setting `GO_EXECUTABLE`.
## Building
Using Ninja (note the 'N' is capitalized in the cmake invocation):
mkdir build
cd build
cmake -GNinja ..
ninja
Using Make (does not work on Windows):
mkdir build
cd build
cmake ..
make
You usually don't need to run `cmake` again after changing `CMakeLists.txt`
files because the build scripts will detect changes to them and rebuild
themselves automatically.
Note that the default build flags in the top-level `CMakeLists.txt` are for
debugging—optimisation isn't enabled. Pass `-DCMAKE_BUILD_TYPE=Release` to
`cmake` to configure a release build.
If you want to cross-compile then there is an example toolchain file for 32-bit
Intel in `util/`. Wipe out the build directory, recreate it and run `cmake` like
this:
cmake -DCMAKE_TOOLCHAIN_FILE=../util/32-bit-toolchain.cmake -GNinja ..
If you want to build as a shared library, pass `-DBUILD_SHARED_LIBS=1`. On
Windows, where functions need to be tagged with `dllimport` when coming from a
shared library, define `BORINGSSL_SHARED_LIBRARY` in any code which `#include`s
the BoringSSL headers.
In order to serve environments where code-size is important as well as those
where performance is the overriding concern, `OPENSSL_SMALL` can be defined to
remove some code that is especially large.
See [CMake's documentation](https://cmake.org/cmake/help/v3.4/manual/cmake-variables.7.html)
for other variables which may be used to configure the build.
### Building for Android
It's possible to build BoringSSL with the Android NDK using CMake. This has
been tested with version 10d of the NDK.
Unpack the Android NDK somewhere and export `ANDROID_NDK` to point to the
directory. Clone https://github.com/taka-no-me/android-cmake into `util/`. Then
make a build directory as above and run CMake *twice* like this:
cmake -DANDROID_NATIVE_API_LEVEL=android-9 \
-DANDROID_ABI=armeabi-v7a \
-DCMAKE_TOOLCHAIN_FILE=../util/android-cmake/android.toolchain.cmake \
-DANDROID_NATIVE_API_LEVEL=16 \
-GNinja ..
Once you've run that twice, Ninja should produce Android-compatible binaries.
You can replace `armeabi-v7a` in the above with `arm64-v8a` to build aarch64
binaries.
## Known Limitations on Windows
* Versions of CMake since 3.0.2 have a bug in its Ninja generator that causes
yasm to output warnings
yasm: warning: can open only one input file, only the last file will be processed
These warnings can be safely ignored. The cmake bug is
http://www.cmake.org/Bug/view.php?id=15253.
* CMake can generate Visual Studio projects, but the generated project files
don't have steps for assembling the assembly language source files, so they
currently cannot be used to build BoringSSL.
## Embedded ARM
ARM, unlike Intel, does not have an instruction that allows applications to
discover the capabilities of the processor. Instead, the capability information
has to be provided by the operating system somehow.
BoringSSL will try to use `getauxval` to discover the capabilities and, failing
that, will probe for NEON support by executing a NEON instruction and handling
any illegal-instruction signal. But some environments don't support that sort
of thing and, for them, it's possible to configure the CPU capabilities
at compile time.
If you define `OPENSSL_STATIC_ARMCAP` then you can define any of the following
to enabling the corresponding ARM feature.
* `OPENSSL_STATIC_ARMCAP_NEON` or `__ARM_NEON__` (note that the latter is set by compilers when NEON support is enabled).
* `OPENSSL_STATIC_ARMCAP_AES`
* `OPENSSL_STATIC_ARMCAP_SHA1`
* `OPENSSL_STATIC_ARMCAP_SHA256`
* `OPENSSL_STATIC_ARMCAP_PMULL`
Note that if a feature is enabled in this way, but not actually supported at
run-time, BoringSSL will likely crash.
# Running tests
There are two sets of tests: the C/C++ tests and the blackbox tests. For former
are built by Ninja and can be run from the top-level directory with `go run
util/all_tests.go`. The latter have to be run separately by running `go test`
from within `ssl/test/runner`.
Both sets of tests may also be run with `ninja -C build run_tests`, but CMake
3.2 or later is required to avoid Ninja's output buffering.
+69 -6
View File
@@ -1,6 +1,16 @@
cmake_minimum_required (VERSION 2.8.10)
project (BoringSSL)
# Defer enabling C and CXX languages.
project (BoringSSL NONE)
if(WIN32)
# On Windows, prefer cl over gcc if both are available. By default most of
# the CMake generators prefer gcc, even on Windows.
set(CMAKE_GENERATOR_CC cl)
endif()
enable_language(C)
enable_language(CXX)
if(ANDROID)
# Android-NDK CMake files reconfigure the path and so Go and Perl won't be
@@ -17,15 +27,15 @@ if (NOT GO_EXECUTABLE)
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -ggdb -fvisibility=hidden")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -ggdb -std=c++0x -fvisibility=hidden")
set(C_CXX_FLAGS "-Wall -Werror -Wformat=2 -Wsign-compare -Wmissing-field-initializers -ggdb -fvisibility=hidden")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_CXX_FLAGS} -Wmissing-prototypes")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x ${C_CXX_FLAGS} -Wmissing-declarations")
elseif(MSVC)
set(MSVC_DISABLED_WARNINGS_LIST
"C4100" # 'exarg' : unreferenced formal parameter
"C4127" # conditional expression is constant
"C4200" # nonstandard extension used : zero-sized array in
# struct/union.
"C4210" # nonstandard extension used : function given file scope
"C4242" # 'function' : conversion from 'int' to 'uint8_t',
# possible loss of data
"C4244" # 'function' : conversion from 'int' to 'uint8_t',
@@ -61,10 +71,25 @@ elseif(MSVC)
"C4996" # 'read': The POSIX name for this item is deprecated. Instead,
# use the ISO C++ conformant name: _read.
)
if(NOT(CMAKE_C_COMPILER_VERSION VERSION_LESS "19.0.23506"))
# MSVC 2015 Update 1.
set(MSVC_DISABLED_WARNINGS_LIST
${MSVC_DISABLED_WARNINGS_LIST}
"C4464" # relative include path contains '..'
"C4623" # default constructor was implicitly defined as deleted
"C5027" # move assignment operator was implicitly defined as deleted
)
set(MSVC_LEVEL4_WARNINGS_LIST
# See https://connect.microsoft.com/VisualStudio/feedback/details/1217660/warning-c4265-when-using-functional-header
"C4265" # class has virtual functions, but destructor is not virtual
)
string(REPLACE "C" " -w4" MSVC_LEVEL4_WARNINGS_STR
${MSVC_LEVEL4_WARNINGS_LIST})
endif()
string(REPLACE "C" " -wd" MSVC_DISABLED_WARNINGS_STR
${MSVC_DISABLED_WARNINGS_LIST})
set(CMAKE_C_FLAGS "-Wall -WX ${MSVC_DISABLED_WARNINGS_STR}")
set(CMAKE_CXX_FLAGS "-Wall -WX ${MSVC_DISABLED_WARNINGS_STR}")
set(CMAKE_C_FLAGS "-Wall -WX ${MSVC_DISABLED_WARNINGS_STR} ${MSVC_LEVEL4_WARNINGS_STR}")
set(CMAKE_CXX_FLAGS "-Wall -WX ${MSVC_DISABLED_WARNINGS_STR} ${MSVC_LEVEL4_WARNINGS_STR}")
add_definitions(-D_HAS_EXCEPTIONS=0)
add_definitions(-DWIN32_LEAN_AND_MEAN)
add_definitions(-DNOMINMAX)
@@ -81,6 +106,20 @@ if((CMAKE_COMPILER_IS_GNUCXX AND CMAKE_C_COMPILER_VERSION VERSION_GREATER "4.8.9
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -D_XOPEN_SOURCE=700")
endif()
if(FUZZ)
if(!CMAKE_CXX_COMPILER_ID MATCHES "Clang")
message("You need to build with Clang for fuzzing to work")
endif()
add_definitions(-DBORINGSSL_UNSAFE_FUZZER_MODE)
set(RUNNER_ARGS "-fuzzer")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fsanitize-coverage=edge,indirect-calls,8bit-counters")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fsanitize-coverage=edge,indirect-calls,8bit-counters")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
link_directories(.)
endif()
add_definitions(-DBORINGSSL_IMPLEMENTATION)
if (BUILD_SHARED_LIBS)
@@ -138,8 +177,32 @@ if (OPENSSL_NO_ASM)
set(ARCH "generic")
endif()
# Declare a dummy target to build all unit tests. Test targets should inject
# themselves as dependencies next to the target definition.
add_custom_target(all_tests)
add_subdirectory(crypto)
add_subdirectory(ssl)
add_subdirectory(ssl/test)
add_subdirectory(tool)
add_subdirectory(decrepit)
if(FUZZ)
add_subdirectory(fuzz)
endif()
if (NOT ${CMAKE_VERSION} VERSION_LESS "3.2")
# USES_TERMINAL is only available in CMake 3.2 or later.
set(MAYBE_USES_TERMINAL USES_TERMINAL)
endif()
add_custom_target(
run_tests
COMMAND ${GO_EXECUTABLE} run util/all_tests.go -build-dir
${CMAKE_BINARY_DIR}
COMMAND cd ssl/test/runner
COMMAND ${GO_EXECUTABLE} test -shim-path $<TARGET_FILE:bssl_shim>
${RUNNER_ARGS}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
DEPENDS all_tests bssl_shim
${MAYBE_USES_TERMINAL})
+49
View File
@@ -0,0 +1,49 @@
Want to contribute? Great! First, read this page (including the small print at the end).
### Before you contribute
Before we can use your code, you must sign the
[Google Individual Contributor License Agreement](https://cla.developers.google.com/about/google-individual)
(CLA), which you can do online. The CLA is necessary mainly because you own the
copyright to your changes, even after your contribution becomes part of our
codebase, so we need your permission to use and distribute your code. We also
need to be sure of various other things—for instance that you'll tell us if you
know that your code infringes on other people's patents. You don't have to sign
the CLA until after you've submitted your code for review and a member has
approved it, but you must do it before we can put your code into our codebase.
Before you start working on a larger contribution, you should get in touch with
us first via email with your idea so that we can help out and possibly guide
you. Coordinating up front makes it much easier to avoid frustration later on.
### Code reviews
All submissions, including submissions by project members, require review. We
use [Gerrit](https://boringssl-review.googlesource.com) for this purpose.
#### Setup
If you have not done so on this machine, you will need to set up a password for
Gerrit. Sign in with a Google account, visit
[this link](https://boringssl.googlesource.com/), and click the "Generate
Password" link in the top right. You will also need to prepare your checkout to
[add Change-Ids](https://gerrit-review.googlesource.com/Documentation/cmd-hook-commit-msg.html)
on commit. Run:
curl -Lo .git/hooks/commit-msg https://boringssl-review.googlesource.com/tools/hooks/commit-msg
chmod u+x .git/hooks/commit-msg
#### Uploading changes
To upload a change, push it to the special `refs/for/master` target:
git push origin HEAD:refs/for/master
The output will then give you a link to the change. Add `agl@google.com` and
`davidben@google.com` as reviewers.
Pushing a commit with the same Change-Id as an existing change will upload a new
version of it. (Use the `git rebase` or `git commit --amend` commands.)
For more detailed instructions, see the
[Gerrit User Guide](https://gerrit-review.googlesource.com/Documentation/intro-user.html).
### The small print
Contributions made by corporations are covered by a different agreement than
the one above, the
[Software Grant and Corporate Contributor License Agreement](https://cla.developers.google.com/about/google-corporate).
+51
View File
@@ -0,0 +1,51 @@
# Fuzz testing
Modern fuzz testers are very effective and we wish to use them to ensure that no silly bugs creep into BoringSSL.
We primarily use Clang's [libFuzzer](http://llvm.org/docs/LibFuzzer.html) for fuzz testing and there are a number of fuzz testing functions in `fuzz/`. They are not built by default because they require libFuzzer at build time.
In order to build the fuzz tests you will need at least Clang 3.7. Pass `-DFUZZ=1` on the CMake command line to enable building BoringSSL with coverage and AddressSanitizer, and to build the fuzz test binaries. You'll probably need to set the `CC` and `CXX` environment variables too, like this:
```
CC=clang CXX=clang++ cmake -GNinja -DFUZZ=1 ..
```
In order for the fuzz tests to link, the linker needs to find libFuzzer. This is not commonly provided and you may need to download the [Clang source code](http://llvm.org/releases/download.html) and do the following:
```
svn co http://llvm.org/svn/llvm-project/llvm/trunk/lib/Fuzzer
clang++ -c -g -O2 -std=c++11 Fuzzer/*.cpp -IFuzzer
ar ruv libFuzzer.a Fuzzer*.o
```
Then copy `libFuzzer.a` to the top-level of your BoringSSL source directory.
From the `build/` directory, you can then run the fuzzers. For example:
```
./fuzz/cert -max_len=3072 -jobs=32 -workers=32 ../fuzz/cert_corpus/
```
The arguments to `jobs` and `workers` should be the number of cores that you wish to dedicate to fuzzing. By default, libFuzzer uses the largest test in the corpus (or 64 if empty) as the maximum test case length. The `max_len` argument overrides this.
The recommended values of `max_len` for each test may be found in `.options` files alongside the test source. These were determined by rounding up the length of the largest case in the corpus. When writing a new fuzzer, configure `max_len` in a similar file.
There are directories in `fuzz/` for each of the fuzzing tests which contain seed files for fuzzing. Some of the seed files were generated manually but many of them are “interesting” results generated by the fuzzing itself. (Where “interesting” means that it triggered a previously unknown path in the code.)
## Minimising the corpuses
When a large number of new seeds are available, it's a good idea to minimise the corpus so that different seeds that trigger the same code paths can be deduplicated.
In order to minimise all the corpuses, build for fuzzing and run `./fuzz/minimise_corpuses.sh`. Note that minimisation is, oddly, often not idempotent for unknown reasons.
## Fuzzer mode
When `-DFUZZ=1` is passed into CMake, BoringSSL builds with `BORINGSSL_UNSAFE_FUZZER_MODE` defined. This modifies the library, particularly the TLS stack, to be more friendly to fuzzers. It will:
* Replace `RAND_bytes` with a deterministic PRNG. Call `RAND_reset_for_fuzzing()` at the start of fuzzers which use `RAND_bytes` to reset the PRNG state.
* Modify the TLS stack to perform all signature checks (CertificateVerify and ServerKeyExchange) and the Finished check, but always act as if the check succeeded.
* Treat every cipher as the NULL cipher.
This is to prevent the fuzzer from getting stuck at a cryptographic invariant in the protocol.
+7
View File
@@ -14,6 +14,13 @@ for the actual license texts. Actually both licenses are BSD-style Open Source
licenses. In case of any license issues related to OpenSSL please contact
openssl-core@openssl.org.
The following are Google-internal bug numbers where explicit permission from
some authors is recorded for use of their work. (This is purely for our own
record keeping.)
27287199
27287880
27287883
OpenSSL License
---------------
+187
View File
@@ -0,0 +1,187 @@
# Porting from OpenSSL to BoringSSL
BoringSSL is an OpenSSL derivative and is mostly source-compatible, for the
subset of OpenSSL retained. Libraries ideally need little to no changes for
BoringSSL support, provided they do not use removed APIs. In general, see if the
library compiles and, on failure, consult the documentation in the header files
and see if problematic features can be removed.
In some cases, BoringSSL-specific code may be necessary. In that case, the
`OPENSSL_IS_BORINGSSL` preprocessor macro may be used in `#ifdef`s. This macro
should also be used in lieu of the presence of any particular function to detect
OpenSSL vs BoringSSL in configure scripts, etc., where those are necessary.
For convenience, BoringSSL defines upstream's `OPENSSL_NO_*` feature macros
corresponding to removed features. These may also be used to disable code which
uses a removed feature.
Note: BoringSSL does *not* have a stable API or ABI. It must be updated with its
consumers. It is not suitable for, say, a system library in a traditional Linux
distribution. For instance, Chromium statically links the specific revision of
BoringSSL it was built against. Likewise, Android's system-internal copy of
BoringSSL is not exposed by the NDK and must not be used by third-party
applications.
## Major API changes
### Integer types
Some APIs have been converted to use `size_t` for consistency and to avoid
integer overflows at the API boundary. (Existing logic uses a mismash of `int`,
`long`, and `unsigned`.) For the most part, implicit casts mean that existing
code continues to compile. In some cases, this may require BoringSSL-specific
code, particularly to avoid compiler warnings.
Most notably, the `STACK_OF(T)` types have all been converted to use `size_t`
instead of `int` for indices and lengths.
### Reference counts
Some external consumers increment reference counts directly by calling
`CRYPTO_add` with the corresponding `CRYPTO_LOCK_*` value.
These APIs no longer exist in BoringSSL. Instead, code which increments
reference counts should call the corresponding `FOO_up_ref` function, such as
`EVP_PKEY_up_ref`. Note that not all of these APIs are present in OpenSSL and
may require `#ifdef`s.
### Error codes
OpenSSL's errors are extremely specific, leaking internals of the library,
including even a function code for the function which emitted the error! As some
logic in BoringSSL has been rewritten, code which conditions on the error may
break (grep for `ERR_GET_REASON` and `ERR_GET_FUNC`). This danger also exists
when upgrading OpenSSL versions.
Where possible, avoid conditioning on the exact error reason. Otherwise, a
BoringSSL `#ifdef` may be necessary. Exactly how best to resolve this issue is
still being determined. It's possible some new APIs will be added in the future.
Function codes have been completely removed. Remove code which conditions on
these as it will break with the slightest change in the library, OpenSSL or
BoringSSL.
### `*_ctrl` functions
Some OpenSSL APIs are implemented with `ioctl`-style functions such as
`SSL_ctrl` and `EVP_PKEY_CTX_ctrl`, combined with convenience macros, such as
# define SSL_CTX_set_mode(ctx,op) \
SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL)
In BoringSSL, these macros have been replaced with proper functions. The
underlying `_ctrl` functions have been removed.
For convenience, `SSL_CTRL_*` values are retained as macros to `doesnt_exist` so
existing code which uses them (or the wrapper macros) in `#ifdef` expressions
will continue to function. However, the macros themselves will not work.
Switch any `*_ctrl` callers to the macro/function versions. This works in both
OpenSSL and BoringSSL. Note that BoringSSL's function versions will be
type-checked and may require more care with types.
### HMAC `EVP_PKEY`s
`EVP_PKEY_HMAC` is removed. Use the `HMAC_*` functions in `hmac.h` instead. This
is compatible with OpenSSL.
### DSA `EVP_PKEY`s
`EVP_PKEY_DSA` is deprecated. It is currently still possible to parse DER into a
DSA `EVP_PKEY`, but signing or verifying with those objects will not work.
### DES
The `DES_cblock` type has been switched from an array to a struct to avoid the
pitfalls around array types in C. Where features which require DES cannot be
disabled, BoringSSL-specific codepaths may be necessary.
### TLS renegotiation
OpenSSL enables TLS renegotiation by default and accepts renegotiation requests
from the peer transparently. Renegotiation is an extremely problematic protocol
feature, so BoringSSL rejects peer renegotiations by default.
To enable renegotiation, call `SSL_set_renegotiate_mode` and set it to
`ssl_renegotiate_once` or `ssl_renegotiate_freely`. Renegotiation is only
supported as a client in SSL3/TLS and the HelloRequest must be received at a
quiet point in the application protocol. This is sufficient to support the
common use of requesting a new client certificate between an HTTP request and
response in (unpipelined) HTTP/1.1.
Things which do not work:
* There is no support for renegotiation as a server.
* There is no support for renegotiation in DTLS.
* There is no support for initiating renegotiation; `SSL_renegotiate` always
fails and `SSL_set_state` does nothing.
* Interleaving application data with the new handshake is forbidden.
* If a HelloRequest is received while `SSL_write` has unsent application data,
the renegotiation is rejected.
### Lowercase hexadecimal
BoringSSL's `BN_bn2hex` function uses lowercase hexadecimal digits instead of
uppercase. Some code may require changes to avoid being sensitive to this
difference.
### Legacy ASN.1 functions
OpenSSL's ASN.1 stack uses `d2i` functions for parsing. They have the form:
RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len);
In addition to returning the result, OpenSSL places it in `*out` if `out` is
not `NULL`. On input, if `*out` is not `NULL`, OpenSSL will usually (but not
always) reuse that object rather than allocating a new one. In BoringSSL, these
functions are compatibility wrappers over a newer ASN.1 stack. Even if `*out`
is not `NULL`, these wrappers will always allocate a new object and free the
previous one.
Ensure that callers do not rely on this object reuse behavior. It is
recommended to avoid the `out` parameter completely and always pass in `NULL`.
Note that less error-prone APIs are available for BoringSSL-specific code (see
below).
## Optional BoringSSL-specific simplifications
BoringSSL makes some changes to OpenSSL which simplify the API but remain
compatible with OpenSSL consumers. In general, consult the BoringSSL
documentation for any functions in new BoringSSL-only code.
### Return values
Most OpenSSL APIs return 1 on success and either 0 or -1 on failure. BoringSSL
has narrowed most of these to 1 on success and 0 on failure. BoringSSL-specific
code may take advantage of the less error-prone APIs and use `!` to check for
errors.
### Initialization
OpenSSL has a number of different initialization functions for setting up error
strings and loading algorithms, etc. All of these functions still exist in
BoringSSL for convenience, but they do nothing and are not necessary.
The one exception is `CRYPTO_library_init`. In `BORINGSSL_NO_STATIC_INITIALIZER`
builds, it must be called to query CPU capabitilies before the rest of the
library. In the default configuration, this is done with a static initializer
and is also unnecessary.
### Threading
OpenSSL provides a number of APIs to configure threading callbacks and set up
locks. Without initializing these, the library is not thread-safe. Configuring
these does nothing in BoringSSL. Instead, BoringSSL calls pthreads and the
corresponding Windows APIs internally and is always thread-safe where the API
guarantees it.
### ASN.1
BoringSSL is in the process of deprecating OpenSSL's `d2i` and `i2d` in favor of
new functions using the much less error-prone `CBS` and `CBB` types.
BoringSSL-only code should use those functions where available.
+31
View File
@@ -0,0 +1,31 @@
# BoringSSL
BoringSSL is a fork of OpenSSL that is designed to meet Google's needs.
Although BoringSSL is an open source project, it is not intended for general
use, as OpenSSL is. We don't recommend that third parties depend upon it. Doing
so is likely to be frustrating because there are no guarantees of API or ABI
stability.
Programs ship their own copies of BoringSSL when they use it and we update
everything as needed when deciding to make API changes. This allows us to
mostly avoid compromises in the name of compatibility. It works for us, but it
may not work for you.
BoringSSL arose because Google used OpenSSL for many years in various ways and,
over time, built up a large number of patches that were maintained while
tracking upstream OpenSSL. As Google's product portfolio became more complex,
more copies of OpenSSL sprung up and the effort involved in maintaining all
these patches in multiple places was growing steadily.
Currently BoringSSL is the SSL library in Chrome/Chromium, Android (but it's
not part of the NDK) and a number of other apps/programs.
There are other files in this directory which might be helpful:
* [PORTING.md](/PORTING.md): how to port OpenSSL-using code to BoringSSL.
* [BUILDING.md](/BUILDING.md): how to build BoringSSL
* [STYLE.md](/STYLE.md): rules and guidelines for coding style.
* include/openssl: public headers with API documentation in comments. Also [available online](https://commondatastorage.googleapis.com/chromium-boringssl-docs/headers.html).
* [FUZZING.md](/FUZZING.md): information about fuzzing BoringSSL.
* [CONTRIBUTING.md](/CONTRIBUTING.md): how to contribute to BoringSSL.
-198
View File
@@ -1,198 +0,0 @@
BoringSSL Style Guide.
BoringSSL usually follows the Google C++ style guide, found below. The
rest of this document describes differences and clarifications on top
of the base guide.
https://google-styleguide.googlecode.com/svn/trunk/cppguide.html
Legacy code.
As a derivative of OpenSSL, BoringSSL contains a lot of legacy code
that does not follow this style guide. Particularly where public API
is concerned, balance consistency within a module with the benefits of
a given rule. Module-wide deviations on naming should be respected
while integer and return value conventions take precedence over
consistency.
Some modules have seen few changes, so they still retain the original
indentation style for now. When editing these, try to retain the
original style. For Emacs, doc/c-indentation.el from OpenSSL may be
helpful in this.
Language.
The majority of the project is in C, so C++-specific rules in the
Google style guide do not apply. Support for C99 features depends on
our target platforms. Typically, Chromium's target MSVC is the most
restrictive.
Variable declarations in the middle of a function are allowed.
Comments should be /* C-style */ for consistency.
When declaration pointer types, * should be placed next to the variable
name, not the type. So
uint8_t *ptr;
not
uint8_t* ptr;
Rather than malloc() and free(), use the wrappers OPENSSL_malloc() and
OPENSSL_free(). Use the standard C assert() function freely.
For new constants, prefer enums when the values are sequential and typed
constants for flags. If adding values to an existing set of #defines, continue
with #define.
Formatting.
Single-statement blocks are not allowed. All conditions and loops must
use braces:
if (foo) {
do_something();
}
not
if (foo)
do_something();
Integers.
Prefer using explicitly-sized integers where appropriate rather than
generic C ones. For instance, to represent a byte, use uint8_t, not
unsigned char. Likewise, represent a two-byte field as uint16_t, not
unsigned short.
Sizes are represented as size_t.
Within a struct that is retained across the lifetime of an SSL
connection, if bounds of a size are known and it's easy, use a smaller
integer type like uint8_t. This is a "free" connection footprint
optimization for servers. Don't make code significantly more complex
for it, and do still check the bounds when passing in and out of the
struct. This narrowing should not propagate to local variables and
function parameters.
When doing arithmetic, account for overflow conditions.
Except with platform APIs, do not use ssize_t. MSVC lacks it, and
prefer out-of-band error signaling for size_t (see Return values).
Naming.
Follow Google naming conventions in C++ files. In C files, use the
following naming conventions for consistency with existing OpenSSL and C
styles:
Define structs with typedef named TYPE_NAME. The corresponding struct
should be named struct type_name_st.
Name public functions as MODULE_function_name, unless the module
already uses a different naming scheme for legacy reasons. The module
name should be a type name if the function is a method of a particular
type.
Some types are allocated within the library while others are
initialized into a struct allocated by the caller, often on the
stack. Name these functions TYPE_NAME_new/TYPE_NAME_free and
TYPE_NAME_init/TYPE_NAME_cleanup, respectively. All TYPE_NAME_free
functions must do nothing on NULL input.
If a variable is the length of a pointer value, it has the suffix
_len. An output parameter is named out or has an out_ prefix. For
instance, For instance:
uint8_t *out,
size_t *out_len,
const uint8_t *in,
size_t in_len,
Name public headers like include/openssl/evp.h with header guards like
OPENSSL_HEADER_EVP_H. Name internal headers like crypto/ec/internal.h
with header guards like OPENSSL_HEADER_EC_INTERNAL_H.
Name enums like unix_hacker_t. For instance:
enum should_free_handshake_buffer_t {
free_handshake_buffer,
dont_free_handshake_buffer,
};
Return values.
As even malloc may fail in BoringSSL, the vast majority of functions
will have a failure case. Functions should return int with one on
success and zero on error. Do not overload the return value to both
signal success/failure and output an integer. For example:
OPENSSL_EXPORT int CBS_get_u16(CBS *cbs, uint16_t *out);
If a function needs more than a true/false result code, define an enum
rather than arbitrarily assigning meaning to int values.
If a function outputs a pointer to an object on success and there are no
other outputs, return the pointer directly and NULL on error.
Parameters.
Where not constrained by legacy code, parameter order should be:
1. context parameters
2. output parameters
3. input parameters
For example,
/* CBB_add_asn sets |*out_contents| to a |CBB| into which the contents of an
* ASN.1 object can be written. The |tag| argument will be used as the tag for
* the object. It returns one on success or zero on error. */
OPENSSL_EXPORT int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag);
Documentation.
All public symbols must have a documentation comment in their header
file. The style is based on that of Go. The first sentence begins with
the symbol name, optionally prefixed with "A" or "An". Apart from the
initial mention of symbol, references to other symbols or parameter
names should be surrounded by |pipes|.
Documentation should be concise but completely describe the exposed
behavior of the function. Pay special note to success/failure behaviors
and caller obligations on object lifetimes. If this sacrifices
conciseness, consider simplifying the function's behavior.
/* EVP_DigestVerifyUpdate appends |len| bytes from |data| to the data which
* will be verified by |EVP_DigestVerifyFinal|. It returns one on success and
* zero otherwise. */
OPENSSL_EXPORT int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data,
size_t len);
Explicitly mention any surprising edge cases or deviations from common
return value patterns in legacy functions.
/* RSA_private_encrypt encrypts |flen| bytes from |from| with the private key in
* |rsa| and writes the encrypted data to |to|. The |to| buffer must have at
* least |RSA_size| bytes of space. It returns the number of bytes written, or
* -1 on error. The |padding| argument must be one of the |RSA_*_PADDING|
* values. If in doubt, |RSA_PKCS1_PADDING| is the most common.
*
* WARNING: this function is dangerous because it breaks the usual return value
* convention. Use |RSA_sign_raw| instead. */
OPENSSL_EXPORT int RSA_private_encrypt(int flen, const uint8_t *from,
uint8_t *to, RSA *rsa, int padding);
Document private functions in their internal.h header or, if static,
where defined.
+197
View File
@@ -0,0 +1,197 @@
# BoringSSL Style Guide
BoringSSL usually follows the
[Google C++ style guide](https://google.github.io/styleguide/cppguide.html),
The rest of this document describes differences and clarifications on
top of the base guide.
## Legacy code
As a derivative of OpenSSL, BoringSSL contains a lot of legacy code that
does not follow this style guide. Particularly where public API is
concerned, balance consistency within a module with the benefits of a
given rule. Module-wide deviations on naming should be respected while
integer and return value conventions take precedence over consistency.
Some modules have seen few changes, so they still retain the original
indentation style for now. When editing these, try to retain the
original style. For Emacs, `doc/c-indentation.el` from OpenSSL may be
helpful in this.
## Language
The majority of the project is in C, so C++-specific rules in the
Google style guide do not apply. Support for C99 features depends on
our target platforms. Typically, Chromium's target MSVC is the most
restrictive.
Variable declarations in the middle of a function are allowed.
Comments should be `/* C-style */` for consistency.
When declaration pointer types, `*` should be placed next to the variable
name, not the type. So
uint8_t *ptr;
not
uint8_t* ptr;
Rather than `malloc()` and `free()`, use the wrappers `OPENSSL_malloc()`
and `OPENSSL_free()`. Use the standard C `assert()` function freely.
For new constants, prefer enums when the values are sequential and typed
constants for flags. If adding values to an existing set of `#define`s,
continue with `#define`.
## Formatting
Single-statement blocks are not allowed. All conditions and loops must
use braces:
if (foo) {
do_something();
}
not
if (foo)
do_something();
## Integers
Prefer using explicitly-sized integers where appropriate rather than
generic C ones. For instance, to represent a byte, use `uint8_t`, not
`unsigned char`. Likewise, represent a two-byte field as `uint16_t`, not
`unsigned short`.
Sizes are represented as `size_t`.
Within a struct that is retained across the lifetime of an SSL
connection, if bounds of a size are known and it's easy, use a smaller
integer type like `uint8_t`. This is a "free" connection footprint
optimization for servers. Don't make code significantly more complex for
it, and do still check the bounds when passing in and out of the
struct. This narrowing should not propagate to local variables and
function parameters.
When doing arithmetic, account for overflow conditions.
Except with platform APIs, do not use `ssize_t`. MSVC lacks it, and
prefer out-of-band error signaling for `size_t` (see Return values).
## Naming
Follow Google naming conventions in C++ files. In C files, use the
following naming conventions for consistency with existing OpenSSL and C
styles:
Define structs with typedef named `TYPE_NAME`. The corresponding struct
should be named `struct type_name_st`.
Name public functions as `MODULE_function_name`, unless the module
already uses a different naming scheme for legacy reasons. The module
name should be a type name if the function is a method of a particular
type.
Some types are allocated within the library while others are initialized
into a struct allocated by the caller, often on the stack. Name these
functions `TYPE_NAME_new`/`TYPE_NAME_free` and
`TYPE_NAME_init`/`TYPE_NAME_cleanup`, respectively. All `TYPE_NAME_free`
functions must do nothing on `NULL` input.
If a variable is the length of a pointer value, it has the suffix
`_len`. An output parameter is named `out` or has an `out_` prefix. For
instance, For instance:
uint8_t *out,
size_t *out_len,
const uint8_t *in,
size_t in_len,
Name public headers like `include/openssl/evp.h` with header guards like
`OPENSSL_HEADER_EVP_H`. Name internal headers like
`crypto/ec/internal.h` with header guards like
`OPENSSL_HEADER_EC_INTERNAL_H`.
Name enums like `enum unix_hacker_t`. For instance:
enum should_free_handshake_buffer_t {
free_handshake_buffer,
dont_free_handshake_buffer,
};
## Return values
As even `malloc` may fail in BoringSSL, the vast majority of functions
will have a failure case. Functions should return `int` with one on
success and zero on error. Do not overload the return value to both
signal success/failure and output an integer. For example:
OPENSSL_EXPORT int CBS_get_u16(CBS *cbs, uint16_t *out);
If a function needs more than a true/false result code, define an enum
rather than arbitrarily assigning meaning to int values.
If a function outputs a pointer to an object on success and there are no
other outputs, return the pointer directly and `NULL` on error.
## Parameters
Where not constrained by legacy code, parameter order should be:
1. context parameters
2. output parameters
3. input parameters
For example,
/* CBB_add_asn sets |*out_contents| to a |CBB| into which the contents of an
* ASN.1 object can be written. The |tag| argument will be used as the tag for
* the object. It returns one on success or zero on error. */
OPENSSL_EXPORT int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag);
## Documentation
All public symbols must have a documentation comment in their header
file. The style is based on that of Go. The first sentence begins with
the symbol name, optionally prefixed with "A" or "An". Apart from the
initial mention of symbol, references to other symbols or parameter
names should be surrounded by |pipes|.
Documentation should be concise but completely describe the exposed
behavior of the function. Pay special note to success/failure behaviors
and caller obligations on object lifetimes. If this sacrifices
conciseness, consider simplifying the function's behavior.
/* EVP_DigestVerifyUpdate appends |len| bytes from |data| to the data which
* will be verified by |EVP_DigestVerifyFinal|. It returns one on success and
* zero otherwise. */
OPENSSL_EXPORT int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data,
size_t len);
Explicitly mention any surprising edge cases or deviations from common
return value patterns in legacy functions.
/* RSA_private_encrypt encrypts |flen| bytes from |from| with the private key in
* |rsa| and writes the encrypted data to |to|. The |to| buffer must have at
* least |RSA_size| bytes of space. It returns the number of bytes written, or
* -1 on error. The |padding| argument must be one of the |RSA_*_PADDING|
* values. If in doubt, |RSA_PKCS1_PADDING| is the most common.
*
* WARNING: this function is dangerous because it breaks the usual return value
* convention. Use |RSA_sign_raw| instead. */
OPENSSL_EXPORT int RSA_private_encrypt(int flen, const uint8_t *from,
uint8_t *to, RSA *rsa, int padding);
Document private functions in their `internal.h` header or, if static,
where defined.
+11 -36
View File
@@ -1,4 +1,4 @@
include_directories(. ../include)
include_directories(../include)
if(APPLE)
if (${ARCH} STREQUAL "x86")
@@ -22,6 +22,7 @@ elseif(UNIX)
endif()
set(ASM_EXT S)
enable_language(ASM)
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -Wa,--noexecstack")
else()
if (CMAKE_CL_64)
message("Using nasm")
@@ -53,39 +54,6 @@ function(perlasm dest src)
)
endfunction()
if (${ARCH} STREQUAL "x86_64")
set(
CRYPTO_ARCH_SOURCES
cpu-intel.c
)
endif()
if (${ARCH} STREQUAL "x86")
set(
CRYPTO_ARCH_SOURCES
cpu-intel.c
)
endif()
if (${ARCH} STREQUAL "arm")
set(
CRYPTO_ARCH_SOURCES
cpu-arm.c
cpu-arm-asm.S
)
endif()
if (${ARCH} STREQUAL "aarch64")
set(
CRYPTO_ARCH_SOURCES
cpu-arm.c
)
endif()
# Level 0.1 - depends on nothing outside this set.
add_subdirectory(stack)
add_subdirectory(lhash)
@@ -105,6 +73,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)
@@ -142,6 +111,10 @@ add_subdirectory(test)
add_library(
crypto
cpu-aarch64-linux.c
cpu-arm.c
cpu-arm-linux.c
cpu-intel.c
crypto.c
directory_posix.c
directory_win.c
@@ -155,8 +128,6 @@ add_library(
thread_win.c
time_support.c
${CRYPTO_ARCH_SOURCES}
$<TARGET_OBJECTS:stack>
$<TARGET_OBJECTS:lhash>
$<TARGET_OBJECTS:err>
@@ -174,6 +145,7 @@ add_library(
$<TARGET_OBJECTS:conf>
$<TARGET_OBJECTS:chacha>
$<TARGET_OBJECTS:poly1305>
$<TARGET_OBJECTS:curve25519>
$<TARGET_OBJECTS:buf>
$<TARGET_OBJECTS:bn>
$<TARGET_OBJECTS:bio>
@@ -210,6 +182,7 @@ add_executable(
)
target_link_libraries(constant_time_test crypto)
add_dependencies(all_tests constant_time_test)
add_executable(
thread_test
@@ -220,6 +193,7 @@ add_executable(
)
target_link_libraries(thread_test crypto)
add_dependencies(all_tests thread_test)
add_executable(
refcount_test
@@ -228,3 +202,4 @@ add_executable(
)
target_link_libraries(refcount_test crypto)
add_dependencies(all_tests refcount_test)
+2 -1
View File
@@ -1,4 +1,4 @@
include_directories(. .. ../../include)
include_directories(../../include)
if (${ARCH} STREQUAL "x86_64")
set(
@@ -69,3 +69,4 @@ add_executable(
)
target_link_libraries(aes_test crypto)
add_dependencies(all_tests aes_test)
+61 -4
View File
@@ -49,6 +49,9 @@
#include <openssl/aes.h>
#include <assert.h>
#include <stdlib.h>
#include <openssl/cpu.h>
#include "internal.h"
@@ -1057,6 +1060,44 @@ void AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
#else
#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
static int hwaes_capable(void) {
return CRYPTO_is_ARMv8_AES_capable();
}
int aes_v8_set_encrypt_key(const uint8_t *user_key, const int bits,
AES_KEY *key);
int aes_v8_set_decrypt_key(const uint8_t *user_key, const int bits,
AES_KEY *key);
void aes_v8_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
void aes_v8_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
#else
static int hwaes_capable(void) {
return 0;
}
static int aes_v8_set_encrypt_key(const uint8_t *user_key, int bits, AES_KEY *key) {
abort();
}
static int aes_v8_set_decrypt_key(const uint8_t *user_key, int bits, AES_KEY *key) {
abort();
}
static void aes_v8_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
abort();
}
static void aes_v8_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
abort();
}
#endif
/* In this case several functions are provided by asm code. However, one cannot
* control asm symbol visibility with command line flags and such so they are
* always hidden and wrapped by these C functions, which can be so
@@ -1064,22 +1105,38 @@ void AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
void asm_AES_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
void AES_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
asm_AES_encrypt(in, out, key);
if (hwaes_capable()) {
aes_v8_encrypt(in, out, key);
} else {
asm_AES_encrypt(in, out, key);
}
}
void asm_AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
void AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
asm_AES_decrypt(in, out, key);
if (hwaes_capable()) {
aes_v8_decrypt(in, out, key);
} else {
asm_AES_decrypt(in, out, key);
}
}
int asm_AES_set_encrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey);
int AES_set_encrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) {
return asm_AES_set_encrypt_key(key, bits, aeskey);
if (hwaes_capable()) {
return aes_v8_set_encrypt_key(key, bits, aeskey);
} else {
return asm_AES_set_encrypt_key(key, bits, aeskey);
}
}
int asm_AES_set_decrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey);
int AES_set_decrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) {
return asm_AES_set_decrypt_key(key, bits, aeskey);
if (hwaes_capable()) {
return aes_v8_set_decrypt_key(key, bits, aeskey);
} else {
return asm_AES_set_decrypt_key(key, bits, aeskey);
}
}
#endif /* OPENSSL_NO_ASM || (!OPENSSL_X86 && !OPENSSL_X86_64 && !OPENSSL_ARM) */
+1 -6
View File
@@ -65,7 +65,7 @@ $rounds="r12";
$code=<<___;
#if defined(__arm__)
#ifndef __KERNEL__
# include "arm_arch.h"
# include <openssl/arm_arch.h>
#else
# define __ARM_ARCH__ __LINUX_ARM_ARCH__
#endif
@@ -191,7 +191,6 @@ AES_Te:
@ void asm_AES_encrypt(const unsigned char *in, unsigned char *out,
@ const AES_KEY *key) {
.global asm_AES_encrypt
.hidden asm_AES_encrypt
.type asm_AES_encrypt,%function
.align 5
asm_AES_encrypt:
@@ -441,7 +440,6 @@ _armv4_AES_encrypt:
.size _armv4_AES_encrypt,.-_armv4_AES_encrypt
.global asm_AES_set_encrypt_key
.hidden asm_AES_set_encrypt_key
.type asm_AES_set_encrypt_key,%function
.align 5
asm_AES_set_encrypt_key:
@@ -748,7 +746,6 @@ _armv4_AES_set_encrypt_key:
.size asm_AES_set_encrypt_key,.-asm_AES_set_encrypt_key
.global asm_AES_set_decrypt_key
.hidden asm_AES_set_decrypt_key
.type asm_AES_set_decrypt_key,%function
.align 5
asm_AES_set_decrypt_key:
@@ -765,7 +762,6 @@ asm_AES_set_decrypt_key:
@ void AES_set_enc2dec_key(const AES_KEY *inp,AES_KEY *out)
.global AES_set_enc2dec_key
.hidden AES_set_enc2dec_key
.type AES_set_enc2dec_key,%function
.align 5
AES_set_enc2dec_key:
@@ -971,7 +967,6 @@ AES_Td:
@ void asm_AES_decrypt(const unsigned char *in, unsigned char *out,
@ const AES_KEY *key) {
.global asm_AES_decrypt
.hidden asm_AES_decrypt
.type asm_AES_decrypt,%function
.align 5
asm_AES_decrypt:
+1 -1
View File
@@ -88,7 +88,7 @@ $inout3="xmm5"; $in1="xmm5";
$inout4="xmm6"; $in0="xmm6";
$inout5="xmm7"; $ivec="xmm7";
# AESNI extenstion
# AESNI extension
sub aeskeygenassist
{ my($dst,$src,$imm)=@_;
if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
+1 -1
View File
@@ -45,7 +45,7 @@ open OUT,"| \"$^X\" $xlate $flavour $output";
$prefix="aes_v8";
$code=<<___;
#include "arm_arch.h"
#include <openssl/arm_arch.h>
#if __ARM_MAX_ARCH__>=7
.text
+1 -11
View File
@@ -701,9 +701,8 @@ ___
}
$code.=<<___;
#if defined(__arm__)
#ifndef __KERNEL__
# include "arm_arch.h"
# include <openssl/arm_arch.h>
# define VFP_ABI_PUSH vstmdb sp!,{d8-d15}
# define VFP_ABI_POP vldmia sp!,{d8-d15}
@@ -1007,7 +1006,6 @@ if (0) { # following four functions are unsupported interface
# used for benchmarking...
$code.=<<___;
.globl bsaes_enc_key_convert
.hidden bsaes_enc_key_convert
.type bsaes_enc_key_convert,%function
.align 4
bsaes_enc_key_convert:
@@ -1026,7 +1024,6 @@ bsaes_enc_key_convert:
.size bsaes_enc_key_convert,.-bsaes_enc_key_convert
.globl bsaes_encrypt_128
.hidden bsaes_encrypt_128
.type bsaes_encrypt_128,%function
.align 4
bsaes_encrypt_128:
@@ -1057,7 +1054,6 @@ bsaes_encrypt_128:
.size bsaes_encrypt_128,.-bsaes_encrypt_128
.globl bsaes_dec_key_convert
.hidden bsaes_dec_key_convert
.type bsaes_dec_key_convert,%function
.align 4
bsaes_dec_key_convert:
@@ -1078,7 +1074,6 @@ bsaes_dec_key_convert:
.size bsaes_dec_key_convert,.-bsaes_dec_key_convert
.globl bsaes_decrypt_128
.hidden bsaes_decrypt_128
.type bsaes_decrypt_128,%function
.align 4
bsaes_decrypt_128:
@@ -1118,7 +1113,6 @@ $code.=<<___;
.extern AES_decrypt
.global bsaes_cbc_encrypt
.hidden bsaes_cbc_encrypt
.type bsaes_cbc_encrypt,%function
.align 5
bsaes_cbc_encrypt:
@@ -1394,7 +1388,6 @@ my $keysched = "sp";
$code.=<<___;
.extern AES_encrypt
.global bsaes_ctr32_encrypt_blocks
.hidden bsaes_ctr32_encrypt_blocks
.type bsaes_ctr32_encrypt_blocks,%function
.align 5
bsaes_ctr32_encrypt_blocks:
@@ -1636,7 +1629,6 @@ my @T=@XMM[6..7];
$code.=<<___;
.globl bsaes_xts_encrypt
.hidden bsaes_xts_encrypt
.type bsaes_xts_encrypt,%function
.align 4
bsaes_xts_encrypt:
@@ -2051,7 +2043,6 @@ $code.=<<___;
.size bsaes_xts_encrypt,.-bsaes_xts_encrypt
.globl bsaes_xts_decrypt
.hidden bsaes_xts_decrypt
.type bsaes_xts_decrypt,%function
.align 4
bsaes_xts_decrypt:
@@ -2497,7 +2488,6 @@ ___
}
$code.=<<___;
#endif
#endif
___
$code =~ s/\`([^\`]*)\`/eval($1)/gem;
+2 -2
View File
@@ -48,9 +48,9 @@
#include <openssl/aes.h>
#include "assert.h"
#include <assert.h>
#include <openssl/modes.h>
#include "../modes/internal.h"
void AES_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
+12 -2
View File
@@ -1,4 +1,4 @@
include_directories(. .. ../../include)
include_directories(../../include)
add_library(
asn1
@@ -32,7 +32,6 @@ add_library(
f_int.c
f_string.c
t_bitst.c
t_pkey.c
tasn_dec.c
tasn_enc.c
tasn_fre.c
@@ -43,3 +42,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)
+176 -168
View File
@@ -33,7 +33,7 @@
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
@@ -61,195 +61,203 @@
#include <openssl/err.h>
#include <openssl/mem.h>
int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
{ return M_ASN1_BIT_STRING_set(x, d, len); }
{
return M_ASN1_BIT_STRING_set(x, d, len);
}
int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
{
int ret,j,bits,len;
unsigned char *p,*d;
{
int ret, j, bits, len;
unsigned char *p, *d;
if (a == NULL) return(0);
if (a == NULL)
return (0);
len=a->length;
len = a->length;
if (len > 0)
{
if (a->flags & ASN1_STRING_FLAG_BITS_LEFT)
{
bits=(int)a->flags&0x07;
}
else
{
for ( ; len > 0; len--)
{
if (a->data[len-1]) break;
}
j=a->data[len-1];
if (j & 0x01) bits=0;
else if (j & 0x02) bits=1;
else if (j & 0x04) bits=2;
else if (j & 0x08) bits=3;
else if (j & 0x10) bits=4;
else if (j & 0x20) bits=5;
else if (j & 0x40) bits=6;
else if (j & 0x80) bits=7;
else bits=0; /* should not happen */
}
}
else
bits=0;
if (len > 0) {
if (a->flags & ASN1_STRING_FLAG_BITS_LEFT) {
bits = (int)a->flags & 0x07;
} else {
for (; len > 0; len--) {
if (a->data[len - 1])
break;
}
j = a->data[len - 1];
if (j & 0x01)
bits = 0;
else if (j & 0x02)
bits = 1;
else if (j & 0x04)
bits = 2;
else if (j & 0x08)
bits = 3;
else if (j & 0x10)
bits = 4;
else if (j & 0x20)
bits = 5;
else if (j & 0x40)
bits = 6;
else if (j & 0x80)
bits = 7;
else
bits = 0; /* should not happen */
}
} else
bits = 0;
ret=1+len;
if (pp == NULL) return(ret);
ret = 1 + len;
if (pp == NULL)
return (ret);
p= *pp;
p = *pp;
*(p++)=(unsigned char)bits;
d=a->data;
memcpy(p,d,len);
p+=len;
if (len > 0) p[-1]&=(0xff<<bits);
*pp=p;
return(ret);
}
*(p++) = (unsigned char)bits;
d = a->data;
memcpy(p, d, len);
p += len;
if (len > 0)
p[-1] &= (0xff << bits);
*pp = p;
return (ret);
}
ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
const unsigned char **pp, long len)
{
ASN1_BIT_STRING *ret=NULL;
const unsigned char *p;
unsigned char *s;
int padding;
const unsigned char **pp, long len)
{
ASN1_BIT_STRING *ret = NULL;
const unsigned char *p;
unsigned char *s;
int padding;
if (len < 1)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT);
goto err;
}
if (len < 1) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT);
goto err;
}
if ((a == NULL) || ((*a) == NULL))
{
if ((ret=M_ASN1_BIT_STRING_new()) == NULL) return(NULL);
}
else
ret=(*a);
if ((a == NULL) || ((*a) == NULL)) {
if ((ret = M_ASN1_BIT_STRING_new()) == NULL)
return (NULL);
} else
ret = (*a);
p= *pp;
padding = *(p++);
if (padding > 7)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
goto err;
}
p = *pp;
padding = *(p++);
if (padding > 7) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
goto err;
}
/* We do this to preserve the settings. If we modify
* the settings, via the _set_bit function, we will recalculate
* on output */
ret->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|padding); /* set */
/*
* We do this to preserve the settings. If we modify the settings, via
* the _set_bit function, we will recalculate on output
*/
ret->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear */
ret->flags |= (ASN1_STRING_FLAG_BITS_LEFT | padding); /* set */
if (len-- > 1) /* using one because of the bits left byte */
{
s=(unsigned char *)OPENSSL_malloc((int)len);
if (s == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
memcpy(s,p,(int)len);
s[len-1]&=(0xff<<padding);
p+=len;
}
else
s=NULL;
if (len-- > 1) { /* using one because of the bits left byte */
s = (unsigned char *)OPENSSL_malloc((int)len);
if (s == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
memcpy(s, p, (int)len);
s[len - 1] &= (0xff << padding);
p += len;
} else
s = NULL;
ret->length=(int)len;
if (ret->data != NULL) OPENSSL_free(ret->data);
ret->data=s;
ret->type=V_ASN1_BIT_STRING;
if (a != NULL) (*a)=ret;
*pp=p;
return(ret);
err:
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
M_ASN1_BIT_STRING_free(ret);
return(NULL);
}
/* These next 2 functions from Goetz Babin-Ebell <babinebell@trustcenter.de>
*/
int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
{
int w,v,iv;
unsigned char *c;
w=n/8;
v=1<<(7-(n&0x07));
iv= ~v;
if (!value) v=0;
if (a == NULL)
return 0;
a->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear, set on write */
if ((a->length < (w+1)) || (a->data == NULL))
{
if (!value) return(1); /* Don't need to set */
if (a->data == NULL)
c=(unsigned char *)OPENSSL_malloc(w+1);
else
c=(unsigned char *)OPENSSL_realloc_clean(a->data,
a->length,
w+1);
if (c == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return 0;
}
if (w+1-a->length > 0) memset(c+a->length, 0, w+1-a->length);
a->data=c;
a->length=w+1;
}
a->data[w]=((a->data[w])&iv)|v;
while ((a->length > 0) && (a->data[a->length-1] == 0))
a->length--;
return(1);
}
int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n)
{
int w,v;
w=n/8;
v=1<<(7-(n&0x07));
if ((a == NULL) || (a->length < (w+1)) || (a->data == NULL))
return(0);
return((a->data[w]&v) != 0);
}
ret->length = (int)len;
if (ret->data != NULL)
OPENSSL_free(ret->data);
ret->data = s;
ret->type = V_ASN1_BIT_STRING;
if (a != NULL)
(*a) = ret;
*pp = p;
return (ret);
err:
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
M_ASN1_BIT_STRING_free(ret);
return (NULL);
}
/*
* Checks if the given bit string contains only bits specified by
* These next 2 functions from Goetz Babin-Ebell <babinebell@trustcenter.de>
*/
int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
{
int w, v, iv;
unsigned char *c;
w = n / 8;
v = 1 << (7 - (n & 0x07));
iv = ~v;
if (!value)
v = 0;
if (a == NULL)
return 0;
a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear, set on write */
if ((a->length < (w + 1)) || (a->data == NULL)) {
if (!value)
return (1); /* Don't need to set */
if (a->data == NULL)
c = (unsigned char *)OPENSSL_malloc(w + 1);
else
c = (unsigned char *)OPENSSL_realloc_clean(a->data,
a->length, w + 1);
if (c == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return 0;
}
if (w + 1 - a->length > 0)
memset(c + a->length, 0, w + 1 - a->length);
a->data = c;
a->length = w + 1;
}
a->data[w] = ((a->data[w]) & iv) | v;
while ((a->length > 0) && (a->data[a->length - 1] == 0))
a->length--;
return (1);
}
int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n)
{
int w, v;
w = n / 8;
v = 1 << (7 - (n & 0x07));
if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL))
return (0);
return ((a->data[w] & v) != 0);
}
/*
* Checks if the given bit string contains only bits specified by
* the flags vector. Returns 0 if there is at least one bit set in 'a'
* which is not specified in 'flags', 1 otherwise.
* 'len' is the length of 'flags'.
*/
int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a,
unsigned char *flags, int flags_len)
{
int i, ok;
/* Check if there is one bit set at all. */
if (!a || !a->data) return 1;
unsigned char *flags, int flags_len)
{
int i, ok;
/* Check if there is one bit set at all. */
if (!a || !a->data)
return 1;
/* Check each byte of the internal representation of the bit string. */
ok = 1;
for (i = 0; i < a->length && ok; ++i)
{
unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
/* We are done if there is an unneeded bit set. */
ok = (a->data[i] & mask) == 0;
}
return ok;
}
/*
* Check each byte of the internal representation of the bit string.
*/
ok = 1;
for (i = 0; i < a->length && ok; ++i) {
unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
/* We are done if there is an unneeded bit set. */
ok = (a->data[i] & mask) == 0;
}
return ok;
}
+42 -44
View File
@@ -33,7 +33,7 @@
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
@@ -59,54 +59,52 @@
#include <openssl/err.h>
#include <openssl/mem.h>
int i2d_ASN1_BOOLEAN(int a, unsigned char **pp)
{
int r;
unsigned char *p;
{
int r;
unsigned char *p;
r=ASN1_object_size(0,1,V_ASN1_BOOLEAN);
if (pp == NULL) return(r);
p= *pp;
r = ASN1_object_size(0, 1, V_ASN1_BOOLEAN);
if (pp == NULL)
return (r);
p = *pp;
ASN1_put_object(&p,0,1,V_ASN1_BOOLEAN,V_ASN1_UNIVERSAL);
*(p++)= (unsigned char)a;
*pp=p;
return(r);
}
ASN1_put_object(&p, 0, 1, V_ASN1_BOOLEAN, V_ASN1_UNIVERSAL);
*(p++) = (unsigned char)a;
*pp = p;
return (r);
}
int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length)
{
int ret= -1;
const unsigned char *p;
long len;
int inf,tag,xclass;
int i=0;
{
int ret = -1;
const unsigned char *p;
long len;
int inf, tag, xclass;
int i = 0;
p= *pp;
inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
if (inf & 0x80)
{
i=ASN1_R_BAD_OBJECT_HEADER;
goto err;
}
p = *pp;
inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
if (inf & 0x80) {
i = ASN1_R_BAD_OBJECT_HEADER;
goto err;
}
if (tag != V_ASN1_BOOLEAN)
{
i=ASN1_R_EXPECTING_A_BOOLEAN;
goto err;
}
if (tag != V_ASN1_BOOLEAN) {
i = ASN1_R_EXPECTING_A_BOOLEAN;
goto err;
}
if (len != 1)
{
i=ASN1_R_BOOLEAN_IS_WRONG_LENGTH;
goto err;
}
ret= (int)*(p++);
if (a != NULL) (*a)=ret;
*pp=p;
return(ret);
err:
OPENSSL_PUT_ERROR(ASN1, i);
return(ret);
}
if (len != 1) {
i = ASN1_R_BOOLEAN_IS_WRONG_LENGTH;
goto err;
}
ret = (int)*(p++);
if (a != NULL)
(*a) = ret;
*pp = p;
return (ret);
err:
OPENSSL_PUT_ERROR(ASN1, i);
return (ret);
}
+212 -221
View File
@@ -62,256 +62,247 @@
#include <openssl/err.h>
#include <openssl/mem.h>
static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c);
/* type is a 'bitmap' of acceptable string types.
/*
* type is a 'bitmap' of acceptable string types.
*/
ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp,
long length, int type)
{
ASN1_STRING *ret=NULL;
const unsigned char *p;
unsigned char *s;
long len;
int inf,tag,xclass;
int i=0;
long length, int type)
{
ASN1_STRING *ret = NULL;
const unsigned char *p;
unsigned char *s;
long len;
int inf, tag, xclass;
int i = 0;
p= *pp;
inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
if (inf & 0x80) goto err;
p = *pp;
inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
if (inf & 0x80)
goto err;
if (tag >= 32)
{
i=ASN1_R_TAG_VALUE_TOO_HIGH;
goto err;
}
if (!(ASN1_tag2bit(tag) & type))
{
i=ASN1_R_WRONG_TYPE;
goto err;
}
if (tag >= 32) {
i = ASN1_R_TAG_VALUE_TOO_HIGH;
goto err;
}
if (!(ASN1_tag2bit(tag) & type)) {
i = ASN1_R_WRONG_TYPE;
goto err;
}
/* If a bit-string, exit early */
if (tag == V_ASN1_BIT_STRING)
return(d2i_ASN1_BIT_STRING(a,pp,length));
/* If a bit-string, exit early */
if (tag == V_ASN1_BIT_STRING)
return (d2i_ASN1_BIT_STRING(a, pp, length));
if ((a == NULL) || ((*a) == NULL))
{
if ((ret=ASN1_STRING_new()) == NULL) return(NULL);
}
else
ret=(*a);
if ((a == NULL) || ((*a) == NULL)) {
if ((ret = ASN1_STRING_new()) == NULL)
return (NULL);
} else
ret = (*a);
if (len != 0)
{
s=(unsigned char *)OPENSSL_malloc((int)len+1);
if (s == NULL)
{
i=ERR_R_MALLOC_FAILURE;
goto err;
}
memcpy(s,p,(int)len);
s[len]='\0';
p+=len;
}
else
s=NULL;
if (len != 0) {
s = (unsigned char *)OPENSSL_malloc((int)len + 1);
if (s == NULL) {
i = ERR_R_MALLOC_FAILURE;
goto err;
}
memcpy(s, p, (int)len);
s[len] = '\0';
p += len;
} else
s = NULL;
if (ret->data != NULL) OPENSSL_free(ret->data);
ret->length=(int)len;
ret->data=s;
ret->type=tag;
if (a != NULL) (*a)=ret;
*pp=p;
return(ret);
err:
OPENSSL_PUT_ERROR(ASN1, i);
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
ASN1_STRING_free(ret);
return(NULL);
}
if (ret->data != NULL)
OPENSSL_free(ret->data);
ret->length = (int)len;
ret->data = s;
ret->type = tag;
if (a != NULL)
(*a) = ret;
*pp = p;
return (ret);
err:
OPENSSL_PUT_ERROR(ASN1, i);
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
ASN1_STRING_free(ret);
return (NULL);
}
int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass)
{
int ret,r,constructed;
unsigned char *p;
{
int ret, r, constructed;
unsigned char *p;
if (a == NULL) return(0);
if (a == NULL)
return (0);
if (tag == V_ASN1_BIT_STRING)
return(i2d_ASN1_BIT_STRING(a,pp));
ret=a->length;
r=ASN1_object_size(0,ret,tag);
if (pp == NULL) return(r);
p= *pp;
if (tag == V_ASN1_BIT_STRING)
return (i2d_ASN1_BIT_STRING(a, pp));
if ((tag == V_ASN1_SEQUENCE) || (tag == V_ASN1_SET))
constructed=1;
else
constructed=0;
ASN1_put_object(&p,constructed,ret,tag,xclass);
memcpy(p,a->data,a->length);
p+=a->length;
*pp= p;
return(r);
}
ret = a->length;
r = ASN1_object_size(0, ret, tag);
if (pp == NULL)
return (r);
p = *pp;
if ((tag == V_ASN1_SEQUENCE) || (tag == V_ASN1_SET))
constructed = 1;
else
constructed = 0;
ASN1_put_object(&p, constructed, ret, tag, xclass);
memcpy(p, a->data, a->length);
p += a->length;
*pp = p;
return (r);
}
ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
long length, int Ptag, int Pclass)
{
ASN1_STRING *ret=NULL;
const unsigned char *p;
unsigned char *s;
long len;
int inf,tag,xclass;
int i=0;
long length, int Ptag, int Pclass)
{
ASN1_STRING *ret = NULL;
const unsigned char *p;
unsigned char *s;
long len;
int inf, tag, xclass;
int i = 0;
if ((a == NULL) || ((*a) == NULL))
{
if ((ret=ASN1_STRING_new()) == NULL) return(NULL);
}
else
ret=(*a);
if ((a == NULL) || ((*a) == NULL)) {
if ((ret = ASN1_STRING_new()) == NULL)
return (NULL);
} else
ret = (*a);
p= *pp;
inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
if (inf & 0x80)
{
i=ASN1_R_BAD_OBJECT_HEADER;
goto err;
}
p = *pp;
inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
if (inf & 0x80) {
i = ASN1_R_BAD_OBJECT_HEADER;
goto err;
}
if (tag != Ptag)
{
i=ASN1_R_WRONG_TAG;
goto err;
}
if (tag != Ptag) {
i = ASN1_R_WRONG_TAG;
goto err;
}
if (inf & V_ASN1_CONSTRUCTED)
{
ASN1_const_CTX c;
if (inf & V_ASN1_CONSTRUCTED) {
ASN1_const_CTX c;
c.pp=pp;
c.p=p;
c.inf=inf;
c.slen=len;
c.tag=Ptag;
c.xclass=Pclass;
c.max=(length == 0)?0:(p+length);
if (!asn1_collate_primitive(ret,&c))
goto err;
else
{
p=c.p;
}
}
else
{
if (len != 0)
{
if ((ret->length < len) || (ret->data == NULL))
{
if (ret->data != NULL) OPENSSL_free(ret->data);
s=(unsigned char *)OPENSSL_malloc((int)len + 1);
if (s == NULL)
{
i=ERR_R_MALLOC_FAILURE;
goto err;
}
}
else
s=ret->data;
memcpy(s,p,(int)len);
s[len] = '\0';
p+=len;
}
else
{
s=NULL;
if (ret->data != NULL) OPENSSL_free(ret->data);
}
c.pp = pp;
c.p = p;
c.inf = inf;
c.slen = len;
c.tag = Ptag;
c.xclass = Pclass;
c.max = (length == 0) ? 0 : (p + length);
if (!asn1_collate_primitive(ret, &c))
goto err;
else {
p = c.p;
}
} else {
if (len != 0) {
if ((ret->length < len) || (ret->data == NULL)) {
if (ret->data != NULL)
OPENSSL_free(ret->data);
s = (unsigned char *)OPENSSL_malloc((int)len + 1);
if (s == NULL) {
i = ERR_R_MALLOC_FAILURE;
goto err;
}
} else
s = ret->data;
memcpy(s, p, (int)len);
s[len] = '\0';
p += len;
} else {
s = NULL;
if (ret->data != NULL)
OPENSSL_free(ret->data);
}
ret->length=(int)len;
ret->data=s;
ret->type=Ptag;
}
ret->length = (int)len;
ret->data = s;
ret->type = Ptag;
}
if (a != NULL) (*a)=ret;
*pp=p;
return(ret);
err:
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
ASN1_STRING_free(ret);
OPENSSL_PUT_ERROR(ASN1, i);
return(NULL);
}
if (a != NULL)
(*a) = ret;
*pp = p;
return (ret);
err:
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
ASN1_STRING_free(ret);
OPENSSL_PUT_ERROR(ASN1, i);
return (NULL);
}
/* We are about to parse 0..n d2i_ASN1_bytes objects, we are to collapse
* them into the one structure that is then returned */
/* There have been a few bug fixes for this function from
* Paul Keogh <paul.keogh@sse.ie>, many thanks to him */
/*
* We are about to parse 0..n d2i_ASN1_bytes objects, we are to collapse them
* into the one structure that is then returned
*/
/*
* There have been a few bug fixes for this function from Paul Keogh
* <paul.keogh@sse.ie>, many thanks to him
*/
static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c)
{
ASN1_STRING *os=NULL;
BUF_MEM b;
int num;
{
ASN1_STRING *os = NULL;
BUF_MEM b;
int num;
b.length=0;
b.max=0;
b.data=NULL;
b.length = 0;
b.max = 0;
b.data = NULL;
if (a == NULL)
{
c->error=ERR_R_PASSED_NULL_PARAMETER;
goto err;
}
if (a == NULL) {
c->error = ERR_R_PASSED_NULL_PARAMETER;
goto err;
}
num=0;
for (;;)
{
if (c->inf & 1)
{
c->eos=ASN1_const_check_infinite_end(&c->p,
(long)(c->max-c->p));
if (c->eos) break;
}
else
{
if (c->slen <= 0) break;
}
num = 0;
for (;;) {
if (c->inf & 1) {
c->eos = ASN1_const_check_infinite_end(&c->p,
(long)(c->max - c->p));
if (c->eos)
break;
} else {
if (c->slen <= 0)
break;
}
c->q=c->p;
if (d2i_ASN1_bytes(&os,&c->p,c->max-c->p,c->tag,c->xclass)
== NULL)
{
c->error=ERR_R_ASN1_LIB;
goto err;
}
c->q = c->p;
if (d2i_ASN1_bytes(&os, &c->p, c->max - c->p, c->tag, c->xclass)
== NULL) {
c->error = ERR_R_ASN1_LIB;
goto err;
}
if (!BUF_MEM_grow_clean(&b,num+os->length))
{
c->error=ERR_R_BUF_LIB;
goto err;
}
memcpy(&(b.data[num]),os->data,os->length);
if (!(c->inf & 1))
c->slen-=(c->p-c->q);
num+=os->length;
}
if (!BUF_MEM_grow_clean(&b, num + os->length)) {
c->error = ERR_R_BUF_LIB;
goto err;
}
memcpy(&(b.data[num]), os->data, os->length);
if (!(c->inf & 1))
c->slen -= (c->p - c->q);
num += os->length;
}
if (!asn1_const_Finish(c)) goto err;
a->length=num;
if (a->data != NULL) OPENSSL_free(a->data);
a->data=(unsigned char *)b.data;
if (os != NULL) ASN1_STRING_free(os);
return(1);
err:
OPENSSL_PUT_ERROR(ASN1, c->error);
if (os != NULL) ASN1_STRING_free(os);
if (b.data != NULL) OPENSSL_free(b.data);
return(0);
}
if (!asn1_const_Finish(c))
goto err;
a->length = num;
if (a->data != NULL)
OPENSSL_free(a->data);
a->data = (unsigned char *)b.data;
if (os != NULL)
ASN1_STRING_free(os);
return (1);
err:
OPENSSL_PUT_ERROR(ASN1, c->error);
if (os != NULL)
ASN1_STRING_free(os);
if (b.data != NULL)
OPENSSL_free(b.data);
return (0);
}
+173 -192
View File
@@ -62,225 +62,206 @@
#include <openssl/err.h>
#include <openssl/mem.h>
static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb);
#ifndef NO_OLD_ASN1
#ifndef OPENSSL_NO_FP_API
# ifndef OPENSSL_NO_FP_API
void *ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x)
{
BIO *b;
void *ret;
void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x)
{
BIO *b;
void *ret;
if ((b=BIO_new(BIO_s_file())) == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
return(NULL);
}
BIO_set_fp(b,in,BIO_NOCLOSE);
ret=ASN1_d2i_bio(xnew,d2i,b,x);
BIO_free(b);
return(ret);
}
#endif
if ((b = BIO_new(BIO_s_file())) == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
return (NULL);
}
BIO_set_fp(b, in, BIO_NOCLOSE);
ret = ASN1_d2i_bio(xnew, d2i, b, x);
BIO_free(b);
return (ret);
}
# endif
void *ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x)
{
BUF_MEM *b = NULL;
const unsigned char *p;
void *ret=NULL;
int len;
void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x)
{
BUF_MEM *b = NULL;
const unsigned char *p;
void *ret = NULL;
int len;
len = asn1_d2i_read_bio(in, &b);
if(len < 0) goto err;
len = asn1_d2i_read_bio(in, &b);
if (len < 0)
goto err;
p=(unsigned char *)b->data;
ret=d2i(x,&p,len);
err:
if (b != NULL) BUF_MEM_free(b);
return(ret);
}
p = (unsigned char *)b->data;
ret = d2i(x, &p, len);
err:
if (b != NULL)
BUF_MEM_free(b);
return (ret);
}
#endif
void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x)
{
BUF_MEM *b = NULL;
const unsigned char *p;
void *ret=NULL;
int len;
{
BUF_MEM *b = NULL;
const unsigned char *p;
void *ret = NULL;
int len;
len = asn1_d2i_read_bio(in, &b);
if(len < 0) goto err;
len = asn1_d2i_read_bio(in, &b);
if (len < 0)
goto err;
p=(const unsigned char *)b->data;
ret=ASN1_item_d2i(x,&p,len, it);
err:
if (b != NULL) BUF_MEM_free(b);
return(ret);
}
p = (const unsigned char *)b->data;
ret = ASN1_item_d2i(x, &p, len, it);
err:
if (b != NULL)
BUF_MEM_free(b);
return (ret);
}
#ifndef OPENSSL_NO_FP_API
void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x)
{
BIO *b;
char *ret;
{
BIO *b;
char *ret;
if ((b=BIO_new(BIO_s_file())) == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
return(NULL);
}
BIO_set_fp(b,in,BIO_NOCLOSE);
ret=ASN1_item_d2i_bio(it,b,x);
BIO_free(b);
return(ret);
}
if ((b = BIO_new(BIO_s_file())) == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
return (NULL);
}
BIO_set_fp(b, in, BIO_NOCLOSE);
ret = ASN1_item_d2i_bio(it, b, x);
BIO_free(b);
return (ret);
}
#endif
#define HEADER_SIZE 8
static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
{
BUF_MEM *b;
unsigned char *p;
int i;
ASN1_const_CTX c;
size_t want=HEADER_SIZE;
int eos=0;
size_t off=0;
size_t len=0;
{
BUF_MEM *b;
unsigned char *p;
int i;
ASN1_const_CTX c;
size_t want = HEADER_SIZE;
int eos = 0;
size_t off = 0;
size_t len = 0;
b=BUF_MEM_new();
if (b == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return -1;
}
b = BUF_MEM_new();
if (b == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return -1;
}
ERR_clear_error();
for (;;)
{
if (want >= (len-off))
{
want-=(len-off);
ERR_clear_error();
for (;;) {
if (want >= (len - off)) {
want -= (len - off);
if (len + want < len || !BUF_MEM_grow_clean(b,len+want))
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
i=BIO_read(in,&(b->data[len]),want);
if ((i < 0) && ((len-off) == 0))
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
goto err;
}
if (i > 0)
{
if (len+i < len)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
goto err;
}
len+=i;
}
}
/* else data already loaded */
if (len + want < len || !BUF_MEM_grow_clean(b, len + want)) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
i = BIO_read(in, &(b->data[len]), want);
if ((i < 0) && ((len - off) == 0)) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
goto err;
}
if (i > 0) {
if (len + i < len) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
goto err;
}
len += i;
}
}
/* else data already loaded */
p=(unsigned char *)&(b->data[off]);
c.p=p;
c.inf=ASN1_get_object(&(c.p),&(c.slen),&(c.tag),&(c.xclass),
len-off);
if (c.inf & 0x80)
{
uint32_t e;
p = (unsigned char *)&(b->data[off]);
c.p = p;
c.inf = ASN1_get_object(&(c.p), &(c.slen), &(c.tag), &(c.xclass),
len - off);
if (c.inf & 0x80) {
uint32_t e;
e=ERR_GET_REASON(ERR_peek_error());
if (e != ASN1_R_TOO_LONG)
goto err;
else
ERR_clear_error(); /* clear error */
}
i=c.p-p;/* header length */
off+=i; /* end of data */
e = ERR_GET_REASON(ERR_peek_error());
if (e != ASN1_R_TOO_LONG)
goto err;
else
ERR_clear_error(); /* clear error */
}
i = c.p - p; /* header length */
off += i; /* end of data */
if (c.inf & 1)
{
/* no data body so go round again */
eos++;
if (eos < 0)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG);
goto err;
}
want=HEADER_SIZE;
}
else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC))
{
/* eos value, so go back and read another header */
eos--;
if (eos <= 0)
break;
else
want=HEADER_SIZE;
}
else
{
/* suck in c.slen bytes of data */
want=c.slen;
if (want > (len-off))
{
want-=(len-off);
if (want > INT_MAX /* BIO_read takes an int length */ ||
len+want < len)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
goto err;
}
if (!BUF_MEM_grow_clean(b,len+want))
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
while (want > 0)
{
i=BIO_read(in,&(b->data[len]),want);
if (i <= 0)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
goto err;
}
/* This can't overflow because
* |len+want| didn't overflow. */
len+=i;
want-=i;
}
}
if (off + c.slen < off)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
goto err;
}
off+=c.slen;
if (eos <= 0)
{
break;
}
else
want=HEADER_SIZE;
}
}
if (c.inf & 1) {
/* no data body so go round again */
eos++;
if (eos < 0) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG);
goto err;
}
want = HEADER_SIZE;
} else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC)) {
/* eos value, so go back and read another header */
eos--;
if (eos <= 0)
break;
else
want = HEADER_SIZE;
} else {
/* suck in c.slen bytes of data */
want = c.slen;
if (want > (len - off)) {
want -= (len - off);
if (want > INT_MAX /* BIO_read takes an int length */ ||
len + want < len) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
goto err;
}
if (!BUF_MEM_grow_clean(b, len + want)) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
while (want > 0) {
i = BIO_read(in, &(b->data[len]), want);
if (i <= 0) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
goto err;
}
/*
* This can't overflow because |len+want| didn't
* overflow.
*/
len += i;
want -= i;
}
}
if (off + c.slen < off) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
goto err;
}
off += c.slen;
if (eos <= 0) {
break;
} else
want = HEADER_SIZE;
}
}
if (off > INT_MAX)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
goto err;
}
if (off > INT_MAX) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
goto err;
}
*pb = b;
return off;
err:
if (b != NULL) BUF_MEM_free(b);
return -1;
}
*pb = b;
return off;
err:
if (b != NULL)
BUF_MEM_free(b);
return -1;
}
+43 -35
View File
@@ -59,45 +59,53 @@
#include <openssl/err.h>
#include <openssl/mem.h>
void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x)
{
unsigned char *b,*p;
const unsigned char *p2;
int i;
char *ret;
{
unsigned char *b, *p;
const unsigned char *p2;
int i;
char *ret;
if (x == NULL) return(NULL);
if (x == NULL)
return (NULL);
i=i2d(x,NULL);
b=OPENSSL_malloc(i+10);
if (b == NULL)
{ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); return(NULL); }
p= b;
i=i2d(x,&p);
p2= b;
ret=d2i(NULL,&p2,i);
OPENSSL_free(b);
return(ret);
}
i = i2d(x, NULL);
b = OPENSSL_malloc(i + 10);
if (b == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return (NULL);
}
p = b;
i = i2d(x, &p);
p2 = b;
ret = d2i(NULL, &p2, i);
OPENSSL_free(b);
return (ret);
}
/* ASN1_ITEM version of dup: this follows the model above except we don't need
* to allocate the buffer. At some point this could be rewritten to directly dup
* the underlying structure instead of doing and encode and decode. */
/*
* ASN1_ITEM version of dup: this follows the model above except we don't
* need to allocate the buffer. At some point this could be rewritten to
* directly dup the underlying structure instead of doing and encode and
* decode.
*/
void *ASN1_item_dup(const ASN1_ITEM *it, void *x)
{
unsigned char *b = NULL;
const unsigned char *p;
long i;
void *ret;
{
unsigned char *b = NULL;
const unsigned char *p;
long i;
void *ret;
if (x == NULL) return(NULL);
if (x == NULL)
return (NULL);
i=ASN1_item_i2d(x,&b,it);
if (b == NULL)
{ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); return(NULL); }
p= b;
ret=ASN1_item_d2i(NULL,&p,i, it);
OPENSSL_free(b);
return(ret);
}
i = ASN1_item_i2d(x, &b, it);
if (b == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return (NULL);
}
p = b;
ret = ASN1_item_d2i(NULL, &p, i, it);
OPENSSL_free(b);
return (ret);
}
+100 -102
View File
@@ -61,123 +61,121 @@
#include <openssl/err.h>
#include <openssl/mem.h>
/*
/*
* Code for ENUMERATED type: identical to INTEGER apart from a different tag.
* for comments on encoding see a_int.c
*/
int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
{
int j,k;
unsigned int i;
unsigned char buf[sizeof(long)+1];
long d;
{
int j, k;
unsigned int i;
unsigned char buf[sizeof(long) + 1];
long d;
a->type=V_ASN1_ENUMERATED;
if (a->length < (int)(sizeof(long)+1))
{
if (a->data != NULL)
OPENSSL_free(a->data);
if ((a->data=(unsigned char *)OPENSSL_malloc(sizeof(long)+1)) != NULL)
memset((char *)a->data,0,sizeof(long)+1);
}
if (a->data == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return(0);
}
d=v;
if (d < 0)
{
d= -d;
a->type=V_ASN1_NEG_ENUMERATED;
}
a->type = V_ASN1_ENUMERATED;
if (a->length < (int)(sizeof(long) + 1)) {
if (a->data != NULL)
OPENSSL_free(a->data);
if ((a->data =
(unsigned char *)OPENSSL_malloc(sizeof(long) + 1)) != NULL)
memset((char *)a->data, 0, sizeof(long) + 1);
}
if (a->data == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return (0);
}
d = v;
if (d < 0) {
d = -d;
a->type = V_ASN1_NEG_ENUMERATED;
}
for (i=0; i<sizeof(long); i++)
{
if (d == 0) break;
buf[i]=(int)d&0xff;
d>>=8;
}
j=0;
for (k=i-1; k >=0; k--)
a->data[j++]=buf[k];
a->length=j;
return(1);
}
for (i = 0; i < sizeof(long); i++) {
if (d == 0)
break;
buf[i] = (int)d & 0xff;
d >>= 8;
}
j = 0;
for (k = i - 1; k >= 0; k--)
a->data[j++] = buf[k];
a->length = j;
return (1);
}
long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a)
{
int neg=0,i;
long r=0;
{
int neg = 0, i;
long r = 0;
if (a == NULL) return(0L);
i=a->type;
if (i == V_ASN1_NEG_ENUMERATED)
neg=1;
else if (i != V_ASN1_ENUMERATED)
return -1;
if (a->length > (int)sizeof(long))
{
/* hmm... a bit ugly */
return(0xffffffffL);
}
if (a->data == NULL)
return 0;
if (a == NULL)
return (0L);
i = a->type;
if (i == V_ASN1_NEG_ENUMERATED)
neg = 1;
else if (i != V_ASN1_ENUMERATED)
return -1;
for (i=0; i<a->length; i++)
{
r<<=8;
r|=(unsigned char)a->data[i];
}
if (neg) r= -r;
return(r);
}
if (a->length > (int)sizeof(long)) {
/* hmm... a bit ugly */
return (0xffffffffL);
}
if (a->data == NULL)
return 0;
for (i = 0; i < a->length; i++) {
r <<= 8;
r |= (unsigned char)a->data[i];
}
if (neg)
r = -r;
return (r);
}
ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
{
ASN1_ENUMERATED *ret;
int len,j;
{
ASN1_ENUMERATED *ret;
int len, j;
if (ai == NULL)
ret=M_ASN1_ENUMERATED_new();
else
ret=ai;
if (ret == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
if(BN_is_negative(bn)) ret->type = V_ASN1_NEG_ENUMERATED;
else ret->type=V_ASN1_ENUMERATED;
j=BN_num_bits(bn);
len=((j == 0)?0:((j/8)+1));
if (ret->length < len+4)
{
unsigned char *new_data=OPENSSL_realloc(ret->data, len+4);
if (!new_data)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
ret->data=new_data;
}
if (ai == NULL)
ret = M_ASN1_ENUMERATED_new();
else
ret = ai;
if (ret == NULL) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
if (BN_is_negative(bn))
ret->type = V_ASN1_NEG_ENUMERATED;
else
ret->type = V_ASN1_ENUMERATED;
j = BN_num_bits(bn);
len = ((j == 0) ? 0 : ((j / 8) + 1));
if (ret->length < len + 4) {
unsigned char *new_data = OPENSSL_realloc(ret->data, len + 4);
if (!new_data) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
ret->data = new_data;
}
ret->length=BN_bn2bin(bn,ret->data);
return(ret);
err:
if (ret != ai) M_ASN1_ENUMERATED_free(ret);
return(NULL);
}
ret->length = BN_bn2bin(bn, ret->data);
return (ret);
err:
if (ret != ai)
M_ASN1_ENUMERATED_free(ret);
return (NULL);
}
BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn)
{
BIGNUM *ret;
{
BIGNUM *ret;
if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL)
OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB);
else if(ai->type == V_ASN1_NEG_ENUMERATED) BN_set_negative(ret,1);
return(ret);
}
if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB);
else if (ai->type == V_ASN1_NEG_ENUMERATED)
BN_set_negative(ret, 1);
return (ret);
}
+171 -170
View File
@@ -63,193 +63,194 @@
#include <openssl/mem.h>
#include <openssl/time_support.h>
#include "asn1_locl.h"
int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d)
{
static const int min[9]={ 0, 0, 1, 1, 0, 0, 0, 0, 0};
static const int max[9]={99, 99,12,31,23,59,59,12,59};
char *a;
int n,i,l,o;
{
static const int min[9] = { 0, 0, 1, 1, 0, 0, 0, 0, 0 };
static const int max[9] = { 99, 99, 12, 31, 23, 59, 59, 12, 59 };
char *a;
int n, i, l, o;
if (d->type != V_ASN1_GENERALIZEDTIME) return(0);
l=d->length;
a=(char *)d->data;
o=0;
/* GENERALIZEDTIME is similar to UTCTIME except the year is
* represented as YYYY. This stuff treats everything as a two digit
* field so make first two fields 00 to 99
*/
if (l < 13) goto err;
for (i=0; i<7; i++)
{
if ((i == 6) && ((a[o] == 'Z') ||
(a[o] == '+') || (a[o] == '-')))
{
i++;
if (tm)
tm->tm_sec = 0;
break;
}
if ((a[o] < '0') || (a[o] > '9')) goto err;
n= a[o]-'0';
if (++o > l) goto err;
if (d->type != V_ASN1_GENERALIZEDTIME)
return (0);
l = d->length;
a = (char *)d->data;
o = 0;
/*
* GENERALIZEDTIME is similar to UTCTIME except the year is represented
* as YYYY. This stuff treats everything as a two digit field so make
* first two fields 00 to 99
*/
if (l < 13)
goto err;
for (i = 0; i < 7; i++) {
if ((i == 6) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) {
i++;
if (tm)
tm->tm_sec = 0;
break;
}
if ((a[o] < '0') || (a[o] > '9'))
goto err;
n = a[o] - '0';
if (++o > l)
goto err;
if ((a[o] < '0') || (a[o] > '9')) goto err;
n=(n*10)+ a[o]-'0';
if (++o > l) goto err;
if ((a[o] < '0') || (a[o] > '9'))
goto err;
n = (n * 10) + a[o] - '0';
if (++o > l)
goto err;
if ((n < min[i]) || (n > max[i])) goto err;
if (tm)
{
switch(i)
{
case 0:
tm->tm_year = n * 100 - 1900;
break;
case 1:
tm->tm_year += n;
break;
case 2:
tm->tm_mon = n - 1;
break;
case 3:
tm->tm_mday = n;
break;
case 4:
tm->tm_hour = n;
break;
case 5:
tm->tm_min = n;
break;
case 6:
tm->tm_sec = n;
break;
}
}
}
/* Optional fractional seconds: decimal point followed by one
* or more digits.
*/
if (a[o] == '.')
{
if (++o > l) goto err;
i = o;
while ((a[o] >= '0') && (a[o] <= '9') && (o <= l))
o++;
/* Must have at least one digit after decimal point */
if (i == o) goto err;
}
if ((n < min[i]) || (n > max[i]))
goto err;
if (tm) {
switch (i) {
case 0:
tm->tm_year = n * 100 - 1900;
break;
case 1:
tm->tm_year += n;
break;
case 2:
tm->tm_mon = n - 1;
break;
case 3:
tm->tm_mday = n;
break;
case 4:
tm->tm_hour = n;
break;
case 5:
tm->tm_min = n;
break;
case 6:
tm->tm_sec = n;
break;
}
}
}
/*
* Optional fractional seconds: decimal point followed by one or more
* digits.
*/
if (a[o] == '.') {
if (++o > l)
goto err;
i = o;
while ((a[o] >= '0') && (a[o] <= '9') && (o <= l))
o++;
/* Must have at least one digit after decimal point */
if (i == o)
goto err;
}
if (a[o] == 'Z')
o++;
else if ((a[o] == '+') || (a[o] == '-'))
{
int offsign = a[o] == '-' ? -1 : 1, offset = 0;
o++;
if (o+4 > l) goto err;
for (i=7; i<9; i++)
{
if ((a[o] < '0') || (a[o] > '9')) goto err;
n= a[o]-'0';
o++;
if ((a[o] < '0') || (a[o] > '9')) goto err;
n=(n*10)+ a[o]-'0';
if ((n < min[i]) || (n > max[i])) goto err;
if (tm)
{
if (i == 7)
offset = n * 3600;
else if (i == 8)
offset += n * 60;
}
o++;
}
if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign))
return 0;
}
else if (a[o])
{
/* Missing time zone information. */
goto err;
}
return(o == l);
err:
return(0);
}
if (a[o] == 'Z')
o++;
else if ((a[o] == '+') || (a[o] == '-')) {
int offsign = a[o] == '-' ? -1 : 1, offset = 0;
o++;
if (o + 4 > l)
goto err;
for (i = 7; i < 9; i++) {
if ((a[o] < '0') || (a[o] > '9'))
goto err;
n = a[o] - '0';
o++;
if ((a[o] < '0') || (a[o] > '9'))
goto err;
n = (n * 10) + a[o] - '0';
if ((n < min[i]) || (n > max[i]))
goto err;
if (tm) {
if (i == 7)
offset = n * 3600;
else if (i == 8)
offset += n * 60;
}
o++;
}
if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign))
return 0;
} else if (a[o]) {
/* Missing time zone information. */
goto err;
}
return (o == l);
err:
return (0);
}
int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *d)
{
return asn1_generalizedtime_to_tm(NULL, d);
}
{
return asn1_generalizedtime_to_tm(NULL, d);
}
int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str)
{
ASN1_GENERALIZEDTIME t;
{
ASN1_GENERALIZEDTIME t;
t.type=V_ASN1_GENERALIZEDTIME;
t.length=strlen(str);
t.data=(unsigned char *)str;
if (ASN1_GENERALIZEDTIME_check(&t))
{
if (s != NULL)
{
if (!ASN1_STRING_set((ASN1_STRING *)s,
(unsigned char *)str,t.length))
return 0;
s->type=V_ASN1_GENERALIZEDTIME;
}
return(1);
}
else
return(0);
}
t.type = V_ASN1_GENERALIZEDTIME;
t.length = strlen(str);
t.data = (unsigned char *)str;
if (ASN1_GENERALIZEDTIME_check(&t)) {
if (s != NULL) {
if (!ASN1_STRING_set((ASN1_STRING *)s,
(unsigned char *)str, t.length))
return 0;
s->type = V_ASN1_GENERALIZEDTIME;
}
return (1);
} else
return (0);
}
ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,
time_t t)
{
return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0);
}
time_t t)
{
return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0);
}
ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
time_t t, int offset_day, long offset_sec)
{
char *p;
struct tm *ts;
struct tm data;
size_t len = 20;
time_t t, int offset_day,
long offset_sec)
{
char *p;
struct tm *ts;
struct tm data;
size_t len = 20;
if (s == NULL)
s=M_ASN1_GENERALIZEDTIME_new();
if (s == NULL)
return(NULL);
if (s == NULL)
s = M_ASN1_GENERALIZEDTIME_new();
if (s == NULL)
return (NULL);
ts=OPENSSL_gmtime(&t, &data);
if (ts == NULL)
return(NULL);
ts = OPENSSL_gmtime(&t, &data);
if (ts == NULL)
return (NULL);
if (offset_day || offset_sec)
{
if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
return NULL;
}
if (offset_day || offset_sec) {
if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
return NULL;
}
p=(char *)s->data;
if ((p == NULL) || ((size_t)s->length < len))
{
p=OPENSSL_malloc(len);
if (p == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return(NULL);
}
if (s->data != NULL)
OPENSSL_free(s->data);
s->data=(unsigned char *)p;
}
p = (char *)s->data;
if ((p == NULL) || ((size_t)s->length < len)) {
p = OPENSSL_malloc(len);
if (p == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return (NULL);
}
if (s->data != NULL)
OPENSSL_free(s->data);
s->data = (unsigned char *)p;
}
BIO_snprintf(p,len,"%04d%02d%02d%02d%02d%02dZ",ts->tm_year + 1900,
ts->tm_mon+1,ts->tm_mday,ts->tm_hour,ts->tm_min,ts->tm_sec);
s->length=strlen(p);
s->type=V_ASN1_GENERALIZEDTIME;
return(s);
}
BIO_snprintf(p, len, "%04d%02d%02d%02d%02d%02dZ", ts->tm_year + 1900,
ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min,
ts->tm_sec);
s->length = strlen(p);
s->type = V_ASN1_GENERALIZEDTIME;
return (s);
}
+76 -83
View File
@@ -59,96 +59,89 @@
#include <openssl/err.h>
#include <openssl/mem.h>
int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x)
{
BIO *b;
int ret;
{
BIO *b;
int ret;
if ((b=BIO_new(BIO_s_file())) == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b,out,BIO_NOCLOSE);
ret=ASN1_i2d_bio(i2d,b,x);
BIO_free(b);
return(ret);
if ((b = BIO_new(BIO_s_file())) == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
return (0);
}
BIO_set_fp(b, out, BIO_NOCLOSE);
ret = ASN1_i2d_bio(i2d, b, x);
BIO_free(b);
return (ret);
}
int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, void *x)
{
char *b;
unsigned char *p;
int i, j = 0, n, ret = 1;
n = i2d(x, NULL);
b = (char *)OPENSSL_malloc(n);
if (b == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return (0);
}
p = (unsigned char *)b;
i2d(x, &p);
for (;;) {
i = BIO_write(out, &(b[j]), n);
if (i == n)
break;
if (i <= 0) {
ret = 0;
break;
}
int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x)
{
char *b;
unsigned char *p;
int i,j=0,n,ret=1;
n=i2d(x,NULL);
b=(char *)OPENSSL_malloc(n);
if (b == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return(0);
}
p=(unsigned char *)b;
i2d(x,&p);
for (;;)
{
i=BIO_write(out,&(b[j]),n);
if (i == n) break;
if (i <= 0)
{
ret=0;
break;
}
j+=i;
n-=i;
}
OPENSSL_free(b);
return(ret);
}
j += i;
n -= i;
}
OPENSSL_free(b);
return (ret);
}
int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x)
{
BIO *b;
int ret;
{
BIO *b;
int ret;
if ((b=BIO_new(BIO_s_file())) == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b,out,BIO_NOCLOSE);
ret=ASN1_item_i2d_bio(it,b,x);
BIO_free(b);
return(ret);
}
if ((b = BIO_new(BIO_s_file())) == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
return (0);
}
BIO_set_fp(b, out, BIO_NOCLOSE);
ret = ASN1_item_i2d_bio(it, b, x);
BIO_free(b);
return (ret);
}
int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x)
{
unsigned char *b = NULL;
int i,j=0,n,ret=1;
{
unsigned char *b = NULL;
int i, j = 0, n, ret = 1;
n = ASN1_item_i2d(x, &b, it);
if (b == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return(0);
}
n = ASN1_item_i2d(x, &b, it);
if (b == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return (0);
}
for (;;)
{
i=BIO_write(out,&(b[j]),n);
if (i == n) break;
if (i <= 0)
{
ret=0;
break;
}
j+=i;
n-=i;
}
OPENSSL_free(b);
return(ret);
}
for (;;) {
i = BIO_write(out, &(b[j]), n);
if (i == n)
break;
if (i <= 0) {
ret = 0;
break;
}
j += i;
n -= i;
}
OPENSSL_free(b);
return (ret);
}
+335 -331
View File
@@ -61,47 +61,46 @@
#include <openssl/err.h>
#include <openssl/mem.h>
ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x)
{ return M_ASN1_INTEGER_dup(x);}
{
return M_ASN1_INTEGER_dup(x);
}
int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
{
int neg, ret;
/* Compare signs */
neg = x->type & V_ASN1_NEG;
if (neg != (y->type & V_ASN1_NEG))
{
if (neg)
return -1;
else
return 1;
}
{
int neg, ret;
/* Compare signs */
neg = x->type & V_ASN1_NEG;
if (neg != (y->type & V_ASN1_NEG)) {
if (neg)
return -1;
else
return 1;
}
ret = ASN1_STRING_cmp(x, y);
ret = ASN1_STRING_cmp(x, y);
if (neg)
return -ret;
else
return ret;
}
if (neg)
return -ret;
else
return ret;
}
/*
/*
* This converts an ASN1 INTEGER into its content encoding.
* The internal representation is an ASN1_STRING whose data is a big endian
* representation of the value, ignoring the sign. The sign is determined by
* the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative.
* the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative.
*
* Positive integers are no problem: they are almost the same as the DER
* encoding, except if the first byte is >= 0x80 we need to add a zero pad.
*
* Negative integers are a bit trickier...
* The DER representation of negative integers is in 2s complement form.
* The internal form is converted by complementing each octet and finally
* The internal form is converted by complementing each octet and finally
* adding one to the result. This can be done less messily with a little trick.
* If the internal form has trailing zeroes then they will become FF by the
* complement and 0 by the add one (due to carry) so just copy as many trailing
* complement and 0 by the add one (due to carry) so just copy as many trailing
* zeros to the destination as there are in the source. The carry will add one
* to the last none zero octet: so complement this octet and add one and finally
* complement any left over until you get to the start of the string.
@@ -113,344 +112,349 @@ int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
*/
int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
{
int pad=0,ret,i,neg;
unsigned char *p,*n,pb=0;
{
int pad = 0, ret, i, neg;
unsigned char *p, *n, pb = 0;
if (a == NULL) return(0);
neg=a->type & V_ASN1_NEG;
if (a->length == 0)
ret=1;
else
{
ret=a->length;
i=a->data[0];
if (!neg && (i > 127)) {
pad=1;
pb=0;
} else if(neg) {
if(i>128) {
pad=1;
pb=0xFF;
} else if(i == 128) {
/*
* Special case: if any other bytes non zero we pad:
* otherwise we don't.
*/
for(i = 1; i < a->length; i++) if(a->data[i]) {
pad=1;
pb=0xFF;
break;
}
}
}
ret+=pad;
}
if (pp == NULL) return(ret);
p= *pp;
if (a == NULL)
return (0);
neg = a->type & V_ASN1_NEG;
if (a->length == 0)
ret = 1;
else {
ret = a->length;
i = a->data[0];
if (ret == 1 && i == 0)
neg = 0;
if (!neg && (i > 127)) {
pad = 1;
pb = 0;
} else if (neg) {
if (i > 128) {
pad = 1;
pb = 0xFF;
} else if (i == 128) {
/*
* Special case: if any other bytes non zero we pad:
* otherwise we don't.
*/
for (i = 1; i < a->length; i++)
if (a->data[i]) {
pad = 1;
pb = 0xFF;
break;
}
}
}
ret += pad;
}
if (pp == NULL)
return (ret);
p = *pp;
if (pad) *(p++)=pb;
if (a->length == 0) *(p++)=0;
else if (!neg) memcpy(p,a->data,(unsigned int)a->length);
else {
/* Begin at the end of the encoding */
n=a->data + a->length - 1;
p += a->length - 1;
i = a->length;
/* Copy zeros to destination as long as source is zero */
while(!*n) {
*(p--) = 0;
n--;
i--;
}
/* Complement and increment next octet */
*(p--) = ((*(n--)) ^ 0xff) + 1;
i--;
/* Complement any octets left */
for(;i > 0; i--) *(p--) = *(n--) ^ 0xff;
}
if (pad)
*(p++) = pb;
if (a->length == 0)
*(p++) = 0;
else if (!neg)
memcpy(p, a->data, (unsigned int)a->length);
else {
/* Begin at the end of the encoding */
n = a->data + a->length - 1;
p += a->length - 1;
i = a->length;
/* Copy zeros to destination as long as source is zero */
while (!*n && i > 1) {
*(p--) = 0;
n--;
i--;
}
/* Complement and increment next octet */
*(p--) = ((*(n--)) ^ 0xff) + 1;
i--;
/* Complement any octets left */
for (; i > 0; i--)
*(p--) = *(n--) ^ 0xff;
}
*pp+=ret;
return(ret);
}
*pp += ret;
return (ret);
}
/* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */
ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
long len)
{
ASN1_INTEGER *ret=NULL;
const unsigned char *p, *pend;
unsigned char *to,*s;
int i;
long len)
{
ASN1_INTEGER *ret = NULL;
const unsigned char *p, *pend;
unsigned char *to, *s;
int i;
if ((a == NULL) || ((*a) == NULL))
{
if ((ret=M_ASN1_INTEGER_new()) == NULL) return(NULL);
ret->type=V_ASN1_INTEGER;
}
else
ret=(*a);
if ((a == NULL) || ((*a) == NULL)) {
if ((ret = M_ASN1_INTEGER_new()) == NULL)
return (NULL);
ret->type = V_ASN1_INTEGER;
} else
ret = (*a);
p= *pp;
pend = p + len;
p = *pp;
pend = p + len;
/* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it
* signifies a missing NULL parameter. */
s=(unsigned char *)OPENSSL_malloc((int)len+1);
if (s == NULL)
{
i=ERR_R_MALLOC_FAILURE;
goto err;
}
to=s;
if(!len) {
/* Strictly speaking this is an illegal INTEGER but we
* tolerate it.
*/
ret->type=V_ASN1_INTEGER;
} else if (*p & 0x80) /* a negative number */
{
ret->type=V_ASN1_NEG_INTEGER;
if ((*p == 0xff) && (len != 1)) {
p++;
len--;
}
i = len;
p += i - 1;
to += i - 1;
while((!*p) && i) {
*(to--) = 0;
i--;
p--;
}
/* Special case: if all zeros then the number will be of
* the form FF followed by n zero bytes: this corresponds to
* 1 followed by n zero bytes. We've already written n zeros
* so we just append an extra one and set the first byte to
* a 1. This is treated separately because it is the only case
* where the number of bytes is larger than len.
*/
if(!i) {
*s = 1;
s[len] = 0;
len++;
} else {
*(to--) = (*(p--) ^ 0xff) + 1;
i--;
for(;i > 0; i--) *(to--) = *(p--) ^ 0xff;
}
} else {
ret->type=V_ASN1_INTEGER;
if ((*p == 0) && (len != 1))
{
p++;
len--;
}
memcpy(s,p,(int)len);
}
/*
* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies
* a missing NULL parameter.
*/
s = (unsigned char *)OPENSSL_malloc((int)len + 1);
if (s == NULL) {
i = ERR_R_MALLOC_FAILURE;
goto err;
}
to = s;
if (!len) {
/*
* Strictly speaking this is an illegal INTEGER but we tolerate it.
*/
ret->type = V_ASN1_INTEGER;
} else if (*p & 0x80) { /* a negative number */
ret->type = V_ASN1_NEG_INTEGER;
if ((*p == 0xff) && (len != 1)) {
p++;
len--;
}
i = len;
p += i - 1;
to += i - 1;
while ((!*p) && i) {
*(to--) = 0;
i--;
p--;
}
/*
* Special case: if all zeros then the number will be of the form FF
* followed by n zero bytes: this corresponds to 1 followed by n zero
* bytes. We've already written n zeros so we just append an extra
* one and set the first byte to a 1. This is treated separately
* because it is the only case where the number of bytes is larger
* than len.
*/
if (!i) {
*s = 1;
s[len] = 0;
len++;
} else {
*(to--) = (*(p--) ^ 0xff) + 1;
i--;
for (; i > 0; i--)
*(to--) = *(p--) ^ 0xff;
}
} else {
ret->type = V_ASN1_INTEGER;
if ((*p == 0) && (len != 1)) {
p++;
len--;
}
memcpy(s, p, (int)len);
}
if (ret->data != NULL) OPENSSL_free(ret->data);
ret->data=s;
ret->length=(int)len;
if (a != NULL) (*a)=ret;
*pp=pend;
return(ret);
err:
OPENSSL_PUT_ERROR(ASN1, i);
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
M_ASN1_INTEGER_free(ret);
return(NULL);
}
if (ret->data != NULL)
OPENSSL_free(ret->data);
ret->data = s;
ret->length = (int)len;
if (a != NULL)
(*a) = ret;
*pp = pend;
return (ret);
err:
OPENSSL_PUT_ERROR(ASN1, i);
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
M_ASN1_INTEGER_free(ret);
return (NULL);
}
/* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of
* ASN1 integers: some broken software can encode a positive INTEGER
* with its MSB set as negative (it doesn't add a padding zero).
/*
* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of ASN1
* integers: some broken software can encode a positive INTEGER with its MSB
* set as negative (it doesn't add a padding zero).
*/
ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
long length)
{
ASN1_INTEGER *ret=NULL;
const unsigned char *p;
unsigned char *s;
long len;
int inf,tag,xclass;
int i;
long length)
{
ASN1_INTEGER *ret = NULL;
const unsigned char *p;
unsigned char *s;
long len;
int inf, tag, xclass;
int i;
if ((a == NULL) || ((*a) == NULL))
{
if ((ret=M_ASN1_INTEGER_new()) == NULL) return(NULL);
ret->type=V_ASN1_INTEGER;
}
else
ret=(*a);
if ((a == NULL) || ((*a) == NULL)) {
if ((ret = M_ASN1_INTEGER_new()) == NULL)
return (NULL);
ret->type = V_ASN1_INTEGER;
} else
ret = (*a);
p= *pp;
inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
if (inf & 0x80)
{
i=ASN1_R_BAD_OBJECT_HEADER;
goto err;
}
p = *pp;
inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
if (inf & 0x80) {
i = ASN1_R_BAD_OBJECT_HEADER;
goto err;
}
if (tag != V_ASN1_INTEGER)
{
i=ASN1_R_EXPECTING_AN_INTEGER;
goto err;
}
if (tag != V_ASN1_INTEGER) {
i = ASN1_R_EXPECTING_AN_INTEGER;
goto err;
}
/* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it
* signifies a missing NULL parameter. */
s=(unsigned char *)OPENSSL_malloc((int)len+1);
if (s == NULL)
{
i=ERR_R_MALLOC_FAILURE;
goto err;
}
ret->type=V_ASN1_INTEGER;
if(len) {
if ((*p == 0) && (len != 1))
{
p++;
len--;
}
memcpy(s,p,(int)len);
p+=len;
}
/*
* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies
* a missing NULL parameter.
*/
s = (unsigned char *)OPENSSL_malloc((int)len + 1);
if (s == NULL) {
i = ERR_R_MALLOC_FAILURE;
goto err;
}
ret->type = V_ASN1_INTEGER;
if (len) {
if ((*p == 0) && (len != 1)) {
p++;
len--;
}
memcpy(s, p, (int)len);
p += len;
}
if (ret->data != NULL) OPENSSL_free(ret->data);
ret->data=s;
ret->length=(int)len;
if (a != NULL) (*a)=ret;
*pp=p;
return(ret);
err:
OPENSSL_PUT_ERROR(ASN1, i);
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
M_ASN1_INTEGER_free(ret);
return(NULL);
}
if (ret->data != NULL)
OPENSSL_free(ret->data);
ret->data = s;
ret->length = (int)len;
if (a != NULL)
(*a) = ret;
*pp = p;
return (ret);
err:
OPENSSL_PUT_ERROR(ASN1, i);
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
M_ASN1_INTEGER_free(ret);
return (NULL);
}
int ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
{
int j,k;
unsigned int i;
unsigned char buf[sizeof(long)+1];
long d;
{
int j, k;
unsigned int i;
unsigned char buf[sizeof(long) + 1];
long d;
a->type=V_ASN1_INTEGER;
if (a->length < (int)(sizeof(long)+1))
{
if (a->data != NULL)
OPENSSL_free(a->data);
if ((a->data=(unsigned char *)OPENSSL_malloc(sizeof(long)+1)) != NULL)
memset((char *)a->data,0,sizeof(long)+1);
}
if (a->data == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return(0);
}
d=v;
if (d < 0)
{
d= -d;
a->type=V_ASN1_NEG_INTEGER;
}
a->type = V_ASN1_INTEGER;
if (a->length < (int)(sizeof(long) + 1)) {
if (a->data != NULL)
OPENSSL_free(a->data);
if ((a->data =
(unsigned char *)OPENSSL_malloc(sizeof(long) + 1)) != NULL)
memset((char *)a->data, 0, sizeof(long) + 1);
}
if (a->data == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return (0);
}
d = v;
if (d < 0) {
d = -d;
a->type = V_ASN1_NEG_INTEGER;
}
for (i=0; i<sizeof(long); i++)
{
if (d == 0) break;
buf[i]=(int)d&0xff;
d>>=8;
}
j=0;
for (k=i-1; k >=0; k--)
a->data[j++]=buf[k];
a->length=j;
return(1);
}
for (i = 0; i < sizeof(long); i++) {
if (d == 0)
break;
buf[i] = (int)d & 0xff;
d >>= 8;
}
j = 0;
for (k = i - 1; k >= 0; k--)
a->data[j++] = buf[k];
a->length = j;
return (1);
}
long ASN1_INTEGER_get(const ASN1_INTEGER *a)
{
int neg=0,i;
long r=0;
{
int neg = 0, i;
long r = 0;
if (a == NULL) return(0L);
i=a->type;
if (i == V_ASN1_NEG_INTEGER)
neg=1;
else if (i != V_ASN1_INTEGER)
return -1;
if (a->length > (int)sizeof(long))
{
/* hmm... a bit ugly, return all ones */
return -1;
}
if (a->data == NULL)
return 0;
if (a == NULL)
return (0L);
i = a->type;
if (i == V_ASN1_NEG_INTEGER)
neg = 1;
else if (i != V_ASN1_INTEGER)
return -1;
for (i=0; i<a->length; i++)
{
r<<=8;
r|=(unsigned char)a->data[i];
}
if (neg) r= -r;
return(r);
}
if (a->length > (int)sizeof(long)) {
/* hmm... a bit ugly, return all ones */
return -1;
}
if (a->data == NULL)
return 0;
for (i = 0; i < a->length; i++) {
r <<= 8;
r |= (unsigned char)a->data[i];
}
if (neg)
r = -r;
return (r);
}
ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
{
ASN1_INTEGER *ret;
int len,j;
{
ASN1_INTEGER *ret;
int len, j;
if (ai == NULL)
ret=M_ASN1_INTEGER_new();
else
ret=ai;
if (ret == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
if (BN_is_negative(bn) && !BN_is_zero(bn))
ret->type = V_ASN1_NEG_INTEGER;
else ret->type=V_ASN1_INTEGER;
j=BN_num_bits(bn);
len=((j == 0)?0:((j/8)+1));
if (ret->length < len+4)
{
unsigned char *new_data=OPENSSL_realloc(ret->data, len+4);
if (!new_data)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
ret->data=new_data;
}
ret->length=BN_bn2bin(bn,ret->data);
/* Correct zero case */
if(!ret->length)
{
ret->data[0] = 0;
ret->length = 1;
}
return(ret);
err:
if (ret != ai) M_ASN1_INTEGER_free(ret);
return(NULL);
}
if (ai == NULL)
ret = M_ASN1_INTEGER_new();
else
ret = ai;
if (ret == NULL) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
if (BN_is_negative(bn) && !BN_is_zero(bn))
ret->type = V_ASN1_NEG_INTEGER;
else
ret->type = V_ASN1_INTEGER;
j = BN_num_bits(bn);
len = ((j == 0) ? 0 : ((j / 8) + 1));
if (ret->length < len + 4) {
unsigned char *new_data = OPENSSL_realloc(ret->data, len + 4);
if (!new_data) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
ret->data = new_data;
}
ret->length = BN_bn2bin(bn, ret->data);
/* Correct zero case */
if (!ret->length) {
ret->data[0] = 0;
ret->length = 1;
}
return (ret);
err:
if (ret != ai)
M_ASN1_INTEGER_free(ret);
return (NULL);
}
BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
{
BIGNUM *ret;
{
BIGNUM *ret;
if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL)
OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB);
else if(ai->type == V_ASN1_NEG_INTEGER)
BN_set_negative(ret, 1);
return(ret);
}
if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB);
else if (ai->type == V_ASN1_NEG_INTEGER)
BN_set_negative(ret, 1);
return (ret);
}
+258 -239
View File
@@ -61,9 +61,9 @@
#include <openssl/err.h>
#include <openssl/mem.h>
static int traverse_string(const unsigned char *p, int len, int inform,
int (*rfunc)(unsigned long value, void *in), void *arg);
int (*rfunc) (unsigned long value, void *in),
void *arg);
static int in_utf8(unsigned long value, void *arg);
static int out_utf8(unsigned long value, void *arg);
static int type_str(unsigned long value, void *arg);
@@ -73,208 +73,219 @@ static int cpy_univ(unsigned long value, void *arg);
static int cpy_utf8(unsigned long value, void *arg);
static int is_printable(unsigned long value);
/* These functions take a string in UTF8, ASCII or multibyte form and
* a mask of permissible ASN1 string types. It then works out the minimal
* type (using the order Printable < IA5 < T61 < BMP < Universal < UTF8)
* and creates a string of the correct type with the supplied data.
* Yes this is horrible: it has to be :-(
* The 'ncopy' form checks minimum and maximum size limits too.
/*
* These functions take a string in UTF8, ASCII or multibyte form and a mask
* of permissible ASN1 string types. It then works out the minimal type
* (using the order Printable < IA5 < T61 < BMP < Universal < UTF8) and
* creates a string of the correct type with the supplied data. Yes this is
* horrible: it has to be :-( The 'ncopy' form checks minimum and maximum
* size limits too.
*/
int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
int inform, unsigned long mask)
int inform, unsigned long mask)
{
return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0);
return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0);
}
int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
int inform, unsigned long mask,
long minsize, long maxsize)
int inform, unsigned long mask,
long minsize, long maxsize)
{
int str_type;
int ret;
char free_out;
int outform, outlen = 0;
ASN1_STRING *dest;
unsigned char *p;
int nchar;
char strbuf[32];
int (*cpyfunc)(unsigned long,void *) = NULL;
if(len == -1) len = strlen((const char *)in);
if(!mask) mask = DIRSTRING_TYPE;
int str_type;
int ret;
char free_out;
int outform, outlen = 0;
ASN1_STRING *dest;
unsigned char *p;
int nchar;
char strbuf[32];
int (*cpyfunc) (unsigned long, void *) = NULL;
if (len == -1)
len = strlen((const char *)in);
if (!mask)
mask = DIRSTRING_TYPE;
/* First do a string check and work out the number of characters */
switch(inform) {
/* First do a string check and work out the number of characters */
switch (inform) {
case MBSTRING_BMP:
if(len & 1) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BMPSTRING_LENGTH);
return -1;
}
nchar = len >> 1;
break;
case MBSTRING_BMP:
if (len & 1) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BMPSTRING_LENGTH);
return -1;
}
nchar = len >> 1;
break;
case MBSTRING_UNIV:
if(len & 3) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
return -1;
}
nchar = len >> 2;
break;
case MBSTRING_UNIV:
if (len & 3) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
return -1;
}
nchar = len >> 2;
break;
case MBSTRING_UTF8:
nchar = 0;
/* This counts the characters and does utf8 syntax checking */
ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar);
if(ret < 0) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UTF8STRING);
return -1;
}
break;
case MBSTRING_UTF8:
nchar = 0;
/* This counts the characters and does utf8 syntax checking */
ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar);
if (ret < 0) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UTF8STRING);
return -1;
}
break;
case MBSTRING_ASC:
nchar = len;
break;
case MBSTRING_ASC:
nchar = len;
break;
default:
OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT);
return -1;
}
default:
OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT);
return -1;
}
if((minsize > 0) && (nchar < minsize)) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT);
BIO_snprintf(strbuf, sizeof strbuf, "%ld", minsize);
ERR_add_error_data(2, "minsize=", strbuf);
return -1;
}
if ((minsize > 0) && (nchar < minsize)) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT);
BIO_snprintf(strbuf, sizeof strbuf, "%ld", minsize);
ERR_add_error_data(2, "minsize=", strbuf);
return -1;
}
if((maxsize > 0) && (nchar > maxsize)) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_LONG);
BIO_snprintf(strbuf, sizeof strbuf, "%ld", maxsize);
ERR_add_error_data(2, "maxsize=", strbuf);
return -1;
}
if ((maxsize > 0) && (nchar > maxsize)) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_LONG);
BIO_snprintf(strbuf, sizeof strbuf, "%ld", maxsize);
ERR_add_error_data(2, "maxsize=", strbuf);
return -1;
}
/* Now work out minimal type (if any) */
if(traverse_string(in, len, inform, type_str, &mask) < 0) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_CHARACTERS);
return -1;
}
/* Now work out minimal type (if any) */
if (traverse_string(in, len, inform, type_str, &mask) < 0) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_CHARACTERS);
return -1;
}
/* Now work out output format and string type */
outform = MBSTRING_ASC;
if (mask & B_ASN1_PRINTABLESTRING)
str_type = V_ASN1_PRINTABLESTRING;
else if (mask & B_ASN1_IA5STRING)
str_type = V_ASN1_IA5STRING;
else if (mask & B_ASN1_T61STRING)
str_type = V_ASN1_T61STRING;
else if (mask & B_ASN1_BMPSTRING) {
str_type = V_ASN1_BMPSTRING;
outform = MBSTRING_BMP;
} else if (mask & B_ASN1_UNIVERSALSTRING) {
str_type = V_ASN1_UNIVERSALSTRING;
outform = MBSTRING_UNIV;
} else {
str_type = V_ASN1_UTF8STRING;
outform = MBSTRING_UTF8;
}
if (!out)
return str_type;
if (*out) {
free_out = 0;
dest = *out;
if (dest->data) {
dest->length = 0;
OPENSSL_free(dest->data);
dest->data = NULL;
}
dest->type = str_type;
} else {
free_out = 1;
dest = ASN1_STRING_type_new(str_type);
if (!dest) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return -1;
}
*out = dest;
}
/* If both the same type just copy across */
if (inform == outform) {
if (!ASN1_STRING_set(dest, in, len)) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return -1;
}
return str_type;
}
/* Now work out output format and string type */
outform = MBSTRING_ASC;
if(mask & B_ASN1_PRINTABLESTRING) str_type = V_ASN1_PRINTABLESTRING;
else if(mask & B_ASN1_IA5STRING) str_type = V_ASN1_IA5STRING;
else if(mask & B_ASN1_T61STRING) str_type = V_ASN1_T61STRING;
else if(mask & B_ASN1_BMPSTRING) {
str_type = V_ASN1_BMPSTRING;
outform = MBSTRING_BMP;
} else if(mask & B_ASN1_UNIVERSALSTRING) {
str_type = V_ASN1_UNIVERSALSTRING;
outform = MBSTRING_UNIV;
} else {
str_type = V_ASN1_UTF8STRING;
outform = MBSTRING_UTF8;
}
if(!out) return str_type;
if(*out) {
free_out = 0;
dest = *out;
if(dest->data) {
dest->length = 0;
OPENSSL_free(dest->data);
dest->data = NULL;
}
dest->type = str_type;
} else {
free_out = 1;
dest = ASN1_STRING_type_new(str_type);
if(!dest) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return -1;
}
*out = dest;
}
/* If both the same type just copy across */
if(inform == outform) {
if(!ASN1_STRING_set(dest, in, len)) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return -1;
}
return str_type;
}
/* Work out how much space the destination will need */
switch (outform) {
case MBSTRING_ASC:
outlen = nchar;
cpyfunc = cpy_asc;
break;
/* Work out how much space the destination will need */
switch(outform) {
case MBSTRING_ASC:
outlen = nchar;
cpyfunc = cpy_asc;
break;
case MBSTRING_BMP:
outlen = nchar << 1;
cpyfunc = cpy_bmp;
break;
case MBSTRING_BMP:
outlen = nchar << 1;
cpyfunc = cpy_bmp;
break;
case MBSTRING_UNIV:
outlen = nchar << 2;
cpyfunc = cpy_univ;
break;
case MBSTRING_UNIV:
outlen = nchar << 2;
cpyfunc = cpy_univ;
break;
case MBSTRING_UTF8:
outlen = 0;
traverse_string(in, len, inform, out_utf8, &outlen);
cpyfunc = cpy_utf8;
break;
}
if(!(p = OPENSSL_malloc(outlen + 1))) {
if(free_out) ASN1_STRING_free(dest);
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return -1;
}
dest->length = outlen;
dest->data = p;
p[outlen] = 0;
traverse_string(in, len, inform, cpyfunc, &p);
return str_type;
case MBSTRING_UTF8:
outlen = 0;
traverse_string(in, len, inform, out_utf8, &outlen);
cpyfunc = cpy_utf8;
break;
}
if (!(p = OPENSSL_malloc(outlen + 1))) {
if (free_out)
ASN1_STRING_free(dest);
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return -1;
}
dest->length = outlen;
dest->data = p;
p[outlen] = 0;
traverse_string(in, len, inform, cpyfunc, &p);
return str_type;
}
/* This function traverses a string and passes the value of each character
* to an optional function along with a void * argument.
/*
* This function traverses a string and passes the value of each character to
* an optional function along with a void * argument.
*/
static int traverse_string(const unsigned char *p, int len, int inform,
int (*rfunc)(unsigned long value, void *in), void *arg)
int (*rfunc) (unsigned long value, void *in),
void *arg)
{
unsigned long value;
int ret;
while(len) {
if(inform == MBSTRING_ASC) {
value = *p++;
len--;
} else if(inform == MBSTRING_BMP) {
value = *p++ << 8;
value |= *p++;
len -= 2;
} else if(inform == MBSTRING_UNIV) {
value = ((unsigned long)*p++) << 24;
value |= ((unsigned long)*p++) << 16;
value |= *p++ << 8;
value |= *p++;
len -= 4;
} else {
ret = UTF8_getc(p, len, &value);
if(ret < 0) return -1;
len -= ret;
p += ret;
}
if(rfunc) {
ret = rfunc(value, arg);
if(ret <= 0) return ret;
}
}
return 1;
unsigned long value;
int ret;
while (len) {
if (inform == MBSTRING_ASC) {
value = *p++;
len--;
} else if (inform == MBSTRING_BMP) {
value = *p++ << 8;
value |= *p++;
len -= 2;
} else if (inform == MBSTRING_UNIV) {
value = ((unsigned long)*p++) << 24;
value |= ((unsigned long)*p++) << 16;
value |= *p++ << 8;
value |= *p++;
len -= 4;
} else {
ret = UTF8_getc(p, len, &value);
if (ret < 0)
return -1;
len -= ret;
p += ret;
}
if (rfunc) {
ret = rfunc(value, arg);
if (ret <= 0)
return ret;
}
}
return 1;
}
/* Various utility functions for traverse_string */
@@ -283,108 +294,116 @@ static int traverse_string(const unsigned char *p, int len, int inform,
static int in_utf8(unsigned long value, void *arg)
{
int *nchar;
nchar = arg;
(*nchar)++;
return 1;
int *nchar;
nchar = arg;
(*nchar)++;
return 1;
}
/* Determine size of output as a UTF8 String */
static int out_utf8(unsigned long value, void *arg)
{
int *outlen;
outlen = arg;
*outlen += UTF8_putc(NULL, -1, value);
return 1;
int *outlen;
outlen = arg;
*outlen += UTF8_putc(NULL, -1, value);
return 1;
}
/* Determine the "type" of a string: check each character against a
* supplied "mask".
/*
* Determine the "type" of a string: check each character against a supplied
* "mask".
*/
static int type_str(unsigned long value, void *arg)
{
unsigned long types;
types = *((unsigned long *)arg);
if((types & B_ASN1_PRINTABLESTRING) && !is_printable(value))
types &= ~B_ASN1_PRINTABLESTRING;
if((types & B_ASN1_IA5STRING) && (value > 127))
types &= ~B_ASN1_IA5STRING;
if((types & B_ASN1_T61STRING) && (value > 0xff))
types &= ~B_ASN1_T61STRING;
if((types & B_ASN1_BMPSTRING) && (value > 0xffff))
types &= ~B_ASN1_BMPSTRING;
if(!types) return -1;
*((unsigned long *)arg) = types;
return 1;
unsigned long types;
types = *((unsigned long *)arg);
if ((types & B_ASN1_PRINTABLESTRING) && !is_printable(value))
types &= ~B_ASN1_PRINTABLESTRING;
if ((types & B_ASN1_IA5STRING) && (value > 127))
types &= ~B_ASN1_IA5STRING;
if ((types & B_ASN1_T61STRING) && (value > 0xff))
types &= ~B_ASN1_T61STRING;
if ((types & B_ASN1_BMPSTRING) && (value > 0xffff))
types &= ~B_ASN1_BMPSTRING;
if (!types)
return -1;
*((unsigned long *)arg) = types;
return 1;
}
/* Copy one byte per character ASCII like strings */
static int cpy_asc(unsigned long value, void *arg)
{
unsigned char **p, *q;
p = arg;
q = *p;
*q = (unsigned char) value;
(*p)++;
return 1;
unsigned char **p, *q;
p = arg;
q = *p;
*q = (unsigned char)value;
(*p)++;
return 1;
}
/* Copy two byte per character BMPStrings */
static int cpy_bmp(unsigned long value, void *arg)
{
unsigned char **p, *q;
p = arg;
q = *p;
*q++ = (unsigned char) ((value >> 8) & 0xff);
*q = (unsigned char) (value & 0xff);
*p += 2;
return 1;
unsigned char **p, *q;
p = arg;
q = *p;
*q++ = (unsigned char)((value >> 8) & 0xff);
*q = (unsigned char)(value & 0xff);
*p += 2;
return 1;
}
/* Copy four byte per character UniversalStrings */
static int cpy_univ(unsigned long value, void *arg)
{
unsigned char **p, *q;
p = arg;
q = *p;
*q++ = (unsigned char) ((value >> 24) & 0xff);
*q++ = (unsigned char) ((value >> 16) & 0xff);
*q++ = (unsigned char) ((value >> 8) & 0xff);
*q = (unsigned char) (value & 0xff);
*p += 4;
return 1;
unsigned char **p, *q;
p = arg;
q = *p;
*q++ = (unsigned char)((value >> 24) & 0xff);
*q++ = (unsigned char)((value >> 16) & 0xff);
*q++ = (unsigned char)((value >> 8) & 0xff);
*q = (unsigned char)(value & 0xff);
*p += 4;
return 1;
}
/* Copy to a UTF8String */
static int cpy_utf8(unsigned long value, void *arg)
{
unsigned char **p;
int ret;
p = arg;
/* We already know there is enough room so pass 0xff as the length */
ret = UTF8_putc(*p, 0xff, value);
*p += ret;
return 1;
unsigned char **p;
int ret;
p = arg;
/* We already know there is enough room so pass 0xff as the length */
ret = UTF8_putc(*p, 0xff, value);
*p += ret;
return 1;
}
/* Return 1 if the character is permitted in a PrintableString */
static int is_printable(unsigned long value)
{
int ch;
if(value > 0x7f) return 0;
ch = (int) value;
/* Note: we can't use 'isalnum' because certain accented
* characters may count as alphanumeric in some environments.
*/
if((ch >= 'a') && (ch <= 'z')) return 1;
if((ch >= 'A') && (ch <= 'Z')) return 1;
if((ch >= '0') && (ch <= '9')) return 1;
if ((ch == ' ') || strchr("'()+,-./:=?", ch)) return 1;
return 0;
int ch;
if (value > 0x7f)
return 0;
ch = (int)value;
/*
* Note: we can't use 'isalnum' because certain accented characters may
* count as alphanumeric in some environments.
*/
if ((ch >= 'a') && (ch <= 'z'))
return 1;
if ((ch >= 'A') && (ch <= 'Z'))
return 1;
if ((ch >= '0') && (ch <= '9'))
return 1;
if ((ch == ' ') || strchr("'()+,-./:=?", ch))
return 1;
return 0;
}
+293 -309
View File
@@ -63,350 +63,334 @@
#include <openssl/mem.h>
#include <openssl/obj.h>
int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
{
unsigned char *p;
int objsize;
{
unsigned char *p;
int objsize;
if ((a == NULL) || (a->data == NULL)) return(0);
if ((a == NULL) || (a->data == NULL))
return (0);
objsize = ASN1_object_size(0,a->length,V_ASN1_OBJECT);
if (pp == NULL) return objsize;
objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT);
if (pp == NULL)
return objsize;
p= *pp;
ASN1_put_object(&p,0,a->length,V_ASN1_OBJECT,V_ASN1_UNIVERSAL);
memcpy(p,a->data,a->length);
p+=a->length;
p = *pp;
ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
memcpy(p, a->data, a->length);
p += a->length;
*pp=p;
return(objsize);
}
*pp = p;
return (objsize);
}
int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
{
int i,first,len=0,c, use_bn;
char ftmp[24], *tmp = ftmp;
int tmpsize = sizeof ftmp;
const char *p;
unsigned long l;
BIGNUM *bl = NULL;
{
int i, first, len = 0, c, use_bn;
char ftmp[24], *tmp = ftmp;
int tmpsize = sizeof ftmp;
const char *p;
unsigned long l;
BIGNUM *bl = NULL;
if (num == 0)
return(0);
else if (num == -1)
num=strlen(buf);
if (num == 0)
return (0);
else if (num == -1)
num = strlen(buf);
p=buf;
c= *(p++);
num--;
if ((c >= '0') && (c <= '2'))
{
first= c-'0';
}
else
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_FIRST_NUM_TOO_LARGE);
goto err;
}
p = buf;
c = *(p++);
num--;
if ((c >= '0') && (c <= '2')) {
first = c - '0';
} else {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_FIRST_NUM_TOO_LARGE);
goto err;
}
if (num <= 0)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_SECOND_NUMBER);
goto err;
}
c= *(p++);
num--;
for (;;)
{
if (num <= 0) break;
if ((c != '.') && (c != ' '))
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_SEPARATOR);
goto err;
}
l=0;
use_bn = 0;
for (;;)
{
if (num <= 0) break;
num--;
c= *(p++);
if ((c == ' ') || (c == '.'))
break;
if ((c < '0') || (c > '9'))
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_DIGIT);
goto err;
}
if (!use_bn && l >= ((ULONG_MAX - 80) / 10L))
{
use_bn = 1;
if (!bl)
bl = BN_new();
if (!bl || !BN_set_word(bl, l))
goto err;
}
if (use_bn)
{
if (!BN_mul_word(bl, 10L)
|| !BN_add_word(bl, c-'0'))
goto err;
}
else
l=l*10L+(long)(c-'0');
}
if (len == 0)
{
if ((first < 2) && (l >= 40))
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_SECOND_NUMBER_TOO_LARGE);
goto err;
}
if (use_bn)
{
if (!BN_add_word(bl, first * 40))
goto err;
}
else
l+=(long)first*40;
}
i=0;
if (use_bn)
{
int blsize;
blsize = BN_num_bits(bl);
blsize = (blsize + 6)/7;
if (blsize > tmpsize)
{
if (tmp != ftmp)
OPENSSL_free(tmp);
tmpsize = blsize + 32;
tmp = OPENSSL_malloc(tmpsize);
if (!tmp)
goto err;
}
while(blsize--)
tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L);
}
else
{
for (;;)
{
tmp[i++]=(unsigned char)l&0x7f;
l>>=7L;
if (l == 0L) break;
}
if (num <= 0) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_SECOND_NUMBER);
goto err;
}
c = *(p++);
num--;
for (;;) {
if (num <= 0)
break;
if ((c != '.') && (c != ' ')) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_SEPARATOR);
goto err;
}
l = 0;
use_bn = 0;
for (;;) {
if (num <= 0)
break;
num--;
c = *(p++);
if ((c == ' ') || (c == '.'))
break;
if ((c < '0') || (c > '9')) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_DIGIT);
goto err;
}
if (!use_bn && l >= ((ULONG_MAX - 80) / 10L)) {
use_bn = 1;
if (!bl)
bl = BN_new();
if (!bl || !BN_set_word(bl, l))
goto err;
}
if (use_bn) {
if (!BN_mul_word(bl, 10L)
|| !BN_add_word(bl, c - '0'))
goto err;
} else
l = l * 10L + (long)(c - '0');
}
if (len == 0) {
if ((first < 2) && (l >= 40)) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_SECOND_NUMBER_TOO_LARGE);
goto err;
}
if (use_bn) {
if (!BN_add_word(bl, first * 40))
goto err;
} else
l += (long)first *40;
}
i = 0;
if (use_bn) {
int blsize;
blsize = BN_num_bits(bl);
blsize = (blsize + 6) / 7;
if (blsize > tmpsize) {
if (tmp != ftmp)
OPENSSL_free(tmp);
tmpsize = blsize + 32;
tmp = OPENSSL_malloc(tmpsize);
if (!tmp)
goto err;
}
while (blsize--)
tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L);
} else {
}
if (out != NULL)
{
if (len+i > olen)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_BUFFER_TOO_SMALL);
goto err;
}
while (--i > 0)
out[len++]=tmp[i]|0x80;
out[len++]=tmp[0];
}
else
len+=i;
}
if (tmp != ftmp)
OPENSSL_free(tmp);
if (bl)
BN_free(bl);
return(len);
err:
if (tmp != ftmp)
OPENSSL_free(tmp);
if (bl)
BN_free(bl);
return(0);
}
for (;;) {
tmp[i++] = (unsigned char)l & 0x7f;
l >>= 7L;
if (l == 0L)
break;
}
}
if (out != NULL) {
if (len + i > olen) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_BUFFER_TOO_SMALL);
goto err;
}
while (--i > 0)
out[len++] = tmp[i] | 0x80;
out[len++] = tmp[0];
} else
len += i;
}
if (tmp != ftmp)
OPENSSL_free(tmp);
if (bl)
BN_free(bl);
return (len);
err:
if (tmp != ftmp)
OPENSSL_free(tmp);
if (bl)
BN_free(bl);
return (0);
}
int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a)
{
return OBJ_obj2txt(buf, buf_len, a, 0);
return OBJ_obj2txt(buf, buf_len, a, 0);
}
int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a)
{
char buf[80], *p = buf;
int i;
{
char buf[80], *p = buf;
int i;
if ((a == NULL) || (a->data == NULL))
return(BIO_write(bp,"NULL",4));
i=i2t_ASN1_OBJECT(buf,sizeof buf,a);
if (i > (int)(sizeof(buf) - 1))
{
p = OPENSSL_malloc(i + 1);
if (!p)
return -1;
i2t_ASN1_OBJECT(p,i + 1,a);
}
if (i <= 0)
return BIO_write(bp, "<INVALID>", 9);
BIO_write(bp,p,i);
if (p != buf)
OPENSSL_free(p);
return(i);
}
if ((a == NULL) || (a->data == NULL))
return (BIO_write(bp, "NULL", 4));
i = i2t_ASN1_OBJECT(buf, sizeof buf, a);
if (i > (int)(sizeof(buf) - 1)) {
p = OPENSSL_malloc(i + 1);
if (!p)
return -1;
i2t_ASN1_OBJECT(p, i + 1, a);
}
if (i <= 0)
return BIO_write(bp, "<INVALID>", 9);
BIO_write(bp, p, i);
if (p != buf)
OPENSSL_free(p);
return (i);
}
ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
long length)
long length)
{
const unsigned char *p;
long len;
int tag,xclass;
int inf,i;
ASN1_OBJECT *ret = NULL;
p= *pp;
inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
if (inf & 0x80)
{
i=ASN1_R_BAD_OBJECT_HEADER;
goto err;
}
const unsigned char *p;
long len;
int tag, xclass;
int inf, i;
ASN1_OBJECT *ret = NULL;
p = *pp;
inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
if (inf & 0x80) {
i = ASN1_R_BAD_OBJECT_HEADER;
goto err;
}
if (tag != V_ASN1_OBJECT)
{
i=ASN1_R_EXPECTING_AN_OBJECT;
goto err;
}
ret = c2i_ASN1_OBJECT(a, &p, len);
if(ret) *pp = p;
return ret;
err:
OPENSSL_PUT_ERROR(ASN1, i);
return(NULL);
if (tag != V_ASN1_OBJECT) {
i = ASN1_R_EXPECTING_AN_OBJECT;
goto err;
}
ret = c2i_ASN1_OBJECT(a, &p, len);
if (ret)
*pp = p;
return ret;
err:
OPENSSL_PUT_ERROR(ASN1, i);
return (NULL);
}
ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
long len)
{
ASN1_OBJECT *ret=NULL;
const unsigned char *p;
unsigned char *data;
int i, length;
long len)
{
ASN1_OBJECT *ret = NULL;
const unsigned char *p;
unsigned char *data;
int i, length;
/* Sanity check OID encoding.
* Need at least one content octet.
* MSB must be clear in the last octet.
* can't have leading 0x80 in subidentifiers, see: X.690 8.19.2
*/
if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
p[len - 1] & 0x80)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING);
return NULL;
}
/* Now 0 < len <= INT_MAX, so the cast is safe. */
length = (int)len;
for (i = 0; i < length; i++, p++)
{
if (*p == 0x80 && (!i || !(p[-1] & 0x80)))
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING);
return NULL;
}
}
/*
* Sanity check OID encoding. Need at least one content octet. MSB must
* be clear in the last octet. can't have leading 0x80 in subidentifiers,
* see: X.690 8.19.2
*/
if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
p[len - 1] & 0x80) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING);
return NULL;
}
/* Now 0 < len <= INT_MAX, so the cast is safe. */
length = (int)len;
for (i = 0; i < length; i++, p++) {
if (*p == 0x80 && (!i || !(p[-1] & 0x80))) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING);
return NULL;
}
}
/* only the ASN1_OBJECTs from the 'table' will have values
* for ->sn or ->ln */
if ((a == NULL) || ((*a) == NULL) ||
!((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC))
{
if ((ret=ASN1_OBJECT_new()) == NULL) return(NULL);
}
else ret=(*a);
/*
* only the ASN1_OBJECTs from the 'table' will have values for ->sn or
* ->ln
*/
if ((a == NULL) || ((*a) == NULL) ||
!((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) {
if ((ret = ASN1_OBJECT_new()) == NULL)
return (NULL);
} else
ret = (*a);
p= *pp;
/* detach data from object */
data = (unsigned char *)ret->data;
ret->data = NULL;
/* once detached we can change it */
if ((data == NULL) || (ret->length < length))
{
ret->length=0;
if (data != NULL) OPENSSL_free(data);
data=(unsigned char *)OPENSSL_malloc(length);
if (data == NULL)
{ i=ERR_R_MALLOC_FAILURE; goto err; }
ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA;
}
memcpy(data,p,length);
/* reattach data to object, after which it remains const */
ret->data =data;
ret->length=length;
ret->sn=NULL;
ret->ln=NULL;
/* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
p+=length;
p = *pp;
/* detach data from object */
data = (unsigned char *)ret->data;
ret->data = NULL;
/* once detached we can change it */
if ((data == NULL) || (ret->length < length)) {
ret->length = 0;
if (data != NULL)
OPENSSL_free(data);
data = (unsigned char *)OPENSSL_malloc(length);
if (data == NULL) {
i = ERR_R_MALLOC_FAILURE;
goto err;
}
ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA;
}
memcpy(data, p, length);
/* reattach data to object, after which it remains const */
ret->data = data;
ret->length = length;
ret->sn = NULL;
ret->ln = NULL;
/* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
p += length;
if (a != NULL) (*a)=ret;
*pp=p;
return(ret);
err:
OPENSSL_PUT_ERROR(ASN1, i);
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
ASN1_OBJECT_free(ret);
return(NULL);
}
if (a != NULL)
(*a) = ret;
*pp = p;
return (ret);
err:
OPENSSL_PUT_ERROR(ASN1, i);
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
ASN1_OBJECT_free(ret);
return (NULL);
}
ASN1_OBJECT *ASN1_OBJECT_new(void)
{
ASN1_OBJECT *ret;
{
ASN1_OBJECT *ret;
ret=(ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT));
if (ret == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return(NULL);
}
ret->length=0;
ret->data=NULL;
ret->nid=0;
ret->sn=NULL;
ret->ln=NULL;
ret->flags=ASN1_OBJECT_FLAG_DYNAMIC;
return(ret);
}
ret = (ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT));
if (ret == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return (NULL);
}
ret->length = 0;
ret->data = NULL;
ret->nid = 0;
ret->sn = NULL;
ret->ln = NULL;
ret->flags = ASN1_OBJECT_FLAG_DYNAMIC;
return (ret);
}
void ASN1_OBJECT_free(ASN1_OBJECT *a)
{
if (a == NULL) return;
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS)
{
#ifndef CONST_STRICT /* disable purely for compile-time strict const checking. Doing this on a "real" compile will cause memory leaks */
if (a->sn != NULL) OPENSSL_free((void *)a->sn);
if (a->ln != NULL) OPENSSL_free((void *)a->ln);
{
if (a == NULL)
return;
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) {
#ifndef CONST_STRICT /* disable purely for compile-time strict
* const checking. Doing this on a "real"
* compile will cause memory leaks */
if (a->sn != NULL)
OPENSSL_free((void *)a->sn);
if (a->ln != NULL)
OPENSSL_free((void *)a->ln);
#endif
a->sn=a->ln=NULL;
}
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA)
{
if (a->data != NULL) OPENSSL_free((void *)a->data);
a->data=NULL;
a->length=0;
}
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
OPENSSL_free(a);
}
a->sn = a->ln = NULL;
}
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) {
if (a->data != NULL)
OPENSSL_free((void *)a->data);
a->data = NULL;
a->length = 0;
}
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
OPENSSL_free(a);
}
ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len,
const char *sn, const char *ln)
{
ASN1_OBJECT o;
const char *sn, const char *ln)
{
ASN1_OBJECT o;
o.sn=sn;
o.ln=ln;
o.data=data;
o.nid=nid;
o.length=len;
o.flags=ASN1_OBJECT_FLAG_DYNAMIC|ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|
ASN1_OBJECT_FLAG_DYNAMIC_DATA;
return(OBJ_dup(&o));
}
o.sn = sn;
o.ln = ln;
o.data = data;
o.nid = nid;
o.length = len;
o.flags = ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
ASN1_OBJECT_FLAG_DYNAMIC_DATA;
return (OBJ_dup(&o));
}
+13 -6
View File
@@ -59,12 +59,19 @@
#include <openssl/err.h>
#include <openssl/mem.h>
ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *x)
{ return M_ASN1_OCTET_STRING_dup(x); }
{
return M_ASN1_OCTET_STRING_dup(x);
}
int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, const ASN1_OCTET_STRING *b)
{ return M_ASN1_OCTET_STRING_cmp(a, b); }
int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a,
const ASN1_OCTET_STRING *b)
{
return M_ASN1_OCTET_STRING_cmp(a, b);
}
int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d, int len)
{ return M_ASN1_OCTET_STRING_set(x, d, len); }
int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d,
int len)
{
return M_ASN1_OCTET_STRING_set(x, d, len);
}
+54 -52
View File
@@ -59,61 +59,63 @@
#include <openssl/err.h>
#include <openssl/mem.h>
int ASN1_PRINTABLE_type(const unsigned char *s, int len)
{
int c;
int ia5=0;
int t61=0;
{
int c;
int ia5 = 0;
int t61 = 0;
if (len <= 0) len= -1;
if (s == NULL) return(V_ASN1_PRINTABLESTRING);
if (len <= 0)
len = -1;
if (s == NULL)
return (V_ASN1_PRINTABLESTRING);
while ((*s) && (len-- != 0))
{
c= *(s++);
if (!( ((c >= 'a') && (c <= 'z')) ||
((c >= 'A') && (c <= 'Z')) ||
(c == ' ') ||
((c >= '0') && (c <= '9')) ||
(c == ' ') || (c == '\'') ||
(c == '(') || (c == ')') ||
(c == '+') || (c == ',') ||
(c == '-') || (c == '.') ||
(c == '/') || (c == ':') ||
(c == '=') || (c == '?')))
ia5=1;
if (c&0x80)
t61=1;
}
if (t61) return(V_ASN1_T61STRING);
if (ia5) return(V_ASN1_IA5STRING);
return(V_ASN1_PRINTABLESTRING);
}
while ((*s) && (len-- != 0)) {
c = *(s++);
if (!(((c >= 'a') && (c <= 'z')) ||
((c >= 'A') && (c <= 'Z')) ||
(c == ' ') ||
((c >= '0') && (c <= '9')) ||
(c == ' ') || (c == '\'') ||
(c == '(') || (c == ')') ||
(c == '+') || (c == ',') ||
(c == '-') || (c == '.') ||
(c == '/') || (c == ':') || (c == '=') || (c == '?')))
ia5 = 1;
if (c & 0x80)
t61 = 1;
}
if (t61)
return (V_ASN1_T61STRING);
if (ia5)
return (V_ASN1_IA5STRING);
return (V_ASN1_PRINTABLESTRING);
}
int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s)
{
int i;
unsigned char *p;
{
int i;
unsigned char *p;
if (s->type != V_ASN1_UNIVERSALSTRING) return(0);
if ((s->length%4) != 0) return(0);
p=s->data;
for (i=0; i<s->length; i+=4)
{
if ((p[0] != '\0') || (p[1] != '\0') || (p[2] != '\0'))
break;
else
p+=4;
}
if (i < s->length) return(0);
p=s->data;
for (i=3; i<s->length; i+=4)
{
*(p++)=s->data[i];
}
*(p)='\0';
s->length/=4;
s->type=ASN1_PRINTABLE_type(s->data,s->length);
return(1);
}
if (s->type != V_ASN1_UNIVERSALSTRING)
return (0);
if ((s->length % 4) != 0)
return (0);
p = s->data;
for (i = 0; i < s->length; i += 4) {
if ((p[0] != '\0') || (p[1] != '\0') || (p[2] != '\0'))
break;
else
p += 4;
}
if (i < s->length)
return (0);
p = s->data;
for (i = 3; i < s->length; i += 4) {
*(p++) = s->data[i];
}
*(p) = '\0';
s->length /= 4;
s->type = ASN1_PRINTABLE_type(s->data, s->length);
return (1);
}
+174 -152
View File
@@ -56,231 +56,253 @@
#include <openssl/asn1.h>
#include <stdlib.h> /* For bsearch */
#include <stdlib.h> /* For bsearch */
#include <string.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
static STACK_OF(ASN1_STRING_TABLE) *stable = NULL;
static void st_free(ASN1_STRING_TABLE *tbl);
/* This is the global mask for the mbstring functions: this is use to
* mask out certain types (such as BMPString and UTF8String) because
* certain software (e.g. Netscape) has problems with them.
/*
* This is the global mask for the mbstring functions: this is use to mask
* out certain types (such as BMPString and UTF8String) because certain
* software (e.g. Netscape) has problems with them.
*/
static unsigned long global_mask = B_ASN1_UTF8STRING;
void ASN1_STRING_set_default_mask(unsigned long mask)
{
global_mask = mask;
global_mask = mask;
}
unsigned long ASN1_STRING_get_default_mask(void)
{
return global_mask;
return global_mask;
}
/* This function sets the default to various "flavours" of configuration.
* based on an ASCII string. Currently this is:
* MASK:XXXX : a numerical mask value.
* nobmp : Don't use BMPStrings (just Printable, T61).
* pkix : PKIX recommendation in RFC2459.
* utf8only : only use UTF8Strings (RFC2459 recommendation for 2004).
* default: the default value, Printable, T61, BMP.
/*
* This function sets the default to various "flavours" of configuration.
* based on an ASCII string. Currently this is: MASK:XXXX : a numerical mask
* value. nobmp : Don't use BMPStrings (just Printable, T61). pkix : PKIX
* recommendation in RFC2459. utf8only : only use UTF8Strings (RFC2459
* recommendation for 2004). default: the default value, Printable, T61, BMP.
*/
int ASN1_STRING_set_default_mask_asc(const char *p)
{
unsigned long mask;
char *end;
if(!strncmp(p, "MASK:", 5)) {
if(!p[5]) return 0;
mask = strtoul(p + 5, &end, 0);
if(*end) return 0;
} else if(!strcmp(p, "nombstr"))
mask = ~((unsigned long)(B_ASN1_BMPSTRING|B_ASN1_UTF8STRING));
else if(!strcmp(p, "pkix"))
mask = ~((unsigned long)B_ASN1_T61STRING);
else if(!strcmp(p, "utf8only")) mask = B_ASN1_UTF8STRING;
else if(!strcmp(p, "default"))
mask = 0xFFFFFFFFL;
else return 0;
ASN1_STRING_set_default_mask(mask);
return 1;
unsigned long mask;
char *end;
if (!strncmp(p, "MASK:", 5)) {
if (!p[5])
return 0;
mask = strtoul(p + 5, &end, 0);
if (*end)
return 0;
} else if (!strcmp(p, "nombstr"))
mask = ~((unsigned long)(B_ASN1_BMPSTRING | B_ASN1_UTF8STRING));
else if (!strcmp(p, "pkix"))
mask = ~((unsigned long)B_ASN1_T61STRING);
else if (!strcmp(p, "utf8only"))
mask = B_ASN1_UTF8STRING;
else if (!strcmp(p, "default"))
mask = 0xFFFFFFFFL;
else
return 0;
ASN1_STRING_set_default_mask(mask);
return 1;
}
/* The following function generates an ASN1_STRING based on limits in a table.
* Frequently the types and length of an ASN1_STRING are restricted by a
* corresponding OID. For example certificates and certificate requests.
/*
* The following function generates an ASN1_STRING based on limits in a
* table. Frequently the types and length of an ASN1_STRING are restricted by
* a corresponding OID. For example certificates and certificate requests.
*/
ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in,
int inlen, int inform, int nid)
ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out,
const unsigned char *in, int inlen,
int inform, int nid)
{
ASN1_STRING_TABLE *tbl;
ASN1_STRING *str = NULL;
unsigned long mask;
int ret;
if(!out) out = &str;
tbl = ASN1_STRING_TABLE_get(nid);
if(tbl) {
mask = tbl->mask;
if(!(tbl->flags & STABLE_NO_MASK)) mask &= global_mask;
ret = ASN1_mbstring_ncopy(out, in, inlen, inform, mask,
tbl->minsize, tbl->maxsize);
} else ret = ASN1_mbstring_copy(out, in, inlen, inform, DIRSTRING_TYPE & global_mask);
if(ret <= 0) return NULL;
return *out;
ASN1_STRING_TABLE *tbl;
ASN1_STRING *str = NULL;
unsigned long mask;
int ret;
if (!out)
out = &str;
tbl = ASN1_STRING_TABLE_get(nid);
if (tbl) {
mask = tbl->mask;
if (!(tbl->flags & STABLE_NO_MASK))
mask &= global_mask;
ret = ASN1_mbstring_ncopy(out, in, inlen, inform, mask,
tbl->minsize, tbl->maxsize);
} else
ret =
ASN1_mbstring_copy(out, in, inlen, inform,
DIRSTRING_TYPE & global_mask);
if (ret <= 0)
return NULL;
return *out;
}
/* Now the tables and helper functions for the string table:
/*
* Now the tables and helper functions for the string table:
*/
/* size limits: this stuff is taken straight from RFC3280 */
#define ub_name 32768
#define ub_common_name 64
#define ub_locality_name 128
#define ub_state_name 128
#define ub_organization_name 64
#define ub_organization_unit_name 64
#define ub_title 64
#define ub_email_address 128
#define ub_serial_number 64
#define ub_name 32768
#define ub_common_name 64
#define ub_locality_name 128
#define ub_state_name 128
#define ub_organization_name 64
#define ub_organization_unit_name 64
#define ub_title 64
#define ub_email_address 128
#define ub_serial_number 64
/* This table must be kept in NID order */
static const ASN1_STRING_TABLE tbl_standard[] = {
{NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0},
{NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
{NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0},
{NID_stateOrProvinceName, 1, ub_state_name, DIRSTRING_TYPE, 0},
{NID_organizationName, 1, ub_organization_name, DIRSTRING_TYPE, 0},
{NID_organizationalUnitName, 1, ub_organization_unit_name, DIRSTRING_TYPE, 0},
{NID_pkcs9_emailAddress, 1, ub_email_address, B_ASN1_IA5STRING, STABLE_NO_MASK},
{NID_pkcs9_unstructuredName, 1, -1, PKCS9STRING_TYPE, 0},
{NID_pkcs9_challengePassword, 1, -1, PKCS9STRING_TYPE, 0},
{NID_pkcs9_unstructuredAddress, 1, -1, DIRSTRING_TYPE, 0},
{NID_givenName, 1, ub_name, DIRSTRING_TYPE, 0},
{NID_surname, 1, ub_name, DIRSTRING_TYPE, 0},
{NID_initials, 1, ub_name, DIRSTRING_TYPE, 0},
{NID_serialNumber, 1, ub_serial_number, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
{NID_friendlyName, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK},
{NID_name, 1, ub_name, DIRSTRING_TYPE, 0},
{NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
{NID_domainComponent, 1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK},
{NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK}
{NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0},
{NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
{NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0},
{NID_stateOrProvinceName, 1, ub_state_name, DIRSTRING_TYPE, 0},
{NID_organizationName, 1, ub_organization_name, DIRSTRING_TYPE, 0},
{NID_organizationalUnitName, 1, ub_organization_unit_name, DIRSTRING_TYPE,
0},
{NID_pkcs9_emailAddress, 1, ub_email_address, B_ASN1_IA5STRING,
STABLE_NO_MASK},
{NID_pkcs9_unstructuredName, 1, -1, PKCS9STRING_TYPE, 0},
{NID_pkcs9_challengePassword, 1, -1, PKCS9STRING_TYPE, 0},
{NID_pkcs9_unstructuredAddress, 1, -1, DIRSTRING_TYPE, 0},
{NID_givenName, 1, ub_name, DIRSTRING_TYPE, 0},
{NID_surname, 1, ub_name, DIRSTRING_TYPE, 0},
{NID_initials, 1, ub_name, DIRSTRING_TYPE, 0},
{NID_serialNumber, 1, ub_serial_number, B_ASN1_PRINTABLESTRING,
STABLE_NO_MASK},
{NID_friendlyName, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK},
{NID_name, 1, ub_name, DIRSTRING_TYPE, 0},
{NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
{NID_domainComponent, 1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK},
{NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK}
};
static int sk_table_cmp(const ASN1_STRING_TABLE **a,
const ASN1_STRING_TABLE **b)
const ASN1_STRING_TABLE **b)
{
return (*a)->nid - (*b)->nid;
return (*a)->nid - (*b)->nid;
}
static int table_cmp(const void *in_a, const void *in_b)
{
const ASN1_STRING_TABLE *a = in_a;
const ASN1_STRING_TABLE *b = in_b;
return a->nid - b->nid;
const ASN1_STRING_TABLE *a = in_a;
const ASN1_STRING_TABLE *b = in_b;
return a->nid - b->nid;
}
ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid)
{
int found;
size_t idx;
ASN1_STRING_TABLE *ttmp;
ASN1_STRING_TABLE fnd;
fnd.nid = nid;
int found;
size_t idx;
ASN1_STRING_TABLE *ttmp;
ASN1_STRING_TABLE fnd;
fnd.nid = nid;
ttmp = bsearch(&fnd, tbl_standard, sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE), sizeof(ASN1_STRING_TABLE), table_cmp);
if(ttmp) return ttmp;
if(!stable) return NULL;
found = sk_ASN1_STRING_TABLE_find(stable, &idx, &fnd);
if (!found) return NULL;
return sk_ASN1_STRING_TABLE_value(stable, idx);
ttmp =
bsearch(&fnd, tbl_standard,
sizeof(tbl_standard) / sizeof(ASN1_STRING_TABLE),
sizeof(ASN1_STRING_TABLE), table_cmp);
if (ttmp)
return ttmp;
if (!stable)
return NULL;
found = sk_ASN1_STRING_TABLE_find(stable, &idx, &fnd);
if (!found)
return NULL;
return sk_ASN1_STRING_TABLE_value(stable, idx);
}
int ASN1_STRING_TABLE_add(int nid,
long minsize, long maxsize, unsigned long mask,
unsigned long flags)
long minsize, long maxsize, unsigned long mask,
unsigned long flags)
{
ASN1_STRING_TABLE *tmp;
char new_nid = 0;
flags &= ~STABLE_FLAGS_MALLOC;
if(!stable) stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
if(!stable) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return 0;
}
if(!(tmp = ASN1_STRING_TABLE_get(nid))) {
tmp = OPENSSL_malloc(sizeof(ASN1_STRING_TABLE));
if(!tmp) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return 0;
}
tmp->flags = flags | STABLE_FLAGS_MALLOC;
tmp->nid = nid;
new_nid = 1;
} else tmp->flags = (tmp->flags & STABLE_FLAGS_MALLOC) | flags;
if(minsize != -1) tmp->minsize = minsize;
if(maxsize != -1) tmp->maxsize = maxsize;
tmp->mask = mask;
if(new_nid) sk_ASN1_STRING_TABLE_push(stable, tmp);
return 1;
ASN1_STRING_TABLE *tmp;
char new_nid = 0;
flags &= ~STABLE_FLAGS_MALLOC;
if (!stable)
stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
if (!stable) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return 0;
}
if (!(tmp = ASN1_STRING_TABLE_get(nid))) {
tmp = OPENSSL_malloc(sizeof(ASN1_STRING_TABLE));
if (!tmp) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return 0;
}
tmp->flags = flags | STABLE_FLAGS_MALLOC;
tmp->nid = nid;
new_nid = 1;
} else
tmp->flags = (tmp->flags & STABLE_FLAGS_MALLOC) | flags;
if (minsize != -1)
tmp->minsize = minsize;
if (maxsize != -1)
tmp->maxsize = maxsize;
tmp->mask = mask;
if (new_nid)
sk_ASN1_STRING_TABLE_push(stable, tmp);
return 1;
}
void ASN1_STRING_TABLE_cleanup(void)
{
STACK_OF(ASN1_STRING_TABLE) *tmp;
tmp = stable;
if(!tmp) return;
stable = NULL;
sk_ASN1_STRING_TABLE_pop_free(tmp, st_free);
STACK_OF(ASN1_STRING_TABLE) *tmp;
tmp = stable;
if (!tmp)
return;
stable = NULL;
sk_ASN1_STRING_TABLE_pop_free(tmp, st_free);
}
static void st_free(ASN1_STRING_TABLE *tbl)
{
if(tbl->flags & STABLE_FLAGS_MALLOC) OPENSSL_free(tbl);
if (tbl->flags & STABLE_FLAGS_MALLOC)
OPENSSL_free(tbl);
}
#ifdef STRING_TABLE_TEST
int
main(void)
int main(void)
{
ASN1_STRING_TABLE *tmp;
int i, last_nid = -1;
ASN1_STRING_TABLE *tmp;
int i, last_nid = -1;
for (tmp = tbl_standard, i = 0;
i < sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE); i++, tmp++)
{
if (tmp->nid < last_nid)
{
last_nid = 0;
break;
}
last_nid = tmp->nid;
}
for (tmp = tbl_standard, i = 0;
i < sizeof(tbl_standard) / sizeof(ASN1_STRING_TABLE); i++, tmp++) {
if (tmp->nid < last_nid) {
last_nid = 0;
break;
}
last_nid = tmp->nid;
}
if (last_nid != 0)
{
printf("Table order OK\n");
exit(0);
}
if (last_nid != 0) {
printf("Table order OK\n");
exit(0);
}
for (tmp = tbl_standard, i = 0;
i < sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE); i++, tmp++)
printf("Index %d, NID %d, Name=%s\n", i, tmp->nid,
OBJ_nid2ln(tmp->nid));
for (tmp = tbl_standard, i = 0;
i < sizeof(tbl_standard) / sizeof(ASN1_STRING_TABLE); i++, tmp++)
printf("Index %d, NID %d, Name=%s\n", i, tmp->nid,
OBJ_nid2ln(tmp->nid));
return 0;
return 0;
}
#endif
+114 -118
View File
@@ -67,12 +67,10 @@
#include "asn1_locl.h"
/* This is an implementation of the ASN1 Time structure which is:
* Time ::= CHOICE {
* utcTime UTCTime,
* generalTime GeneralizedTime }
* written by Steve Henson.
/*
* This is an implementation of the ASN1 Time structure which is: Time ::=
* CHOICE { utcTime UTCTime, generalTime GeneralizedTime } written by Steve
* Henson.
*/
IMPLEMENT_ASN1_MSTRING(ASN1_TIME, B_ASN1_TIME)
@@ -81,141 +79,139 @@ IMPLEMENT_ASN1_FUNCTIONS(ASN1_TIME)
#if 0
int i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **pp)
{
if(a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME)
return(i2d_ASN1_bytes((ASN1_STRING *)a,pp,
a->type ,V_ASN1_UNIVERSAL));
OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPECTING_A_TIME);
return -1;
}
{
if (a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME)
return (i2d_ASN1_bytes((ASN1_STRING *)a, pp,
a->type, V_ASN1_UNIVERSAL));
OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPECTING_A_TIME);
return -1;
}
#endif
ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t)
{
return ASN1_TIME_adj(s, t, 0, 0);
}
{
return ASN1_TIME_adj(s, t, 0, 0);
}
ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t,
int offset_day, long offset_sec)
{
struct tm *ts;
struct tm data;
int offset_day, long offset_sec)
{
struct tm *ts;
struct tm data;
ts=OPENSSL_gmtime(&t,&data);
if (ts == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_ERROR_GETTING_TIME);
return NULL;
}
if (offset_day || offset_sec)
{
if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
return NULL;
}
if((ts->tm_year >= 50) && (ts->tm_year < 150))
return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec);
return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
}
ts = OPENSSL_gmtime(&t, &data);
if (ts == NULL) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_ERROR_GETTING_TIME);
return NULL;
}
if (offset_day || offset_sec) {
if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
return NULL;
}
if ((ts->tm_year >= 50) && (ts->tm_year < 150))
return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec);
return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
}
int ASN1_TIME_check(ASN1_TIME *t)
{
if (t->type == V_ASN1_GENERALIZEDTIME)
return ASN1_GENERALIZEDTIME_check(t);
else if (t->type == V_ASN1_UTCTIME)
return ASN1_UTCTIME_check(t);
return 0;
}
{
if (t->type == V_ASN1_GENERALIZEDTIME)
return ASN1_GENERALIZEDTIME_check(t);
else if (t->type == V_ASN1_UTCTIME)
return ASN1_UTCTIME_check(t);
return 0;
}
/* Convert an ASN1_TIME structure to GeneralizedTime */
ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out)
{
ASN1_GENERALIZEDTIME *ret;
char *str;
int newlen;
ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t,
ASN1_GENERALIZEDTIME **out)
{
ASN1_GENERALIZEDTIME *ret;
char *str;
int newlen;
if (!ASN1_TIME_check(t)) return NULL;
if (!ASN1_TIME_check(t))
return NULL;
if (!out || !*out)
{
if (!(ret = ASN1_GENERALIZEDTIME_new ()))
return NULL;
if (out) *out = ret;
}
else ret = *out;
if (!out || !*out) {
if (!(ret = ASN1_GENERALIZEDTIME_new()))
return NULL;
if (out)
*out = ret;
} else
ret = *out;
/* If already GeneralizedTime just copy across */
if (t->type == V_ASN1_GENERALIZEDTIME)
{
if(!ASN1_STRING_set(ret, t->data, t->length))
return NULL;
return ret;
}
/* If already GeneralizedTime just copy across */
if (t->type == V_ASN1_GENERALIZEDTIME) {
if (!ASN1_STRING_set(ret, t->data, t->length))
return NULL;
return ret;
}
/* grow the string */
if (!ASN1_STRING_set(ret, NULL, t->length + 2))
return NULL;
/* ASN1_STRING_set() allocated 'len + 1' bytes. */
newlen = t->length + 2 + 1;
str = (char *)ret->data;
/* Work out the century and prepend */
if (t->data[0] >= '5') BUF_strlcpy(str, "19", newlen);
else BUF_strlcpy(str, "20", newlen);
/* grow the string */
if (!ASN1_STRING_set(ret, NULL, t->length + 2))
return NULL;
/* ASN1_STRING_set() allocated 'len + 1' bytes. */
newlen = t->length + 2 + 1;
str = (char *)ret->data;
/* Work out the century and prepend */
if (t->data[0] >= '5')
BUF_strlcpy(str, "19", newlen);
else
BUF_strlcpy(str, "20", newlen);
BUF_strlcat(str, (char *)t->data, newlen);
BUF_strlcat(str, (char *)t->data, newlen);
return ret;
}
return ret;
}
int ASN1_TIME_set_string(ASN1_TIME *s, const char *str)
{
ASN1_TIME t;
{
ASN1_TIME t;
t.length = strlen(str);
t.data = (unsigned char *)str;
t.flags = 0;
t.type = V_ASN1_UTCTIME;
t.length = strlen(str);
t.data = (unsigned char *)str;
t.flags = 0;
if (!ASN1_TIME_check(&t))
{
t.type = V_ASN1_GENERALIZEDTIME;
if (!ASN1_TIME_check(&t))
return 0;
}
if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t))
return 0;
t.type = V_ASN1_UTCTIME;
return 1;
}
if (!ASN1_TIME_check(&t)) {
t.type = V_ASN1_GENERALIZEDTIME;
if (!ASN1_TIME_check(&t))
return 0;
}
if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t))
return 0;
return 1;
}
static int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *t)
{
if (t == NULL)
{
time_t now_t;
time(&now_t);
if (OPENSSL_gmtime(&now_t, tm))
return 1;
return 0;
}
if (t->type == V_ASN1_UTCTIME)
return asn1_utctime_to_tm(tm, t);
else if (t->type == V_ASN1_GENERALIZEDTIME)
return asn1_generalizedtime_to_tm(tm, t);
{
if (t == NULL) {
time_t now_t;
time(&now_t);
if (OPENSSL_gmtime(&now_t, tm))
return 1;
return 0;
}
return 0;
}
if (t->type == V_ASN1_UTCTIME)
return asn1_utctime_to_tm(tm, t);
else if (t->type == V_ASN1_GENERALIZEDTIME)
return asn1_generalizedtime_to_tm(tm, t);
return 0;
}
int ASN1_TIME_diff(int *pday, int *psec,
const ASN1_TIME *from, const ASN1_TIME *to)
{
struct tm tm_from, tm_to;
if (!asn1_time_to_tm(&tm_from, from))
return 0;
if (!asn1_time_to_tm(&tm_to, to))
return 0;
return OPENSSL_gmtime_diff(pday, psec, &tm_from, &tm_to);
}
const ASN1_TIME *from, const ASN1_TIME *to)
{
struct tm tm_from, tm_to;
if (!asn1_time_to_tm(&tm_from, from))
return 0;
if (!asn1_time_to_tm(&tm_to, to))
return 0;
return OPENSSL_gmtime_diff(pday, psec, &tm_from, &tm_to);
}
+79 -86
View File
@@ -61,100 +61,93 @@
#include <openssl/mem.h>
#include <openssl/obj.h>
int ASN1_TYPE_get(ASN1_TYPE *a)
{
if ((a->value.ptr != NULL) || (a->type == V_ASN1_NULL))
return(a->type);
else
return(0);
}
{
if ((a->value.ptr != NULL) || (a->type == V_ASN1_NULL))
return (a->type);
else
return (0);
}
void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value)
{
if (a->value.ptr != NULL)
{
ASN1_TYPE **tmp_a = &a;
ASN1_primitive_free((ASN1_VALUE **)tmp_a, NULL);
}
a->type=type;
if (type == V_ASN1_BOOLEAN)
a->value.boolean = value ? 0xff : 0;
else
a->value.ptr=value;
}
{
if (a->value.ptr != NULL) {
ASN1_TYPE **tmp_a = &a;
ASN1_primitive_free((ASN1_VALUE **)tmp_a, NULL);
}
a->type = type;
if (type == V_ASN1_BOOLEAN)
a->value.boolean = value ? 0xff : 0;
else
a->value.ptr = value;
}
int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value)
{
if (!value || (type == V_ASN1_BOOLEAN))
{
void *p = (void *)value;
ASN1_TYPE_set(a, type, p);
}
else if (type == V_ASN1_OBJECT)
{
ASN1_OBJECT *odup;
odup = OBJ_dup(value);
if (!odup)
return 0;
ASN1_TYPE_set(a, type, odup);
}
else
{
ASN1_STRING *sdup;
sdup = ASN1_STRING_dup(value);
if (!sdup)
return 0;
ASN1_TYPE_set(a, type, sdup);
}
return 1;
}
{
if (!value || (type == V_ASN1_BOOLEAN)) {
void *p = (void *)value;
ASN1_TYPE_set(a, type, p);
} else if (type == V_ASN1_OBJECT) {
ASN1_OBJECT *odup;
odup = OBJ_dup(value);
if (!odup)
return 0;
ASN1_TYPE_set(a, type, odup);
} else {
ASN1_STRING *sdup;
sdup = ASN1_STRING_dup(value);
if (!sdup)
return 0;
ASN1_TYPE_set(a, type, sdup);
}
return 1;
}
/* Returns 0 if they are equal, != 0 otherwise. */
int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
{
int result = -1;
{
int result = -1;
if (!a || !b || a->type != b->type) return -1;
if (!a || !b || a->type != b->type)
return -1;
switch (a->type)
{
case V_ASN1_OBJECT:
result = OBJ_cmp(a->value.object, b->value.object);
break;
case V_ASN1_NULL:
result = 0; /* They do not have content. */
break;
case V_ASN1_BOOLEAN:
result = a->value.boolean - b->value.boolean;
break;
case V_ASN1_INTEGER:
case V_ASN1_NEG_INTEGER:
case V_ASN1_ENUMERATED:
case V_ASN1_NEG_ENUMERATED:
case V_ASN1_BIT_STRING:
case V_ASN1_OCTET_STRING:
case V_ASN1_SEQUENCE:
case V_ASN1_SET:
case V_ASN1_NUMERICSTRING:
case V_ASN1_PRINTABLESTRING:
case V_ASN1_T61STRING:
case V_ASN1_VIDEOTEXSTRING:
case V_ASN1_IA5STRING:
case V_ASN1_UTCTIME:
case V_ASN1_GENERALIZEDTIME:
case V_ASN1_GRAPHICSTRING:
case V_ASN1_VISIBLESTRING:
case V_ASN1_GENERALSTRING:
case V_ASN1_UNIVERSALSTRING:
case V_ASN1_BMPSTRING:
case V_ASN1_UTF8STRING:
case V_ASN1_OTHER:
default:
result = ASN1_STRING_cmp((ASN1_STRING *) a->value.ptr,
(ASN1_STRING *) b->value.ptr);
break;
}
switch (a->type) {
case V_ASN1_OBJECT:
result = OBJ_cmp(a->value.object, b->value.object);
break;
case V_ASN1_NULL:
result = 0; /* They do not have content. */
break;
case V_ASN1_BOOLEAN:
result = a->value.boolean - b->value.boolean;
break;
case V_ASN1_INTEGER:
case V_ASN1_NEG_INTEGER:
case V_ASN1_ENUMERATED:
case V_ASN1_NEG_ENUMERATED:
case V_ASN1_BIT_STRING:
case V_ASN1_OCTET_STRING:
case V_ASN1_SEQUENCE:
case V_ASN1_SET:
case V_ASN1_NUMERICSTRING:
case V_ASN1_PRINTABLESTRING:
case V_ASN1_T61STRING:
case V_ASN1_VIDEOTEXSTRING:
case V_ASN1_IA5STRING:
case V_ASN1_UTCTIME:
case V_ASN1_GENERALIZEDTIME:
case V_ASN1_GRAPHICSTRING:
case V_ASN1_VISIBLESTRING:
case V_ASN1_GENERALSTRING:
case V_ASN1_UNIVERSALSTRING:
case V_ASN1_BMPSTRING:
case V_ASN1_UTF8STRING:
case V_ASN1_OTHER:
default:
result = ASN1_STRING_cmp((ASN1_STRING *)a->value.ptr,
(ASN1_STRING *)b->value.ptr);
break;
}
return result;
}
return result;
}
+227 -234
View File
@@ -63,280 +63,273 @@
#include <openssl/mem.h>
#include <openssl/time_support.h>
#include "asn1_locl.h"
#if 0
int i2d_ASN1_UTCTIME(ASN1_UTCTIME *a, unsigned char **pp)
{
return(i2d_ASN1_bytes((ASN1_STRING *)a,pp,
V_ASN1_UTCTIME,V_ASN1_UNIVERSAL));
}
{
return (i2d_ASN1_bytes((ASN1_STRING *)a, pp,
V_ASN1_UTCTIME, V_ASN1_UNIVERSAL));
}
ASN1_UTCTIME *d2i_ASN1_UTCTIME(ASN1_UTCTIME **a, unsigned char **pp,
long length)
{
ASN1_UTCTIME *ret=NULL;
long length)
{
ASN1_UTCTIME *ret = NULL;
ret=(ASN1_UTCTIME *)d2i_ASN1_bytes((ASN1_STRING **)a,pp,length,
V_ASN1_UTCTIME,V_ASN1_UNIVERSAL);
if (ret == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_NESTED_ASN1_ERROR);
return(NULL);
}
if (!ASN1_UTCTIME_check(ret))
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_TIME_FORMAT);
goto err;
}
ret = (ASN1_UTCTIME *)d2i_ASN1_bytes((ASN1_STRING **)a, pp, length,
V_ASN1_UTCTIME, V_ASN1_UNIVERSAL);
if (ret == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_NESTED_ASN1_ERROR);
return (NULL);
}
if (!ASN1_UTCTIME_check(ret)) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_TIME_FORMAT);
goto err;
}
return(ret);
err:
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
M_ASN1_UTCTIME_free(ret);
return(NULL);
}
return (ret);
err:
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
M_ASN1_UTCTIME_free(ret);
return (NULL);
}
#endif
int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d)
{
static const int min[8]={ 0, 1, 1, 0, 0, 0, 0, 0};
static const int max[8]={99,12,31,23,59,59,12,59};
char *a;
int n,i,l,o;
{
static const int min[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };
static const int max[8] = { 99, 12, 31, 23, 59, 59, 12, 59 };
char *a;
int n, i, l, o;
if (d->type != V_ASN1_UTCTIME) return(0);
l=d->length;
a=(char *)d->data;
o=0;
if (d->type != V_ASN1_UTCTIME)
return (0);
l = d->length;
a = (char *)d->data;
o = 0;
if (l < 11) goto err;
for (i=0; i<6; i++)
{
if ((i == 5) && ((a[o] == 'Z') ||
(a[o] == '+') || (a[o] == '-')))
{
i++;
if (tm)
tm->tm_sec = 0;
break;
}
if ((a[o] < '0') || (a[o] > '9')) goto err;
n= a[o]-'0';
if (++o > l) goto err;
if (l < 11)
goto err;
for (i = 0; i < 6; i++) {
if ((i == 5) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) {
i++;
if (tm)
tm->tm_sec = 0;
break;
}
if ((a[o] < '0') || (a[o] > '9'))
goto err;
n = a[o] - '0';
if (++o > l)
goto err;
if ((a[o] < '0') || (a[o] > '9')) goto err;
n=(n*10)+ a[o]-'0';
if (++o > l) goto err;
if ((a[o] < '0') || (a[o] > '9'))
goto err;
n = (n * 10) + a[o] - '0';
if (++o > l)
goto err;
if ((n < min[i]) || (n > max[i])) goto err;
if (tm)
{
switch(i)
{
case 0:
tm->tm_year = n < 50 ? n + 100 : n;
break;
case 1:
tm->tm_mon = n - 1;
break;
case 2:
tm->tm_mday = n;
break;
case 3:
tm->tm_hour = n;
break;
case 4:
tm->tm_min = n;
break;
case 5:
tm->tm_sec = n;
break;
}
}
}
if (a[o] == 'Z')
o++;
else if ((a[o] == '+') || (a[o] == '-'))
{
int offsign = a[o] == '-' ? -1 : 1, offset = 0;
o++;
if (o+4 > l) goto err;
for (i=6; i<8; i++)
{
if ((a[o] < '0') || (a[o] > '9')) goto err;
n= a[o]-'0';
o++;
if ((a[o] < '0') || (a[o] > '9')) goto err;
n=(n*10)+ a[o]-'0';
if ((n < min[i]) || (n > max[i])) goto err;
if (tm)
{
if (i == 6)
offset = n * 3600;
else if (i == 7)
offset += n * 60;
}
o++;
}
if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign))
return 0;
}
return o == l;
err:
return 0;
}
if ((n < min[i]) || (n > max[i]))
goto err;
if (tm) {
switch (i) {
case 0:
tm->tm_year = n < 50 ? n + 100 : n;
break;
case 1:
tm->tm_mon = n - 1;
break;
case 2:
tm->tm_mday = n;
break;
case 3:
tm->tm_hour = n;
break;
case 4:
tm->tm_min = n;
break;
case 5:
tm->tm_sec = n;
break;
}
}
}
if (a[o] == 'Z')
o++;
else if ((a[o] == '+') || (a[o] == '-')) {
int offsign = a[o] == '-' ? -1 : 1, offset = 0;
o++;
if (o + 4 > l)
goto err;
for (i = 6; i < 8; i++) {
if ((a[o] < '0') || (a[o] > '9'))
goto err;
n = a[o] - '0';
o++;
if ((a[o] < '0') || (a[o] > '9'))
goto err;
n = (n * 10) + a[o] - '0';
if ((n < min[i]) || (n > max[i]))
goto err;
if (tm) {
if (i == 6)
offset = n * 3600;
else if (i == 7)
offset += n * 60;
}
o++;
}
if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign))
return 0;
}
return o == l;
err:
return 0;
}
int ASN1_UTCTIME_check(const ASN1_UTCTIME *d)
{
return asn1_utctime_to_tm(NULL, d);
}
{
return asn1_utctime_to_tm(NULL, d);
}
int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str)
{
ASN1_UTCTIME t;
{
ASN1_UTCTIME t;
t.type=V_ASN1_UTCTIME;
t.length=strlen(str);
t.data=(unsigned char *)str;
if (ASN1_UTCTIME_check(&t))
{
if (s != NULL)
{
if (!ASN1_STRING_set((ASN1_STRING *)s,
(unsigned char *)str,t.length))
return 0;
s->type = V_ASN1_UTCTIME;
}
return(1);
}
else
return(0);
}
t.type = V_ASN1_UTCTIME;
t.length = strlen(str);
t.data = (unsigned char *)str;
if (ASN1_UTCTIME_check(&t)) {
if (s != NULL) {
if (!ASN1_STRING_set((ASN1_STRING *)s,
(unsigned char *)str, t.length))
return 0;
s->type = V_ASN1_UTCTIME;
}
return (1);
} else
return (0);
}
ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t)
{
return ASN1_UTCTIME_adj(s, t, 0, 0);
}
{
return ASN1_UTCTIME_adj(s, t, 0, 0);
}
ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
int offset_day, long offset_sec)
{
char *p;
struct tm *ts;
struct tm data;
size_t len = 20;
int free_s = 0;
int offset_day, long offset_sec)
{
char *p;
struct tm *ts;
struct tm data;
size_t len = 20;
int free_s = 0;
if (s == NULL)
{
free_s = 1;
s=M_ASN1_UTCTIME_new();
}
if (s == NULL)
goto err;
if (s == NULL) {
free_s = 1;
s = M_ASN1_UTCTIME_new();
}
if (s == NULL)
goto err;
ts = OPENSSL_gmtime(&t, &data);
if (ts == NULL)
goto err;
ts=OPENSSL_gmtime(&t, &data);
if (ts == NULL)
goto err;
if (offset_day || offset_sec) {
if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
goto err;
}
if (offset_day || offset_sec)
{
if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
goto err;
}
if ((ts->tm_year < 50) || (ts->tm_year >= 150))
goto err;
if((ts->tm_year < 50) || (ts->tm_year >= 150))
goto err;
p=(char *)s->data;
if ((p == NULL) || ((size_t)s->length < len))
{
p=OPENSSL_malloc(len);
if (p == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
if (s->data != NULL)
OPENSSL_free(s->data);
s->data=(unsigned char *)p;
}
BIO_snprintf(p,len,"%02d%02d%02d%02d%02d%02dZ",ts->tm_year%100,
ts->tm_mon+1,ts->tm_mday,ts->tm_hour,ts->tm_min,ts->tm_sec);
s->length=strlen(p);
s->type=V_ASN1_UTCTIME;
return(s);
err:
if (free_s && s)
M_ASN1_UTCTIME_free(s);
return NULL;
}
p = (char *)s->data;
if ((p == NULL) || ((size_t)s->length < len)) {
p = OPENSSL_malloc(len);
if (p == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
if (s->data != NULL)
OPENSSL_free(s->data);
s->data = (unsigned char *)p;
}
BIO_snprintf(p, len, "%02d%02d%02d%02d%02d%02dZ", ts->tm_year % 100,
ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min,
ts->tm_sec);
s->length = strlen(p);
s->type = V_ASN1_UTCTIME;
return (s);
err:
if (free_s && s)
M_ASN1_UTCTIME_free(s);
return NULL;
}
int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t)
{
struct tm stm, ttm;
int day, sec;
{
struct tm stm, ttm;
int day, sec;
if (!asn1_utctime_to_tm(&stm, s))
return -2;
if (!asn1_utctime_to_tm(&stm, s))
return -2;
if (!OPENSSL_gmtime(&t, &ttm))
return -2;
if (!OPENSSL_gmtime(&t, &ttm))
return -2;
if (!OPENSSL_gmtime_diff(&day, &sec, &ttm, &stm))
return -2;
if (day > 0)
return 1;
if (day < 0)
return -1;
if (sec > 0)
return 1;
if (sec < 0)
return -1;
return 0;
}
if (!OPENSSL_gmtime_diff(&day, &sec, &ttm, &stm))
return -2;
if (day > 0)
return 1;
if (day < 0)
return -1;
if (sec > 0)
return 1;
if (sec < 0)
return -1;
return 0;
}
#if 0
time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s)
{
struct tm tm;
int offset;
{
struct tm tm;
int offset;
memset(&tm,'\0',sizeof tm);
memset(&tm, '\0', sizeof tm);
#define g2(p) (((p)[0]-'0')*10+(p)[1]-'0')
tm.tm_year=g2(s->data);
if(tm.tm_year < 50)
tm.tm_year+=100;
tm.tm_mon=g2(s->data+2)-1;
tm.tm_mday=g2(s->data+4);
tm.tm_hour=g2(s->data+6);
tm.tm_min=g2(s->data+8);
tm.tm_sec=g2(s->data+10);
if(s->data[12] == 'Z')
offset=0;
else
{
offset=g2(s->data+13)*60+g2(s->data+15);
if(s->data[12] == '-')
offset= -offset;
}
#undef g2
# define g2(p) (((p)[0]-'0')*10+(p)[1]-'0')
tm.tm_year = g2(s->data);
if (tm.tm_year < 50)
tm.tm_year += 100;
tm.tm_mon = g2(s->data + 2) - 1;
tm.tm_mday = g2(s->data + 4);
tm.tm_hour = g2(s->data + 6);
tm.tm_min = g2(s->data + 8);
tm.tm_sec = g2(s->data + 10);
if (s->data[12] == 'Z')
offset = 0;
else {
offset = g2(s->data + 13) * 60 + g2(s->data + 15);
if (s->data[12] == '-')
offset = -offset;
}
# undef g2
return mktime(&tm)-offset*60; /* FIXME: mktime assumes the current timezone
* instead of UTC, and unless we rewrite OpenSSL
* in Lisp we cannot locally change the timezone
* without possibly interfering with other parts
* of the program. timegm, which uses UTC, is
* non-standard.
* Also time_t is inappropriate for general
* UTC times because it may a 32 bit type. */
}
return mktime(&tm) - offset * 60; /* FIXME: mktime assumes the current
* timezone instead of UTC, and unless
* we rewrite OpenSSL in Lisp we cannot
* locally change the timezone without
* possibly interfering with other
* parts of the program. timegm, which
* uses UTC, is non-standard. Also
* time_t is inappropriate for general
* UTC times because it may a 32 bit
* type. */
}
#endif
+159 -135
View File
@@ -59,152 +59,176 @@
#include <openssl/err.h>
#include <openssl/mem.h>
/* UTF8 utilities */
/* This parses a UTF8 string one character at a time. It is passed a pointer
* to the string and the length of the string. It sets 'value' to the value of
* the current character. It returns the number of characters read or a
* negative error code:
* -1 = string too short
* -2 = illegal character
* -3 = subsequent characters not of the form 10xxxxxx
* -4 = character encoded incorrectly (not minimal length).
/*
* This parses a UTF8 string one character at a time. It is passed a pointer
* to the string and the length of the string. It sets 'value' to the value
* of the current character. It returns the number of characters read or a
* negative error code: -1 = string too short -2 = illegal character -3 =
* subsequent characters not of the form 10xxxxxx -4 = character encoded
* incorrectly (not minimal length).
*/
int UTF8_getc(const unsigned char *str, int len, unsigned long *val)
{
const unsigned char *p;
unsigned long value;
int ret;
if(len <= 0) return 0;
p = str;
const unsigned char *p;
unsigned long value;
int ret;
if (len <= 0)
return 0;
p = str;
/* Check syntax and work out the encoded value (if correct) */
if((*p & 0x80) == 0) {
value = *p++ & 0x7f;
ret = 1;
} else if((*p & 0xe0) == 0xc0) {
if(len < 2) return -1;
if((p[1] & 0xc0) != 0x80) return -3;
value = (*p++ & 0x1f) << 6;
value |= *p++ & 0x3f;
if(value < 0x80) return -4;
ret = 2;
} else if((*p & 0xf0) == 0xe0) {
if(len < 3) return -1;
if( ((p[1] & 0xc0) != 0x80)
|| ((p[2] & 0xc0) != 0x80) ) return -3;
value = (*p++ & 0xf) << 12;
value |= (*p++ & 0x3f) << 6;
value |= *p++ & 0x3f;
if(value < 0x800) return -4;
ret = 3;
} else if((*p & 0xf8) == 0xf0) {
if(len < 4) return -1;
if( ((p[1] & 0xc0) != 0x80)
|| ((p[2] & 0xc0) != 0x80)
|| ((p[3] & 0xc0) != 0x80) ) return -3;
value = ((unsigned long)(*p++ & 0x7)) << 18;
value |= (*p++ & 0x3f) << 12;
value |= (*p++ & 0x3f) << 6;
value |= *p++ & 0x3f;
if(value < 0x10000) return -4;
ret = 4;
} else if((*p & 0xfc) == 0xf8) {
if(len < 5) return -1;
if( ((p[1] & 0xc0) != 0x80)
|| ((p[2] & 0xc0) != 0x80)
|| ((p[3] & 0xc0) != 0x80)
|| ((p[4] & 0xc0) != 0x80) ) return -3;
value = ((unsigned long)(*p++ & 0x3)) << 24;
value |= ((unsigned long)(*p++ & 0x3f)) << 18;
value |= ((unsigned long)(*p++ & 0x3f)) << 12;
value |= (*p++ & 0x3f) << 6;
value |= *p++ & 0x3f;
if(value < 0x200000) return -4;
ret = 5;
} else if((*p & 0xfe) == 0xfc) {
if(len < 6) return -1;
if( ((p[1] & 0xc0) != 0x80)
|| ((p[2] & 0xc0) != 0x80)
|| ((p[3] & 0xc0) != 0x80)
|| ((p[4] & 0xc0) != 0x80)
|| ((p[5] & 0xc0) != 0x80) ) return -3;
value = ((unsigned long)(*p++ & 0x1)) << 30;
value |= ((unsigned long)(*p++ & 0x3f)) << 24;
value |= ((unsigned long)(*p++ & 0x3f)) << 18;
value |= ((unsigned long)(*p++ & 0x3f)) << 12;
value |= (*p++ & 0x3f) << 6;
value |= *p++ & 0x3f;
if(value < 0x4000000) return -4;
ret = 6;
} else return -2;
*val = value;
return ret;
/* Check syntax and work out the encoded value (if correct) */
if ((*p & 0x80) == 0) {
value = *p++ & 0x7f;
ret = 1;
} else if ((*p & 0xe0) == 0xc0) {
if (len < 2)
return -1;
if ((p[1] & 0xc0) != 0x80)
return -3;
value = (*p++ & 0x1f) << 6;
value |= *p++ & 0x3f;
if (value < 0x80)
return -4;
ret = 2;
} else if ((*p & 0xf0) == 0xe0) {
if (len < 3)
return -1;
if (((p[1] & 0xc0) != 0x80)
|| ((p[2] & 0xc0) != 0x80))
return -3;
value = (*p++ & 0xf) << 12;
value |= (*p++ & 0x3f) << 6;
value |= *p++ & 0x3f;
if (value < 0x800)
return -4;
ret = 3;
} else if ((*p & 0xf8) == 0xf0) {
if (len < 4)
return -1;
if (((p[1] & 0xc0) != 0x80)
|| ((p[2] & 0xc0) != 0x80)
|| ((p[3] & 0xc0) != 0x80))
return -3;
value = ((unsigned long)(*p++ & 0x7)) << 18;
value |= (*p++ & 0x3f) << 12;
value |= (*p++ & 0x3f) << 6;
value |= *p++ & 0x3f;
if (value < 0x10000)
return -4;
ret = 4;
} else if ((*p & 0xfc) == 0xf8) {
if (len < 5)
return -1;
if (((p[1] & 0xc0) != 0x80)
|| ((p[2] & 0xc0) != 0x80)
|| ((p[3] & 0xc0) != 0x80)
|| ((p[4] & 0xc0) != 0x80))
return -3;
value = ((unsigned long)(*p++ & 0x3)) << 24;
value |= ((unsigned long)(*p++ & 0x3f)) << 18;
value |= ((unsigned long)(*p++ & 0x3f)) << 12;
value |= (*p++ & 0x3f) << 6;
value |= *p++ & 0x3f;
if (value < 0x200000)
return -4;
ret = 5;
} else if ((*p & 0xfe) == 0xfc) {
if (len < 6)
return -1;
if (((p[1] & 0xc0) != 0x80)
|| ((p[2] & 0xc0) != 0x80)
|| ((p[3] & 0xc0) != 0x80)
|| ((p[4] & 0xc0) != 0x80)
|| ((p[5] & 0xc0) != 0x80))
return -3;
value = ((unsigned long)(*p++ & 0x1)) << 30;
value |= ((unsigned long)(*p++ & 0x3f)) << 24;
value |= ((unsigned long)(*p++ & 0x3f)) << 18;
value |= ((unsigned long)(*p++ & 0x3f)) << 12;
value |= (*p++ & 0x3f) << 6;
value |= *p++ & 0x3f;
if (value < 0x4000000)
return -4;
ret = 6;
} else
return -2;
*val = value;
return ret;
}
/* This takes a character 'value' and writes the UTF8 encoded value in
* 'str' where 'str' is a buffer containing 'len' characters. Returns
* the number of characters written or -1 if 'len' is too small. 'str' can
* be set to NULL in which case it just returns the number of characters.
* It will need at most 6 characters.
/*
* This takes a character 'value' and writes the UTF8 encoded value in 'str'
* where 'str' is a buffer containing 'len' characters. Returns the number of
* characters written or -1 if 'len' is too small. 'str' can be set to NULL
* in which case it just returns the number of characters. It will need at
* most 6 characters.
*/
int UTF8_putc(unsigned char *str, int len, unsigned long value)
{
if(!str) len = 6; /* Maximum we will need */
else if(len <= 0) return -1;
if(value < 0x80) {
if(str) *str = (unsigned char)value;
return 1;
}
if(value < 0x800) {
if(len < 2) return -1;
if(str) {
*str++ = (unsigned char)(((value >> 6) & 0x1f) | 0xc0);
*str = (unsigned char)((value & 0x3f) | 0x80);
}
return 2;
}
if(value < 0x10000) {
if(len < 3) return -1;
if(str) {
*str++ = (unsigned char)(((value >> 12) & 0xf) | 0xe0);
*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
*str = (unsigned char)((value & 0x3f) | 0x80);
}
return 3;
}
if(value < 0x200000) {
if(len < 4) return -1;
if(str) {
*str++ = (unsigned char)(((value >> 18) & 0x7) | 0xf0);
*str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
*str = (unsigned char)((value & 0x3f) | 0x80);
}
return 4;
}
if(value < 0x4000000) {
if(len < 5) return -1;
if(str) {
*str++ = (unsigned char)(((value >> 24) & 0x3) | 0xf8);
*str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
*str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
*str = (unsigned char)((value & 0x3f) | 0x80);
}
return 5;
}
if(len < 6) return -1;
if(str) {
*str++ = (unsigned char)(((value >> 30) & 0x1) | 0xfc);
*str++ = (unsigned char)(((value >> 24) & 0x3f) | 0x80);
*str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
*str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
*str = (unsigned char)((value & 0x3f) | 0x80);
}
return 6;
if (!str)
len = 6; /* Maximum we will need */
else if (len <= 0)
return -1;
if (value < 0x80) {
if (str)
*str = (unsigned char)value;
return 1;
}
if (value < 0x800) {
if (len < 2)
return -1;
if (str) {
*str++ = (unsigned char)(((value >> 6) & 0x1f) | 0xc0);
*str = (unsigned char)((value & 0x3f) | 0x80);
}
return 2;
}
if (value < 0x10000) {
if (len < 3)
return -1;
if (str) {
*str++ = (unsigned char)(((value >> 12) & 0xf) | 0xe0);
*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
*str = (unsigned char)((value & 0x3f) | 0x80);
}
return 3;
}
if (value < 0x200000) {
if (len < 4)
return -1;
if (str) {
*str++ = (unsigned char)(((value >> 18) & 0x7) | 0xf0);
*str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
*str = (unsigned char)((value & 0x3f) | 0x80);
}
return 4;
}
if (value < 0x4000000) {
if (len < 5)
return -1;
if (str) {
*str++ = (unsigned char)(((value >> 24) & 0x3) | 0xf8);
*str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
*str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
*str = (unsigned char)((value & 0x3f) | 0x80);
}
return 5;
}
if (len < 6)
return -1;
if (str) {
*str++ = (unsigned char)(((value >> 30) & 0x1) | 0xfc);
*str++ = (unsigned char)(((value >> 24) & 0x3f) | 0x80);
*str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
*str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
*str = (unsigned char)((value & 0x3f) | 0x80);
}
return 6;
}
+355 -356
View File
@@ -63,16 +63,19 @@
#include <openssl/err.h>
#include <openssl/mem.h>
/* Used in asn1_mac.h.
* TODO(davidben): Remove this once asn1_mac.h is gone or trimmed. */
OPENSSL_DECLARE_ERROR_REASON(ASN1, MALLOC_FAILURE);
/* Cross-module errors from crypto/x509/i2d_pr.c */
/* Cross-module errors from crypto/x509/i2d_pr.c. */
OPENSSL_DECLARE_ERROR_REASON(ASN1, UNSUPPORTED_PUBLIC_KEY_TYPE);
/* Cross-module errors from crypto/x509/asn1_gen.c.
* TODO(davidben): Remove these once asn1_gen.c is gone. */
/* Cross-module errors from crypto/x509/algorithm.c. */
OPENSSL_DECLARE_ERROR_REASON(ASN1, CONTEXT_NOT_INITIALISED);
OPENSSL_DECLARE_ERROR_REASON(ASN1, DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_SIGNATURE_ALGORITHM);
OPENSSL_DECLARE_ERROR_REASON(ASN1, WRONG_PUBLIC_KEY_TYPE);
/*
* Cross-module errors from crypto/x509/asn1_gen.c. TODO(davidben): Remove
* these once asn1_gen.c is gone.
*/
OPENSSL_DECLARE_ERROR_REASON(ASN1, DEPTH_EXCEEDED);
OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_BITSTRING_FORMAT);
OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_BOOLEAN);
@@ -97,414 +100,410 @@ OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_FORMAT);
OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_TAG);
OPENSSL_DECLARE_ERROR_REASON(ASN1, UNSUPPORTED_TYPE);
static int asn1_get_length(const unsigned char **pp,int *inf,long *rl,int max);
static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
int max);
static void asn1_put_length(unsigned char **pp, int length);
static int _asn1_check_infinite_end(const unsigned char **p, long len)
{
/* If there is 0 or 1 byte left, the length check should pick
* things up */
if (len <= 0)
return(1);
else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0))
{
(*p)+=2;
return(1);
}
return(0);
}
{
/*
* If there is 0 or 1 byte left, the length check should pick things up
*/
if (len <= 0)
return (1);
else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0)) {
(*p) += 2;
return (1);
}
return (0);
}
int ASN1_check_infinite_end(unsigned char **p, long len)
{
return _asn1_check_infinite_end((const unsigned char **)p, len);
}
{
return _asn1_check_infinite_end((const unsigned char **)p, len);
}
int ASN1_const_check_infinite_end(const unsigned char **p, long len)
{
return _asn1_check_infinite_end(p, len);
}
{
return _asn1_check_infinite_end(p, len);
}
int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
int *pclass, long omax)
{
int i,ret;
long l;
const unsigned char *p= *pp;
int tag,xclass,inf;
long max=omax;
int *pclass, long omax)
{
int i, ret;
long l;
const unsigned char *p = *pp;
int tag, xclass, inf;
long max = omax;
if (!max) goto err;
ret=(*p&V_ASN1_CONSTRUCTED);
xclass=(*p&V_ASN1_PRIVATE);
i= *p&V_ASN1_PRIMITIVE_TAG;
if (i == V_ASN1_PRIMITIVE_TAG)
{ /* high-tag */
p++;
if (--max == 0) goto err;
l=0;
while (*p&0x80)
{
l<<=7L;
l|= *(p++)&0x7f;
if (--max == 0) goto err;
if (l > (INT_MAX >> 7L)) goto err;
}
l<<=7L;
l|= *(p++)&0x7f;
tag=(int)l;
if (--max == 0) goto err;
}
else
{
tag=i;
p++;
if (--max == 0) goto err;
}
*ptag=tag;
*pclass=xclass;
if (!asn1_get_length(&p,&inf,plength,(int)max)) goto err;
if (!max)
goto err;
ret = (*p & V_ASN1_CONSTRUCTED);
xclass = (*p & V_ASN1_PRIVATE);
i = *p & V_ASN1_PRIMITIVE_TAG;
if (i == V_ASN1_PRIMITIVE_TAG) { /* high-tag */
p++;
if (--max == 0)
goto err;
l = 0;
while (*p & 0x80) {
l <<= 7L;
l |= *(p++) & 0x7f;
if (--max == 0)
goto err;
if (l > (INT_MAX >> 7L))
goto err;
}
l <<= 7L;
l |= *(p++) & 0x7f;
tag = (int)l;
if (--max == 0)
goto err;
} else {
tag = i;
p++;
if (--max == 0)
goto err;
}
if (inf && !(ret & V_ASN1_CONSTRUCTED))
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;
if (inf && !(ret & V_ASN1_CONSTRUCTED))
goto err;
#if 0
fprintf(stderr,"p=%d + *plength=%ld > omax=%ld + *pp=%d (%d > %d)\n",
(int)p,*plength,omax,(int)*pp,(int)(p+ *plength),
(int)(omax+ *pp));
fprintf(stderr, "p=%d + *plength=%ld > omax=%ld + *pp=%d (%d > %d)\n",
(int)p, *plength, omax, (int)*pp, (int)(p + *plength),
(int)(omax + *pp));
#endif
if (*plength > (omax - (p - *pp)))
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
/* Set this so that even if things are not long enough
* the values are set correctly */
ret|=0x80;
}
*pp=p;
return(ret|inf);
err:
OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG);
return(0x80);
}
if (*plength > (omax - (p - *pp))) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
/*
* Set this so that even if things are not long enough the values are
* set correctly
*/
ret |= 0x80;
}
*pp = p;
return (ret | inf);
err:
OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG);
return (0x80);
}
static int asn1_get_length(const unsigned char **pp, int *inf, long *rl, int max)
{
const unsigned char *p= *pp;
unsigned long ret=0;
unsigned int i;
static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
int max)
{
const unsigned char *p = *pp;
unsigned long ret = 0;
unsigned int i;
if (max-- < 1) return(0);
if (*p == 0x80)
{
*inf=1;
ret=0;
p++;
}
else
{
*inf=0;
i= *p&0x7f;
if (*(p++) & 0x80)
{
if (i > sizeof(long))
return 0;
if (max-- == 0) return(0);
while (i-- > 0)
{
ret<<=8L;
ret|= *(p++);
if (max-- == 0) return(0);
}
}
else
ret=i;
}
if (ret > LONG_MAX)
return 0;
*pp=p;
*rl=(long)ret;
return(1);
}
if (max-- < 1)
return (0);
if (*p == 0x80) {
*inf = 1;
ret = 0;
p++;
} else {
*inf = 0;
i = *p & 0x7f;
if (*(p++) & 0x80) {
if (i > sizeof(long))
return 0;
if (max-- == 0)
return (0);
while (i-- > 0) {
ret <<= 8L;
ret |= *(p++);
if (max-- == 0)
return (0);
}
} else
ret = i;
}
if (ret > LONG_MAX)
return 0;
*pp = p;
*rl = (long)ret;
return (1);
}
/* class 0 is constructed
* constructed == 2 for indefinite length constructed */
/*
* class 0 is constructed constructed == 2 for indefinite length constructed
*/
void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
int xclass)
{
unsigned char *p= *pp;
int i, ttag;
int xclass)
{
unsigned char *p = *pp;
int i, ttag;
i=(constructed)?V_ASN1_CONSTRUCTED:0;
i|=(xclass&V_ASN1_PRIVATE);
if (tag < 31)
*(p++)=i|(tag&V_ASN1_PRIMITIVE_TAG);
else
{
*(p++)=i|V_ASN1_PRIMITIVE_TAG;
for(i = 0, ttag = tag; ttag > 0; i++) ttag >>=7;
ttag = i;
while(i-- > 0)
{
p[i] = tag & 0x7f;
if(i != (ttag - 1)) p[i] |= 0x80;
tag >>= 7;
}
p += ttag;
}
if (constructed == 2)
*(p++)=0x80;
else
asn1_put_length(&p,length);
*pp=p;
}
i = (constructed) ? V_ASN1_CONSTRUCTED : 0;
i |= (xclass & V_ASN1_PRIVATE);
if (tag < 31)
*(p++) = i | (tag & V_ASN1_PRIMITIVE_TAG);
else {
*(p++) = i | V_ASN1_PRIMITIVE_TAG;
for (i = 0, ttag = tag; ttag > 0; i++)
ttag >>= 7;
ttag = i;
while (i-- > 0) {
p[i] = tag & 0x7f;
if (i != (ttag - 1))
p[i] |= 0x80;
tag >>= 7;
}
p += ttag;
}
if (constructed == 2)
*(p++) = 0x80;
else
asn1_put_length(&p, length);
*pp = p;
}
int ASN1_put_eoc(unsigned char **pp)
{
unsigned char *p = *pp;
*p++ = 0;
*p++ = 0;
*pp = p;
return 2;
}
{
unsigned char *p = *pp;
*p++ = 0;
*p++ = 0;
*pp = p;
return 2;
}
static void asn1_put_length(unsigned char **pp, int length)
{
unsigned char *p= *pp;
int i,l;
if (length <= 127)
*(p++)=(unsigned char)length;
else
{
l=length;
for (i=0; l > 0; i++)
l>>=8;
*(p++)=i|0x80;
l=i;
while (i-- > 0)
{
p[i]=length&0xff;
length>>=8;
}
p+=l;
}
*pp=p;
}
{
unsigned char *p = *pp;
int i, l;
if (length <= 127)
*(p++) = (unsigned char)length;
else {
l = length;
for (i = 0; l > 0; i++)
l >>= 8;
*(p++) = i | 0x80;
l = i;
while (i-- > 0) {
p[i] = length & 0xff;
length >>= 8;
}
p += l;
}
*pp = p;
}
int ASN1_object_size(int constructed, int length, int tag)
{
int ret;
{
int ret;
ret=length;
ret++;
if (tag >= 31)
{
while (tag > 0)
{
tag>>=7;
ret++;
}
}
if (constructed == 2)
return ret + 3;
ret++;
if (length > 127)
{
while (length > 0)
{
length>>=8;
ret++;
}
}
return(ret);
}
ret = length;
ret++;
if (tag >= 31) {
while (tag > 0) {
tag >>= 7;
ret++;
}
}
if (constructed == 2)
return ret + 3;
ret++;
if (length > 127) {
while (length > 0) {
length >>= 8;
ret++;
}
}
return (ret);
}
static int _asn1_Finish(ASN1_const_CTX *c)
{
if ((c->inf == (1|V_ASN1_CONSTRUCTED)) && (!c->eos))
{
if (!ASN1_const_check_infinite_end(&c->p,c->slen))
{
c->error=ASN1_R_MISSING_ASN1_EOS;
return(0);
}
}
if ( ((c->slen != 0) && !(c->inf & 1)) ||
((c->slen < 0) && (c->inf & 1)))
{
c->error=ASN1_R_ASN1_LENGTH_MISMATCH;
return(0);
}
return(1);
}
{
if ((c->inf == (1 | V_ASN1_CONSTRUCTED)) && (!c->eos)) {
if (!ASN1_const_check_infinite_end(&c->p, c->slen)) {
c->error = ASN1_R_MISSING_ASN1_EOS;
return (0);
}
}
if (((c->slen != 0) && !(c->inf & 1)) || ((c->slen < 0) && (c->inf & 1))) {
c->error = ASN1_R_ASN1_LENGTH_MISMATCH;
return (0);
}
return (1);
}
int asn1_Finish(ASN1_CTX *c)
{
return _asn1_Finish((ASN1_const_CTX *)c);
}
{
return _asn1_Finish((ASN1_const_CTX *)c);
}
int asn1_const_Finish(ASN1_const_CTX *c)
{
return _asn1_Finish(c);
}
{
return _asn1_Finish(c);
}
int asn1_GetSequence(ASN1_const_CTX *c, long *length)
{
const unsigned char *q;
{
const unsigned char *q;
q=c->p;
c->inf=ASN1_get_object(&(c->p),&(c->slen),&(c->tag),&(c->xclass),
*length);
if (c->inf & 0x80)
{
c->error=ASN1_R_BAD_GET_ASN1_OBJECT_CALL;
return(0);
}
if (c->tag != V_ASN1_SEQUENCE)
{
c->error=ASN1_R_EXPECTING_AN_ASN1_SEQUENCE;
return(0);
}
(*length)-=(c->p-q);
if (c->max && (*length < 0))
{
c->error=ASN1_R_ASN1_LENGTH_MISMATCH;
return(0);
}
if (c->inf == (1|V_ASN1_CONSTRUCTED))
c->slen= *length+ *(c->pp)-c->p;
c->eos=0;
return(1);
}
q = c->p;
c->inf = ASN1_get_object(&(c->p), &(c->slen), &(c->tag), &(c->xclass),
*length);
if (c->inf & 0x80) {
c->error = ASN1_R_BAD_GET_ASN1_OBJECT_CALL;
return (0);
}
if (c->tag != V_ASN1_SEQUENCE) {
c->error = ASN1_R_EXPECTING_AN_ASN1_SEQUENCE;
return (0);
}
(*length) -= (c->p - q);
if (c->max && (*length < 0)) {
c->error = ASN1_R_ASN1_LENGTH_MISMATCH;
return (0);
}
if (c->inf == (1 | V_ASN1_CONSTRUCTED))
c->slen = *length + *(c->pp) - c->p;
c->eos = 0;
return (1);
}
int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
{
if (str == NULL)
return 0;
dst->type = str->type;
if (!ASN1_STRING_set(dst,str->data,str->length))
return 0;
dst->flags = str->flags;
return 1;
}
{
if (str == NULL)
return 0;
dst->type = str->type;
if (!ASN1_STRING_set(dst, str->data, str->length))
return 0;
dst->flags = str->flags;
return 1;
}
ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str)
{
ASN1_STRING *ret;
if (!str)
return NULL;
ret=ASN1_STRING_new();
if (!ret)
return NULL;
if (!ASN1_STRING_copy(ret,str))
{
ASN1_STRING_free(ret);
return NULL;
}
return ret;
}
{
ASN1_STRING *ret;
if (!str)
return NULL;
ret = ASN1_STRING_new();
if (!ret)
return NULL;
if (!ASN1_STRING_copy(ret, str)) {
ASN1_STRING_free(ret);
return NULL;
}
return ret;
}
int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
{
unsigned char *c;
const char *data=_data;
{
unsigned char *c;
const char *data = _data;
if (len < 0)
{
if (data == NULL)
return(0);
else
len=strlen(data);
}
if ((str->length < len) || (str->data == NULL))
{
c=str->data;
if (c == NULL)
str->data=OPENSSL_malloc(len+1);
else
str->data=OPENSSL_realloc(c,len+1);
if (len < 0) {
if (data == NULL)
return (0);
else
len = strlen(data);
}
if ((str->length < len) || (str->data == NULL)) {
c = str->data;
if (c == NULL)
str->data = OPENSSL_malloc(len + 1);
else
str->data = OPENSSL_realloc(c, len + 1);
if (str->data == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
str->data=c;
return(0);
}
}
str->length=len;
if (data != NULL)
{
memcpy(str->data,data,len);
/* an allowance for strings :-) */
str->data[len]='\0';
}
return(1);
}
if (str->data == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
str->data = c;
return (0);
}
}
str->length = len;
if (data != NULL) {
memcpy(str->data, data, len);
/* an allowance for strings :-) */
str->data[len] = '\0';
}
return (1);
}
void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len)
{
if (str->data)
OPENSSL_free(str->data);
str->data = data;
str->length = len;
}
{
if (str->data)
OPENSSL_free(str->data);
str->data = data;
str->length = len;
}
ASN1_STRING *ASN1_STRING_new(void)
{
return(ASN1_STRING_type_new(V_ASN1_OCTET_STRING));
}
{
return (ASN1_STRING_type_new(V_ASN1_OCTET_STRING));
}
ASN1_STRING *ASN1_STRING_type_new(int type)
{
ASN1_STRING *ret;
{
ASN1_STRING *ret;
ret=(ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING));
if (ret == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return(NULL);
}
ret->length=0;
ret->type=type;
ret->data=NULL;
ret->flags=0;
return(ret);
}
ret = (ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING));
if (ret == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return (NULL);
}
ret->length = 0;
ret->type = type;
ret->data = NULL;
ret->flags = 0;
return (ret);
}
void ASN1_STRING_free(ASN1_STRING *a)
{
if (a == NULL) return;
if (a->data && !(a->flags & ASN1_STRING_FLAG_NDEF))
OPENSSL_free(a->data);
OPENSSL_free(a);
}
{
if (a == NULL)
return;
if (a->data && !(a->flags & ASN1_STRING_FLAG_NDEF))
OPENSSL_free(a->data);
OPENSSL_free(a);
}
int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
{
int i;
{
int i;
i=(a->length-b->length);
if (i == 0)
{
i=memcmp(a->data,b->data,a->length);
if (i == 0)
return(a->type-b->type);
else
return(i);
}
else
return(i);
}
i = (a->length - b->length);
if (i == 0) {
i = memcmp(a->data, b->data, a->length);
if (i == 0)
return (a->type - b->type);
else
return (i);
} else
return (i);
}
int ASN1_STRING_length(const ASN1_STRING *x)
{ return M_ASN1_STRING_length(x); }
{
return M_ASN1_STRING_length(x);
}
void ASN1_STRING_length_set(ASN1_STRING *x, int len)
{ M_ASN1_STRING_length_set(x, len); return; }
{
M_ASN1_STRING_length_set(x, len);
return;
}
int ASN1_STRING_type(ASN1_STRING *x)
{ return M_ASN1_STRING_type(x); }
{
return M_ASN1_STRING_type(x);
}
unsigned char * ASN1_STRING_data(ASN1_STRING *x)
{ return M_ASN1_STRING_data(x); }
unsigned char *ASN1_STRING_data(ASN1_STRING *x)
{
return M_ASN1_STRING_data(x);
}
+11 -11
View File
@@ -1,6 +1,7 @@
/* asn1t.h */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2006.
/*
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
* 2006.
*/
/* ====================================================================
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
@@ -10,7 +11,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 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
@@ -63,11 +64,10 @@ int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d);
/* ASN1 print context structure */
struct asn1_pctx_st
{
unsigned long flags;
unsigned long nm_flags;
unsigned long cert_flags;
unsigned long oid_flags;
unsigned long str_flags;
} /* ASN1_PCTX */;
struct asn1_pctx_st {
unsigned long flags;
unsigned long nm_flags;
unsigned long cert_flags;
unsigned long oid_flags;
unsigned long str_flags;
} /* ASN1_PCTX */ ;
+313 -346
View File
@@ -60,376 +60,343 @@
#include <openssl/err.h>
#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,
int offset, int depth, int indent, int dump);
static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
int indent)
{
static const char fmt[]="%-18s";
char str[128];
const char *p;
int indent);
static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
int offset, int depth, int indent, int dump);
static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
int indent)
{
static const char fmt[] = "%-18s";
char str[128];
const char *p;
if (constructed & V_ASN1_CONSTRUCTED)
p="cons: ";
else
p="prim: ";
if (BIO_write(bp,p,6) < 6) goto err;
BIO_indent(bp,indent,128);
if (constructed & V_ASN1_CONSTRUCTED)
p = "cons: ";
else
p = "prim: ";
if (BIO_write(bp, p, 6) < 6)
goto err;
BIO_indent(bp, indent, 128);
p=str;
if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
BIO_snprintf(str,sizeof str,"priv [ %d ] ",tag);
else if ((xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
BIO_snprintf(str,sizeof str,"cont [ %d ]",tag);
else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
BIO_snprintf(str,sizeof str,"appl [ %d ]",tag);
else if (tag > 30)
BIO_snprintf(str,sizeof str,"<ASN1 %d>",tag);
else
p = ASN1_tag2str(tag);
p = str;
if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
BIO_snprintf(str, sizeof str, "priv [ %d ] ", tag);
else if ((xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
BIO_snprintf(str, sizeof str, "cont [ %d ]", tag);
else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
BIO_snprintf(str, sizeof str, "appl [ %d ]", tag);
else if (tag > 30)
BIO_snprintf(str, sizeof str, "<ASN1 %d>", tag);
else
p = ASN1_tag2str(tag);
if (BIO_printf(bp,fmt,p) <= 0)
goto err;
return(1);
err:
return(0);
}
if (BIO_printf(bp, fmt, p) <= 0)
goto err;
return (1);
err:
return (0);
}
int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent)
{
return(asn1_parse2(bp,&pp,len,0,0,indent,0));
}
{
return (asn1_parse2(bp, &pp, len, 0, 0, indent, 0));
}
int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent, int dump)
{
return(asn1_parse2(bp,&pp,len,0,0,indent,dump));
}
int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent,
int dump)
{
return (asn1_parse2(bp, &pp, len, 0, 0, indent, dump));
}
static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offset,
int depth, int indent, int dump)
{
const unsigned char *p,*ep,*tot,*op,*opp;
long len;
int tag,xclass,ret=0;
int nl,hl,j,r;
ASN1_OBJECT *o=NULL;
ASN1_OCTET_STRING *os=NULL;
/* ASN1_BMPSTRING *bmp=NULL;*/
int dump_indent;
static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
int offset, int depth, int indent, int dump)
{
const unsigned char *p, *ep, *tot, *op, *opp;
long len;
int tag, xclass, ret = 0;
int nl, hl, j, r;
ASN1_OBJECT *o = NULL;
ASN1_OCTET_STRING *os = NULL;
/* ASN1_BMPSTRING *bmp=NULL; */
int dump_indent;
#if 0
dump_indent = indent;
dump_indent = indent;
#else
dump_indent = 6; /* Because we know BIO_dump_indent() */
dump_indent = 6; /* Because we know BIO_dump_indent() */
#endif
p= *pp;
tot=p+length;
op=p-1;
while ((p < tot) && (op < p))
{
op=p;
j=ASN1_get_object(&p,&len,&tag,&xclass,length);
if (depth > ASN1_PARSE_MAXDEPTH) {
BIO_puts(bp, "BAD RECURSION DEPTH\n");
return 0;
}
p = *pp;
tot = p + length;
op = p - 1;
while ((p < tot) && (op < p)) {
op = p;
j = ASN1_get_object(&p, &len, &tag, &xclass, length);
#ifdef LINT
j=j;
j = j;
#endif
if (j & 0x80)
{
if (BIO_puts(bp, "Error in encoding\n") <= 0)
goto end;
ret=0;
goto end;
}
hl=(p-op);
length-=hl;
/* if j == 0x21 it is a constructed indefinite length object */
if (BIO_printf(bp,"%5ld:",(long)offset+(long)(op- *pp))
<= 0) goto end;
if (j & 0x80) {
if (BIO_puts(bp, "Error in encoding\n") <= 0)
goto end;
ret = 0;
goto end;
}
hl = (p - op);
length -= hl;
/*
* if j == 0x21 it is a constructed indefinite length object
*/
if (BIO_printf(bp, "%5ld:", (long)offset + (long)(op - *pp))
<= 0)
goto end;
if (j != (V_ASN1_CONSTRUCTED | 1))
{
if (BIO_printf(bp,"d=%-2d hl=%ld l=%4ld ",
depth,(long)hl,len) <= 0)
goto end;
}
else
{
if (BIO_printf(bp,"d=%-2d hl=%ld l=inf ",
depth,(long)hl) <= 0)
goto end;
}
if (!asn1_print_info(bp,tag,xclass,j,(indent)?depth:0))
goto end;
if (j & V_ASN1_CONSTRUCTED)
{
ep=p+len;
if (BIO_puts(bp, "\n") <= 0) goto end;
if (len > length)
{
BIO_printf(bp,
"length is greater than %ld\n",length);
ret=0;
goto end;
}
if ((j == 0x21) && (len == 0))
{
for (;;)
{
r=asn1_parse2(bp,&p,(long)(tot-p),
offset+(p - *pp),depth+1,
indent,dump);
if (r == 0) { ret=0; goto end; }
if ((r == 2) || (p >= tot)) break;
}
}
else
while (p < ep)
{
r=asn1_parse2(bp,&p,(long)len,
offset+(p - *pp),depth+1,
indent,dump);
if (r == 0) { ret=0; goto end; }
}
}
else if (xclass != 0)
{
p+=len;
if (BIO_puts(bp, "\n") <= 0) goto end;
}
else
{
nl=0;
if ( (tag == V_ASN1_PRINTABLESTRING) ||
(tag == V_ASN1_T61STRING) ||
(tag == V_ASN1_IA5STRING) ||
(tag == V_ASN1_VISIBLESTRING) ||
(tag == V_ASN1_NUMERICSTRING) ||
(tag == V_ASN1_UTF8STRING) ||
(tag == V_ASN1_UTCTIME) ||
(tag == V_ASN1_GENERALIZEDTIME))
{
if (BIO_puts(bp, ":") <= 0) goto end;
if ((len > 0) &&
BIO_write(bp,(const char *)p,(int)len)
!= (int)len)
goto end;
}
else if (tag == V_ASN1_OBJECT)
{
opp=op;
if (d2i_ASN1_OBJECT(&o,&opp,len+hl) != NULL)
{
if (BIO_puts(bp, ":") <= 0) goto end;
i2a_ASN1_OBJECT(bp,o);
}
else
{
if (BIO_puts(bp, ":BAD OBJECT") <= 0)
goto end;
}
}
else if (tag == V_ASN1_BOOLEAN)
{
int ii;
if (j != (V_ASN1_CONSTRUCTED | 1)) {
if (BIO_printf(bp, "d=%-2d hl=%ld l=%4ld ",
depth, (long)hl, len) <= 0)
goto end;
} else {
if (BIO_printf(bp, "d=%-2d hl=%ld l=inf ", depth, (long)hl) <= 0)
goto end;
}
if (!asn1_print_info(bp, tag, xclass, j, (indent) ? depth : 0))
goto end;
if (j & V_ASN1_CONSTRUCTED) {
ep = p + len;
if (BIO_puts(bp, "\n") <= 0)
goto end;
if (len > length) {
BIO_printf(bp, "length is greater than %ld\n", length);
ret = 0;
goto end;
}
if ((j == 0x21) && (len == 0)) {
for (;;) {
r = asn1_parse2(bp, &p, (long)(tot - p),
offset + (p - *pp), depth + 1,
indent, dump);
if (r == 0) {
ret = 0;
goto end;
}
if ((r == 2) || (p >= tot))
break;
}
} else
while (p < ep) {
r = asn1_parse2(bp, &p, (long)len,
offset + (p - *pp), depth + 1,
indent, dump);
if (r == 0) {
ret = 0;
goto end;
}
}
} else if (xclass != 0) {
p += len;
if (BIO_puts(bp, "\n") <= 0)
goto end;
} else {
nl = 0;
if ((tag == V_ASN1_PRINTABLESTRING) ||
(tag == V_ASN1_T61STRING) ||
(tag == V_ASN1_IA5STRING) ||
(tag == V_ASN1_VISIBLESTRING) ||
(tag == V_ASN1_NUMERICSTRING) ||
(tag == V_ASN1_UTF8STRING) ||
(tag == V_ASN1_UTCTIME) || (tag == V_ASN1_GENERALIZEDTIME)) {
if (BIO_puts(bp, ":") <= 0)
goto end;
if ((len > 0) && BIO_write(bp, (const char *)p, (int)len)
!= (int)len)
goto end;
} else if (tag == V_ASN1_OBJECT) {
opp = op;
if (d2i_ASN1_OBJECT(&o, &opp, len + hl) != NULL) {
if (BIO_puts(bp, ":") <= 0)
goto end;
i2a_ASN1_OBJECT(bp, o);
} else {
if (BIO_puts(bp, ":BAD OBJECT") <= 0)
goto end;
}
} else if (tag == V_ASN1_BOOLEAN) {
int ii;
opp=op;
ii=d2i_ASN1_BOOLEAN(NULL,&opp,len+hl);
if (ii < 0)
{
if (BIO_puts(bp, "Bad boolean\n") <= 0)
goto end;
}
BIO_printf(bp,":%d",ii);
}
else if (tag == V_ASN1_BMPSTRING)
{
/* do the BMP thang */
}
else if (tag == V_ASN1_OCTET_STRING)
{
int i,printable=1;
opp = op;
ii = d2i_ASN1_BOOLEAN(NULL, &opp, len + hl);
if (ii < 0) {
if (BIO_puts(bp, "Bad boolean\n") <= 0)
goto end;
}
BIO_printf(bp, ":%d", ii);
} else if (tag == V_ASN1_BMPSTRING) {
/* do the BMP thang */
} else if (tag == V_ASN1_OCTET_STRING) {
int i, printable = 1;
opp=op;
os=d2i_ASN1_OCTET_STRING(NULL,&opp,len+hl);
if (os != NULL && os->length > 0)
{
opp = os->data;
/* testing whether the octet string is
* printable */
for (i=0; i<os->length; i++)
{
if (( (opp[i] < ' ') &&
(opp[i] != '\n') &&
(opp[i] != '\r') &&
(opp[i] != '\t')) ||
(opp[i] > '~'))
{
printable=0;
break;
}
}
if (printable)
/* printable string */
{
if (BIO_puts(bp, ":") <= 0)
goto end;
if (BIO_write(bp,(const char *)opp,
os->length) <= 0)
goto end;
}
else if (!dump)
/* not printable => print octet string
* as hex dump */
{
if (BIO_puts(bp, "[HEX DUMP]:") <= 0)
goto end;
for (i=0; i<os->length; i++)
{
if (BIO_printf(bp,"%02X"
, opp[i]) <= 0)
goto end;
}
}
else
/* print the normal dump */
{
if (!nl)
{
if (BIO_puts(bp, "\n") <= 0)
goto end;
}
if (!BIO_hexdump(bp, opp,
((dump == -1 || dump >
os->length)?os->length:dump),
dump_indent))
goto end;
nl=1;
}
}
if (os != NULL)
{
M_ASN1_OCTET_STRING_free(os);
os=NULL;
}
}
else if (tag == V_ASN1_INTEGER)
{
ASN1_INTEGER *bs;
int i;
opp = op;
os = d2i_ASN1_OCTET_STRING(NULL, &opp, len + hl);
if (os != NULL && os->length > 0) {
opp = os->data;
/*
* testing whether the octet string is printable
*/
for (i = 0; i < os->length; i++) {
if (((opp[i] < ' ') &&
(opp[i] != '\n') &&
(opp[i] != '\r') &&
(opp[i] != '\t')) || (opp[i] > '~')) {
printable = 0;
break;
}
}
if (printable)
/* printable string */
{
if (BIO_puts(bp, ":") <= 0)
goto end;
if (BIO_write(bp, (const char *)opp, os->length) <= 0)
goto end;
} else if (!dump)
/*
* not printable => print octet string as hex dump
*/
{
if (BIO_puts(bp, "[HEX DUMP]:") <= 0)
goto end;
for (i = 0; i < os->length; i++) {
if (BIO_printf(bp, "%02X", opp[i]) <= 0)
goto end;
}
} else
/* print the normal dump */
{
if (!nl) {
if (BIO_puts(bp, "\n") <= 0)
goto end;
}
if (!BIO_hexdump(bp, opp,
((dump == -1 || dump >
os->length) ? os->length : dump),
dump_indent))
goto end;
nl = 1;
}
}
if (os != NULL) {
M_ASN1_OCTET_STRING_free(os);
os = NULL;
}
} else if (tag == V_ASN1_INTEGER) {
ASN1_INTEGER *bs;
int i;
opp=op;
bs=d2i_ASN1_INTEGER(NULL,&opp,len+hl);
if (bs != NULL)
{
if (BIO_puts(bp, ":") <= 0) goto end;
if (bs->type == V_ASN1_NEG_INTEGER)
if (BIO_puts(bp, "-") <= 0)
goto end;
for (i=0; i<bs->length; i++)
{
if (BIO_printf(bp,"%02X",
bs->data[i]) <= 0)
goto end;
}
if (bs->length == 0)
{
if (BIO_puts(bp, "00") <= 0)
goto end;
}
}
else
{
if (BIO_puts(bp, "BAD INTEGER") <= 0)
goto end;
}
M_ASN1_INTEGER_free(bs);
}
else if (tag == V_ASN1_ENUMERATED)
{
ASN1_ENUMERATED *bs;
int i;
opp = op;
bs = d2i_ASN1_INTEGER(NULL, &opp, len + hl);
if (bs != NULL) {
if (BIO_puts(bp, ":") <= 0)
goto end;
if (bs->type == V_ASN1_NEG_INTEGER)
if (BIO_puts(bp, "-") <= 0)
goto end;
for (i = 0; i < bs->length; i++) {
if (BIO_printf(bp, "%02X", bs->data[i]) <= 0)
goto end;
}
if (bs->length == 0) {
if (BIO_puts(bp, "00") <= 0)
goto end;
}
} else {
if (BIO_puts(bp, "BAD INTEGER") <= 0)
goto end;
}
M_ASN1_INTEGER_free(bs);
} else if (tag == V_ASN1_ENUMERATED) {
ASN1_ENUMERATED *bs;
int i;
opp=op;
bs=d2i_ASN1_ENUMERATED(NULL,&opp,len+hl);
if (bs != NULL)
{
if (BIO_puts(bp, ":") <= 0) goto end;
if (bs->type == V_ASN1_NEG_ENUMERATED)
if (BIO_puts(bp, "-") <= 0)
goto end;
for (i=0; i<bs->length; i++)
{
if (BIO_printf(bp,"%02X",
bs->data[i]) <= 0)
goto end;
}
if (bs->length == 0)
{
if (BIO_puts(bp, "00") <= 0)
goto end;
}
}
else
{
if (BIO_puts(bp, "BAD ENUMERATED") <= 0)
goto end;
}
M_ASN1_ENUMERATED_free(bs);
}
else if (len > 0 && dump)
{
if (!nl)
{
if (BIO_puts(bp, "\n") <= 0)
goto end;
}
if (!BIO_hexdump(bp,p,
((dump == -1 || dump > len)?len:dump),
dump_indent))
goto end;
nl=1;
}
opp = op;
bs = d2i_ASN1_ENUMERATED(NULL, &opp, len + hl);
if (bs != NULL) {
if (BIO_puts(bp, ":") <= 0)
goto end;
if (bs->type == V_ASN1_NEG_ENUMERATED)
if (BIO_puts(bp, "-") <= 0)
goto end;
for (i = 0; i < bs->length; i++) {
if (BIO_printf(bp, "%02X", bs->data[i]) <= 0)
goto end;
}
if (bs->length == 0) {
if (BIO_puts(bp, "00") <= 0)
goto end;
}
} else {
if (BIO_puts(bp, "BAD ENUMERATED") <= 0)
goto end;
}
M_ASN1_ENUMERATED_free(bs);
} else if (len > 0 && dump) {
if (!nl) {
if (BIO_puts(bp, "\n") <= 0)
goto end;
}
if (!BIO_hexdump(bp, p,
((dump == -1 || dump > len) ? len : dump),
dump_indent))
goto end;
nl = 1;
}
if (!nl)
{
if (BIO_puts(bp, "\n") <= 0) goto end;
}
p+=len;
if ((tag == V_ASN1_EOC) && (xclass == 0))
{
ret=2; /* End of sequence */
goto end;
}
}
length-=len;
}
ret=1;
end:
if (o != NULL) ASN1_OBJECT_free(o);
if (os != NULL) M_ASN1_OCTET_STRING_free(os);
*pp=p;
return(ret);
}
if (!nl) {
if (BIO_puts(bp, "\n") <= 0)
goto end;
}
p += len;
if ((tag == V_ASN1_EOC) && (xclass == 0)) {
ret = 2; /* End of sequence */
goto end;
}
}
length -= len;
}
ret = 1;
end:
if (o != NULL)
ASN1_OBJECT_free(o);
if (os != NULL)
M_ASN1_OCTET_STRING_free(os);
*pp = p;
return (ret);
}
const char *ASN1_tag2str(int tag)
{
static const char * const tag2str[] = {
"EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", /* 0-4 */
"NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */
"ENUMERATED", "<ASN1 11>", "UTF8STRING", "<ASN1 13>", /* 10-13 */
"<ASN1 14>", "<ASN1 15>", "SEQUENCE", "SET", /* 15-17 */
"NUMERICSTRING", "PRINTABLESTRING", "T61STRING", /* 18-20 */
"VIDEOTEXSTRING", "IA5STRING", "UTCTIME","GENERALIZEDTIME", /* 21-24 */
"GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", /* 25-27 */
"UNIVERSALSTRING", "<ASN1 29>", "BMPSTRING" /* 28-30 */
};
static const char *const tag2str[] = {
"EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", /* 0-4 */
"NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */
"ENUMERATED", "<ASN1 11>", "UTF8STRING", "<ASN1 13>", /* 10-13 */
"<ASN1 14>", "<ASN1 15>", "SEQUENCE", "SET", /* 15-17 */
"NUMERICSTRING", "PRINTABLESTRING", "T61STRING", /* 18-20 */
"VIDEOTEXSTRING", "IA5STRING", "UTCTIME", "GENERALIZEDTIME", /* 21-24
*/
"GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", /* 25-27 */
"UNIVERSALSTRING", "<ASN1 29>", "BMPSTRING" /* 28-30 */
};
if((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED))
tag &= ~0x100;
if ((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED))
tag &= ~0x100;
if(tag < 0 || tag > 30) return "(unknown)";
return tag2str[tag];
if (tag < 0 || tag > 30)
return "(unknown)";
return tag2str[tag];
}
+81
View File
@@ -0,0 +1,81 @@
/* 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"
// kTag128 is an ASN.1 structure with a universal tag with number 128.
static const uint8_t kTag128[] = {
0x1f, 0x81, 0x00, 0x01, 0x00,
};
// 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.");
// kTagOverflow is an ASN.1 structure with a universal tag with number 2^35-1,
// which will not fit in an int.
static const uint8_t kTagOverflow[] = {
0x1f, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x01, 0x00,
};
static 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;
}
ERR_clear_error();
p = kTagOverflow;
obj.reset(d2i_ASN1_TYPE(NULL, &p, sizeof(kTagOverflow)));
if (obj) {
fprintf(stderr, "Parsed value with tag overflow (type = %d).\n", obj->type);
return false;
}
ERR_clear_error();
p = kTag128;
obj.reset(d2i_ASN1_TYPE(NULL, &p, sizeof(kTag128)));
if (!obj || obj->type != 128 || obj->value.asn1_string->length != 1 ||
obj->value.asn1_string->data[0] != 0) {
fprintf(stderr, "Failed to parse value with tag 128.\n");
ERR_print_errors_fp(stderr);
return false;
}
return true;
}
int main() {
CRYPTO_library_init();
if (!TestLargeTags()) {
return 1;
}
printf("PASS\n");
return 0;
}
+30 -29
View File
@@ -59,46 +59,47 @@
#include <openssl/err.h>
#include <openssl/mem.h>
/* ASN1_ITEM versions of the above */
ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct)
{
ASN1_STRING *octmp;
ASN1_STRING *octmp;
if (!oct || !*oct) {
if (!(octmp = ASN1_STRING_new ())) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return NULL;
}
if (oct) *oct = octmp;
} else octmp = *oct;
if (!oct || !*oct) {
if (!(octmp = ASN1_STRING_new())) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return NULL;
}
if (oct)
*oct = octmp;
} else
octmp = *oct;
if(octmp->data) {
OPENSSL_free(octmp->data);
octmp->data = NULL;
}
if (!(octmp->length = ASN1_item_i2d(obj, &octmp->data, it))) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_ENCODE_ERROR);
return NULL;
}
if (!octmp->data) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return NULL;
}
return octmp;
if (octmp->data) {
OPENSSL_free(octmp->data);
octmp->data = NULL;
}
if (!(octmp->length = ASN1_item_i2d(obj, &octmp->data, it))) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_ENCODE_ERROR);
return NULL;
}
if (!octmp->data) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return NULL;
}
return octmp;
}
/* Extract an ASN1 object from an ASN1_STRING */
void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it)
{
const unsigned char *p;
void *ret;
const unsigned char *p;
void *ret;
p = oct->data;
if(!(ret = ASN1_item_d2i(NULL, &p, oct->length, it)))
OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR);
return ret;
p = oct->data;
if (!(ret = ASN1_item_d2i(NULL, &p, oct->length, it)))
OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR);
return ret;
}
+329 -348
View File
@@ -62,53 +62,48 @@
#include <openssl/bio.h>
#include <openssl/mem.h>
/* Must be large enough for biggest tag+length */
#define DEFAULT_ASN1_BUF_SIZE 20
typedef enum
{
ASN1_STATE_START,
ASN1_STATE_PRE_COPY,
ASN1_STATE_HEADER,
ASN1_STATE_HEADER_COPY,
ASN1_STATE_DATA_COPY,
ASN1_STATE_POST_COPY,
ASN1_STATE_DONE
} asn1_bio_state_t;
typedef enum {
ASN1_STATE_START,
ASN1_STATE_PRE_COPY,
ASN1_STATE_HEADER,
ASN1_STATE_HEADER_COPY,
ASN1_STATE_DATA_COPY,
ASN1_STATE_POST_COPY,
ASN1_STATE_DONE
} asn1_bio_state_t;
typedef struct BIO_ASN1_EX_FUNCS_st
{
asn1_ps_func *ex_func;
asn1_ps_func *ex_free_func;
} BIO_ASN1_EX_FUNCS;
typedef struct BIO_ASN1_EX_FUNCS_st {
asn1_ps_func *ex_func;
asn1_ps_func *ex_free_func;
} BIO_ASN1_EX_FUNCS;
typedef struct BIO_ASN1_BUF_CTX_t
{
/* Internal state */
asn1_bio_state_t state;
/* Internal buffer */
unsigned char *buf;
/* Size of buffer */
int bufsize;
/* Current position in buffer */
int bufpos;
/* Current buffer length */
int buflen;
/* Amount of data to copy */
int copylen;
/* Class and tag to use */
int asn1_class, asn1_tag;
asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free;
/* Extra buffer for prefix and suffix data */
unsigned char *ex_buf;
int ex_len;
int ex_pos;
void *ex_arg;
} BIO_ASN1_BUF_CTX;
typedef struct BIO_ASN1_BUF_CTX_t {
/* Internal state */
asn1_bio_state_t state;
/* Internal buffer */
unsigned char *buf;
/* Size of buffer */
int bufsize;
/* Current position in buffer */
int bufpos;
/* Current buffer length */
int buflen;
/* Amount of data to copy */
int copylen;
/* Class and tag to use */
int asn1_class, asn1_tag;
asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free;
/* Extra buffer for prefix and suffix data */
unsigned char *ex_buf;
int ex_len;
int ex_pos;
void *ex_arg;
} BIO_ASN1_BUF_CTX;
static int asn1_bio_write(BIO *h, const char *buf,int num);
static int asn1_bio_write(BIO *h, const char *buf, int num);
static int asn1_bio_read(BIO *h, char *buf, int size);
static int asn1_bio_puts(BIO *h, const char *str);
static int asn1_bio_gets(BIO *h, char *str, int size);
@@ -119,378 +114,364 @@ static long asn1_bio_callback_ctrl(BIO *h, int cmd, bio_info_cb fp);
static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size);
static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
asn1_ps_func *cleanup, asn1_bio_state_t next);
asn1_ps_func *cleanup, asn1_bio_state_t next);
static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
asn1_ps_func *setup,
asn1_bio_state_t ex_state,
asn1_bio_state_t other_state);
asn1_ps_func *setup,
asn1_bio_state_t ex_state,
asn1_bio_state_t other_state);
static const BIO_METHOD methods_asn1=
{
BIO_TYPE_ASN1,
"asn1",
asn1_bio_write,
asn1_bio_read,
asn1_bio_puts,
asn1_bio_gets,
asn1_bio_ctrl,
asn1_bio_new,
asn1_bio_free,
asn1_bio_callback_ctrl,
};
static const BIO_METHOD methods_asn1 = {
BIO_TYPE_ASN1,
"asn1",
asn1_bio_write,
asn1_bio_read,
asn1_bio_puts,
asn1_bio_gets,
asn1_bio_ctrl,
asn1_bio_new,
asn1_bio_free,
asn1_bio_callback_ctrl,
};
const BIO_METHOD *BIO_f_asn1(void)
{
return(&methods_asn1);
}
{
return (&methods_asn1);
}
static int asn1_bio_new(BIO *b)
{
BIO_ASN1_BUF_CTX *ctx;
ctx = OPENSSL_malloc(sizeof(BIO_ASN1_BUF_CTX));
if (!ctx)
return 0;
if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE))
{
OPENSSL_free(ctx);
return 0;
}
b->init = 1;
b->ptr = (char *)ctx;
b->flags = 0;
return 1;
}
{
BIO_ASN1_BUF_CTX *ctx;
ctx = OPENSSL_malloc(sizeof(BIO_ASN1_BUF_CTX));
if (!ctx)
return 0;
if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE)) {
OPENSSL_free(ctx);
return 0;
}
b->init = 1;
b->ptr = (char *)ctx;
b->flags = 0;
return 1;
}
static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size)
{
ctx->buf = OPENSSL_malloc(size);
if (!ctx->buf)
return 0;
ctx->bufsize = size;
ctx->bufpos = 0;
ctx->buflen = 0;
ctx->copylen = 0;
ctx->asn1_class = V_ASN1_UNIVERSAL;
ctx->asn1_tag = V_ASN1_OCTET_STRING;
ctx->ex_buf = 0;
ctx->ex_pos = 0;
ctx->ex_len = 0;
ctx->state = ASN1_STATE_START;
return 1;
}
{
ctx->buf = OPENSSL_malloc(size);
if (!ctx->buf)
return 0;
ctx->bufsize = size;
ctx->bufpos = 0;
ctx->buflen = 0;
ctx->copylen = 0;
ctx->asn1_class = V_ASN1_UNIVERSAL;
ctx->asn1_tag = V_ASN1_OCTET_STRING;
ctx->ex_buf = 0;
ctx->ex_pos = 0;
ctx->ex_len = 0;
ctx->state = ASN1_STATE_START;
return 1;
}
static int asn1_bio_free(BIO *b)
{
BIO_ASN1_BUF_CTX *ctx;
ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
if (ctx == NULL)
return 0;
if (ctx->buf)
OPENSSL_free(ctx->buf);
OPENSSL_free(ctx);
b->init = 0;
b->ptr = NULL;
b->flags = 0;
return 1;
}
{
BIO_ASN1_BUF_CTX *ctx;
ctx = (BIO_ASN1_BUF_CTX *)b->ptr;
if (ctx == NULL)
return 0;
if (ctx->buf)
OPENSSL_free(ctx->buf);
OPENSSL_free(ctx);
b->init = 0;
b->ptr = NULL;
b->flags = 0;
return 1;
}
static int asn1_bio_write(BIO *b, const char *in , int inl)
{
BIO_ASN1_BUF_CTX *ctx;
int wrmax, wrlen, ret;
unsigned char *p;
if (!in || (inl < 0) || (b->next_bio == NULL))
return 0;
ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
if (ctx == NULL)
return 0;
static int asn1_bio_write(BIO *b, const char *in, int inl)
{
BIO_ASN1_BUF_CTX *ctx;
int wrmax, wrlen, ret;
unsigned char *p;
if (!in || (inl < 0) || (b->next_bio == NULL))
return 0;
ctx = (BIO_ASN1_BUF_CTX *)b->ptr;
if (ctx == NULL)
return 0;
wrlen = 0;
ret = -1;
wrlen = 0;
ret = -1;
for(;;)
{
switch (ctx->state)
{
for (;;) {
switch (ctx->state) {
/* Setup prefix data, call it */
case ASN1_STATE_START:
if (!asn1_bio_setup_ex(b, ctx, ctx->prefix,
ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER))
return 0;
break;
/* Setup prefix data, call it */
case ASN1_STATE_START:
if (!asn1_bio_setup_ex(b, ctx, ctx->prefix,
ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER))
return 0;
break;
/* Copy any pre data first */
case ASN1_STATE_PRE_COPY:
/* Copy any pre data first */
case ASN1_STATE_PRE_COPY:
ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free,
ASN1_STATE_HEADER);
ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free,
ASN1_STATE_HEADER);
if (ret <= 0)
goto done;
if (ret <= 0)
goto done;
break;
break;
case ASN1_STATE_HEADER:
ctx->buflen =
ASN1_object_size(0, inl, ctx->asn1_tag) - inl;
assert(ctx->buflen <= ctx->bufsize);
p = ctx->buf;
ASN1_put_object(&p, 0, inl,
ctx->asn1_tag, ctx->asn1_class);
ctx->copylen = inl;
ctx->state = ASN1_STATE_HEADER_COPY;
case ASN1_STATE_HEADER:
ctx->buflen = ASN1_object_size(0, inl, ctx->asn1_tag) - inl;
assert(ctx->buflen <= ctx->bufsize);
p = ctx->buf;
ASN1_put_object(&p, 0, inl, ctx->asn1_tag, ctx->asn1_class);
ctx->copylen = inl;
ctx->state = ASN1_STATE_HEADER_COPY;
break;
break;
case ASN1_STATE_HEADER_COPY:
ret = BIO_write(b->next_bio,
ctx->buf + ctx->bufpos, ctx->buflen);
if (ret <= 0)
goto done;
case ASN1_STATE_HEADER_COPY:
ret = BIO_write(b->next_bio, ctx->buf + ctx->bufpos, ctx->buflen);
if (ret <= 0)
goto done;
ctx->buflen -= ret;
if (ctx->buflen)
ctx->bufpos += ret;
else
{
ctx->bufpos = 0;
ctx->state = ASN1_STATE_DATA_COPY;
}
ctx->buflen -= ret;
if (ctx->buflen)
ctx->bufpos += ret;
else {
ctx->bufpos = 0;
ctx->state = ASN1_STATE_DATA_COPY;
}
break;
break;
case ASN1_STATE_DATA_COPY:
case ASN1_STATE_DATA_COPY:
if (inl > ctx->copylen)
wrmax = ctx->copylen;
else
wrmax = inl;
ret = BIO_write(b->next_bio, in, wrmax);
if (ret <= 0)
break;
wrlen += ret;
ctx->copylen -= ret;
in += ret;
inl -= ret;
if (inl > ctx->copylen)
wrmax = ctx->copylen;
else
wrmax = inl;
ret = BIO_write(b->next_bio, in, wrmax);
if (ret <= 0)
break;
wrlen += ret;
ctx->copylen -= ret;
in += ret;
inl -= ret;
if (ctx->copylen == 0)
ctx->state = ASN1_STATE_HEADER;
if (ctx->copylen == 0)
ctx->state = ASN1_STATE_HEADER;
if (inl == 0)
goto done;
if (inl == 0)
goto done;
break;
break;
default:
BIO_clear_retry_flags(b);
return 0;
default:
BIO_clear_retry_flags(b);
return 0;
}
}
}
}
done:
BIO_clear_retry_flags(b);
BIO_copy_next_retry(b);
done:
BIO_clear_retry_flags(b);
BIO_copy_next_retry(b);
return (wrlen > 0) ? wrlen : ret;
return (wrlen > 0) ? wrlen : ret;
}
}
static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
asn1_ps_func *cleanup, asn1_bio_state_t next)
{
int ret;
if (ctx->ex_len <= 0)
return 1;
for(;;)
{
ret = BIO_write(b->next_bio, ctx->ex_buf + ctx->ex_pos,
ctx->ex_len);
if (ret <= 0)
break;
ctx->ex_len -= ret;
if (ctx->ex_len > 0)
ctx->ex_pos += ret;
else
{
if(cleanup)
cleanup(b, &ctx->ex_buf, &ctx->ex_len,
&ctx->ex_arg);
ctx->state = next;
ctx->ex_pos = 0;
break;
}
}
return ret;
}
asn1_ps_func *cleanup, asn1_bio_state_t next)
{
int ret;
if (ctx->ex_len <= 0)
return 1;
for (;;) {
ret = BIO_write(b->next_bio, ctx->ex_buf + ctx->ex_pos, ctx->ex_len);
if (ret <= 0)
break;
ctx->ex_len -= ret;
if (ctx->ex_len > 0)
ctx->ex_pos += ret;
else {
if (cleanup)
cleanup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg);
ctx->state = next;
ctx->ex_pos = 0;
break;
}
}
return ret;
}
static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
asn1_ps_func *setup,
asn1_bio_state_t ex_state,
asn1_bio_state_t other_state)
{
if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg))
{
BIO_clear_retry_flags(b);
return 0;
}
if (ctx->ex_len > 0)
ctx->state = ex_state;
else
ctx->state = other_state;
return 1;
}
asn1_ps_func *setup,
asn1_bio_state_t ex_state,
asn1_bio_state_t other_state)
{
if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg)) {
BIO_clear_retry_flags(b);
return 0;
}
if (ctx->ex_len > 0)
ctx->state = ex_state;
else
ctx->state = other_state;
return 1;
}
static int asn1_bio_read(BIO *b, char *in , int inl)
{
if (!b->next_bio)
return 0;
return BIO_read(b->next_bio, in , inl);
}
static int asn1_bio_read(BIO *b, char *in, int inl)
{
if (!b->next_bio)
return 0;
return BIO_read(b->next_bio, in, inl);
}
static int asn1_bio_puts(BIO *b, const char *str)
{
return asn1_bio_write(b, str, strlen(str));
}
{
return asn1_bio_write(b, str, strlen(str));
}
static int asn1_bio_gets(BIO *b, char *str, int size)
{
if (!b->next_bio)
return 0;
return BIO_gets(b->next_bio, str , size);
}
{
if (!b->next_bio)
return 0;
return BIO_gets(b->next_bio, str, size);
}
static long asn1_bio_callback_ctrl(BIO *b, int cmd, bio_info_cb fp)
{
if (b->next_bio == NULL) return(0);
return BIO_callback_ctrl(b->next_bio,cmd,fp);
}
{
if (b->next_bio == NULL)
return (0);
return BIO_callback_ctrl(b->next_bio, cmd, fp);
}
static long asn1_bio_ctrl(BIO *b, int cmd, long arg1, void *arg2)
{
BIO_ASN1_BUF_CTX *ctx;
BIO_ASN1_EX_FUNCS *ex_func;
long ret = 1;
ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
if (ctx == NULL)
return 0;
switch(cmd)
{
{
BIO_ASN1_BUF_CTX *ctx;
BIO_ASN1_EX_FUNCS *ex_func;
long ret = 1;
ctx = (BIO_ASN1_BUF_CTX *)b->ptr;
if (ctx == NULL)
return 0;
switch (cmd) {
case BIO_C_SET_PREFIX:
ex_func = arg2;
ctx->prefix = ex_func->ex_func;
ctx->prefix_free = ex_func->ex_free_func;
break;
case BIO_C_SET_PREFIX:
ex_func = arg2;
ctx->prefix = ex_func->ex_func;
ctx->prefix_free = ex_func->ex_free_func;
break;
case BIO_C_GET_PREFIX:
ex_func = arg2;
ex_func->ex_func = ctx->prefix;
ex_func->ex_free_func = ctx->prefix_free;
break;
case BIO_C_GET_PREFIX:
ex_func = arg2;
ex_func->ex_func = ctx->prefix;
ex_func->ex_free_func = ctx->prefix_free;
break;
case BIO_C_SET_SUFFIX:
ex_func = arg2;
ctx->suffix = ex_func->ex_func;
ctx->suffix_free = ex_func->ex_free_func;
break;
case BIO_C_SET_SUFFIX:
ex_func = arg2;
ctx->suffix = ex_func->ex_func;
ctx->suffix_free = ex_func->ex_free_func;
break;
case BIO_C_GET_SUFFIX:
ex_func = arg2;
ex_func->ex_func = ctx->suffix;
ex_func->ex_free_func = ctx->suffix_free;
break;
case BIO_C_GET_SUFFIX:
ex_func = arg2;
ex_func->ex_func = ctx->suffix;
ex_func->ex_free_func = ctx->suffix_free;
break;
case BIO_C_SET_EX_ARG:
ctx->ex_arg = arg2;
break;
case BIO_C_SET_EX_ARG:
ctx->ex_arg = arg2;
break;
case BIO_C_GET_EX_ARG:
*(void **)arg2 = ctx->ex_arg;
break;
case BIO_C_GET_EX_ARG:
*(void **)arg2 = ctx->ex_arg;
break;
case BIO_CTRL_FLUSH:
if (!b->next_bio)
return 0;
case BIO_CTRL_FLUSH:
if (!b->next_bio)
return 0;
/* Call post function if possible */
if (ctx->state == ASN1_STATE_HEADER)
{
if (!asn1_bio_setup_ex(b, ctx, ctx->suffix,
ASN1_STATE_POST_COPY, ASN1_STATE_DONE))
return 0;
}
/* Call post function if possible */
if (ctx->state == ASN1_STATE_HEADER) {
if (!asn1_bio_setup_ex(b, ctx, ctx->suffix,
ASN1_STATE_POST_COPY, ASN1_STATE_DONE))
return 0;
}
if (ctx->state == ASN1_STATE_POST_COPY)
{
ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free,
ASN1_STATE_DONE);
if (ret <= 0)
return ret;
}
if (ctx->state == ASN1_STATE_POST_COPY) {
ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free,
ASN1_STATE_DONE);
if (ret <= 0)
return ret;
}
if (ctx->state == ASN1_STATE_DONE)
return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
else
{
BIO_clear_retry_flags(b);
return 0;
}
break;
if (ctx->state == ASN1_STATE_DONE)
return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
else {
BIO_clear_retry_flags(b);
return 0;
}
break;
default:
if (!b->next_bio)
return 0;
return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
default:
if (!b->next_bio)
return 0;
return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
}
}
return ret;
}
return ret;
}
static int asn1_bio_set_ex(BIO *b, int cmd,
asn1_ps_func *ex_func, asn1_ps_func *ex_free_func)
{
BIO_ASN1_EX_FUNCS extmp;
extmp.ex_func = ex_func;
extmp.ex_free_func = ex_free_func;
return BIO_ctrl(b, cmd, 0, &extmp);
}
asn1_ps_func *ex_func, asn1_ps_func *ex_free_func)
{
BIO_ASN1_EX_FUNCS extmp;
extmp.ex_func = ex_func;
extmp.ex_free_func = ex_free_func;
return BIO_ctrl(b, cmd, 0, &extmp);
}
static int asn1_bio_get_ex(BIO *b, int cmd,
asn1_ps_func **ex_func, asn1_ps_func **ex_free_func)
{
BIO_ASN1_EX_FUNCS extmp;
int ret;
ret = BIO_ctrl(b, cmd, 0, &extmp);
if (ret > 0)
{
*ex_func = extmp.ex_func;
*ex_free_func = extmp.ex_free_func;
}
return ret;
}
asn1_ps_func **ex_func,
asn1_ps_func **ex_free_func)
{
BIO_ASN1_EX_FUNCS extmp;
int ret;
ret = BIO_ctrl(b, cmd, 0, &extmp);
if (ret > 0) {
*ex_func = extmp.ex_func;
*ex_free_func = extmp.ex_free_func;
}
return ret;
}
int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, asn1_ps_func *prefix_free)
{
return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free);
}
int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix,
asn1_ps_func *prefix_free)
{
return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free);
}
int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, asn1_ps_func **pprefix_free)
{
return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free);
}
int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix,
asn1_ps_func **pprefix_free)
{
return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free);
}
int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, asn1_ps_func *suffix_free)
{
return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free);
}
int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix,
asn1_ps_func *suffix_free)
{
return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free);
}
int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, asn1_ps_func **psuffix_free)
{
return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free);
}
int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix,
asn1_ps_func **psuffix_free)
{
return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free);
}
+138 -141
View File
@@ -63,192 +63,189 @@
#include <openssl/err.h>
#include <openssl/mem.h>
/* Experimental NDEF ASN1 BIO support routines */
/* The usage is quite simple, initialize an ASN1 structure,
* get a BIO from it then any data written through the BIO
* will end up translated to approptiate format on the fly.
* The data is streamed out and does *not* need to be
* all held in memory at once.
*
* When the BIO is flushed the output is finalized and any
* signatures etc written out.
*
* The BIO is a 'proper' BIO and can handle non blocking I/O
* correctly.
*
* The usage is simple. The implementation is *not*...
/*
* The usage is quite simple, initialize an ASN1 structure, get a BIO from it
* then any data written through the BIO will end up translated to
* approptiate format on the fly. The data is streamed out and does *not*
* need to be all held in memory at once. When the BIO is flushed the output
* is finalized and any signatures etc written out. The BIO is a 'proper'
* BIO and can handle non blocking I/O correctly. The usage is simple. The
* implementation is *not*...
*/
/* BIO support data stored in the ASN1 BIO ex_arg */
typedef struct ndef_aux_st
{
/* ASN1 structure this BIO refers to */
ASN1_VALUE *val;
const ASN1_ITEM *it;
/* Top of the BIO chain */
BIO *ndef_bio;
/* Output BIO */
BIO *out;
/* Boundary where content is inserted */
unsigned char **boundary;
/* DER buffer start */
unsigned char *derbuf;
} NDEF_SUPPORT;
typedef struct ndef_aux_st {
/* ASN1 structure this BIO refers to */
ASN1_VALUE *val;
const ASN1_ITEM *it;
/* Top of the BIO chain */
BIO *ndef_bio;
/* Output BIO */
BIO *out;
/* Boundary where content is inserted */
unsigned char **boundary;
/* DER buffer start */
unsigned char *derbuf;
} NDEF_SUPPORT;
static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen,
void *parg);
static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen,
void *parg);
BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
{
NDEF_SUPPORT *ndef_aux = NULL;
BIO *asn_bio = NULL;
const ASN1_AUX *aux = it->funcs;
ASN1_STREAM_ARG sarg;
{
NDEF_SUPPORT *ndef_aux = NULL;
BIO *asn_bio = NULL;
const ASN1_AUX *aux = it->funcs;
ASN1_STREAM_ARG sarg;
if (!aux || !aux->asn1_cb)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_STREAMING_NOT_SUPPORTED);
return NULL;
}
ndef_aux = OPENSSL_malloc(sizeof(NDEF_SUPPORT));
asn_bio = BIO_new(BIO_f_asn1());
if (!aux || !aux->asn1_cb) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_STREAMING_NOT_SUPPORTED);
return NULL;
}
ndef_aux = OPENSSL_malloc(sizeof(NDEF_SUPPORT));
asn_bio = BIO_new(BIO_f_asn1());
/* ASN1 bio needs to be next to output BIO */
/* ASN1 bio needs to be next to output BIO */
out = BIO_push(asn_bio, out);
out = BIO_push(asn_bio, out);
if (!ndef_aux || !asn_bio || !out)
goto err;
if (!ndef_aux || !asn_bio || !out)
goto err;
BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free);
BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free);
/* Now let callback prepend any digest, cipher etc BIOs
* ASN1 structure needs.
*/
/*
* Now let callback prepend any digest, cipher etc BIOs ASN1 structure
* needs.
*/
sarg.out = out;
sarg.ndef_bio = NULL;
sarg.boundary = NULL;
sarg.out = out;
sarg.ndef_bio = NULL;
sarg.boundary = NULL;
if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0)
goto err;
if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0)
goto err;
ndef_aux->val = val;
ndef_aux->it = it;
ndef_aux->ndef_bio = sarg.ndef_bio;
ndef_aux->boundary = sarg.boundary;
ndef_aux->out = out;
ndef_aux->val = val;
ndef_aux->it = it;
ndef_aux->ndef_bio = sarg.ndef_bio;
ndef_aux->boundary = sarg.boundary;
ndef_aux->out = out;
BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);
BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);
return sarg.ndef_bio;
return sarg.ndef_bio;
err:
if (asn_bio)
BIO_free(asn_bio);
if (ndef_aux)
OPENSSL_free(ndef_aux);
return NULL;
}
err:
if (asn_bio)
BIO_free(asn_bio);
if (ndef_aux)
OPENSSL_free(ndef_aux);
return NULL;
}
static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
{
NDEF_SUPPORT *ndef_aux;
unsigned char *p;
int derlen;
{
NDEF_SUPPORT *ndef_aux;
unsigned char *p;
int derlen;
if (!parg)
return 0;
if (!parg)
return 0;
ndef_aux = *(NDEF_SUPPORT **)parg;
ndef_aux = *(NDEF_SUPPORT **)parg;
derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
p = OPENSSL_malloc(derlen);
if (p == NULL)
return 0;
derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
p = OPENSSL_malloc(derlen);
if (p == NULL)
return 0;
ndef_aux->derbuf = p;
*pbuf = p;
derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
ndef_aux->derbuf = p;
*pbuf = p;
derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
if (!*ndef_aux->boundary)
return 0;
if (!*ndef_aux->boundary)
return 0;
*plen = *ndef_aux->boundary - *pbuf;
*plen = *ndef_aux->boundary - *pbuf;
return 1;
}
return 1;
}
static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
{
NDEF_SUPPORT *ndef_aux;
static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen,
void *parg)
{
NDEF_SUPPORT *ndef_aux;
if (!parg)
return 0;
if (!parg)
return 0;
ndef_aux = *(NDEF_SUPPORT **)parg;
ndef_aux = *(NDEF_SUPPORT **)parg;
if (ndef_aux->derbuf)
OPENSSL_free(ndef_aux->derbuf);
if (ndef_aux->derbuf)
OPENSSL_free(ndef_aux->derbuf);
ndef_aux->derbuf = NULL;
*pbuf = NULL;
*plen = 0;
return 1;
}
ndef_aux->derbuf = NULL;
*pbuf = NULL;
*plen = 0;
return 1;
}
static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
{
NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg;
if (!ndef_prefix_free(b, pbuf, plen, parg))
return 0;
OPENSSL_free(*pndef_aux);
*pndef_aux = NULL;
return 1;
}
static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen,
void *parg)
{
NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg;
if (!ndef_prefix_free(b, pbuf, plen, parg))
return 0;
OPENSSL_free(*pndef_aux);
*pndef_aux = NULL;
return 1;
}
static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
{
NDEF_SUPPORT *ndef_aux;
unsigned char *p;
int derlen;
const ASN1_AUX *aux;
ASN1_STREAM_ARG sarg;
{
NDEF_SUPPORT *ndef_aux;
unsigned char *p;
int derlen;
const ASN1_AUX *aux;
ASN1_STREAM_ARG sarg;
if (!parg)
return 0;
if (!parg)
return 0;
ndef_aux = *(NDEF_SUPPORT **)parg;
ndef_aux = *(NDEF_SUPPORT **)parg;
aux = ndef_aux->it->funcs;
aux = ndef_aux->it->funcs;
/* Finalize structures */
sarg.ndef_bio = ndef_aux->ndef_bio;
sarg.out = ndef_aux->out;
sarg.boundary = ndef_aux->boundary;
if (aux->asn1_cb(ASN1_OP_STREAM_POST,
&ndef_aux->val, ndef_aux->it, &sarg) <= 0)
return 0;
/* Finalize structures */
sarg.ndef_bio = ndef_aux->ndef_bio;
sarg.out = ndef_aux->out;
sarg.boundary = ndef_aux->boundary;
if (aux->asn1_cb(ASN1_OP_STREAM_POST,
&ndef_aux->val, ndef_aux->it, &sarg) <= 0)
return 0;
derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
p = OPENSSL_malloc(derlen);
if (p == NULL)
return 0;
derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
p = OPENSSL_malloc(derlen);
if (p == NULL)
return 0;
ndef_aux->derbuf = p;
*pbuf = p;
derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
ndef_aux->derbuf = p;
*pbuf = p;
derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
if (!*ndef_aux->boundary)
return 0;
*pbuf = *ndef_aux->boundary;
*plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf);
if (!*ndef_aux->boundary)
return 0;
*pbuf = *ndef_aux->boundary;
*plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf);
return 1;
}
return 1;
}
+128 -134
View File
@@ -62,145 +62,139 @@
/* Based on a_int.c: equivalent ENUMERATED functions */
int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a)
{
int i,n=0;
static const char *h="0123456789ABCDEF";
char buf[2];
{
int i, n = 0;
static const char *h = "0123456789ABCDEF";
char buf[2];
if (a == NULL) return(0);
if (a == NULL)
return (0);
if (a->length == 0)
{
if (BIO_write(bp,"00",2) != 2) goto err;
n=2;
}
else
{
for (i=0; i<a->length; i++)
{
if ((i != 0) && (i%35 == 0))
{
if (BIO_write(bp,"\\\n",2) != 2) goto err;
n+=2;
}
buf[0]=h[((unsigned char)a->data[i]>>4)&0x0f];
buf[1]=h[((unsigned char)a->data[i] )&0x0f];
if (BIO_write(bp,buf,2) != 2) goto err;
n+=2;
}
}
return(n);
err:
return(-1);
}
if (a->length == 0) {
if (BIO_write(bp, "00", 2) != 2)
goto err;
n = 2;
} else {
for (i = 0; i < a->length; i++) {
if ((i != 0) && (i % 35 == 0)) {
if (BIO_write(bp, "\\\n", 2) != 2)
goto err;
n += 2;
}
buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
if (BIO_write(bp, buf, 2) != 2)
goto err;
n += 2;
}
}
return (n);
err:
return (-1);
}
int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
{
int ret=0;
int i,j,k,m,n,again,bufsize;
unsigned char *s=NULL,*sp;
unsigned char *bufp;
int num=0,slen=0,first=1;
{
int ret = 0;
int i, j, k, m, n, again, bufsize;
unsigned char *s = NULL, *sp;
unsigned char *bufp;
int num = 0, slen = 0, first = 1;
bs->type=V_ASN1_ENUMERATED;
bs->type = V_ASN1_ENUMERATED;
bufsize=BIO_gets(bp,buf,size);
for (;;)
{
if (bufsize < 1) goto err_sl;
i=bufsize;
if (buf[i-1] == '\n') buf[--i]='\0';
if (i == 0) goto err_sl;
if (buf[i-1] == '\r') buf[--i]='\0';
if (i == 0) goto err_sl;
again=(buf[i-1] == '\\');
bufsize = BIO_gets(bp, buf, size);
for (;;) {
if (bufsize < 1)
goto err_sl;
i = bufsize;
if (buf[i - 1] == '\n')
buf[--i] = '\0';
if (i == 0)
goto err_sl;
if (buf[i - 1] == '\r')
buf[--i] = '\0';
if (i == 0)
goto err_sl;
again = (buf[i - 1] == '\\');
for (j=0; j<i; j++)
{
if (!( ((buf[j] >= '0') && (buf[j] <= '9')) ||
((buf[j] >= 'a') && (buf[j] <= 'f')) ||
((buf[j] >= 'A') && (buf[j] <= 'F'))))
{
i=j;
break;
}
}
buf[i]='\0';
/* We have now cleared all the crap off the end of the
* line */
if (i < 2) goto err_sl;
bufp=(unsigned char *)buf;
if (first)
{
first=0;
if ((bufp[0] == '0') && (buf[1] == '0'))
{
bufp+=2;
i-=2;
}
}
k=0;
i-=again;
if (i%2 != 0)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
goto err;
}
i/=2;
if (num+i > slen)
{
if (s == NULL)
sp=(unsigned char *)OPENSSL_malloc(
(unsigned int)num+i*2);
else
sp=(unsigned char *)OPENSSL_realloc(s,
(unsigned int)num+i*2);
if (sp == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
s=sp;
slen=num+i*2;
}
for (j=0; j<i; j++,k+=2)
{
for (n=0; n<2; n++)
{
m=bufp[k+n];
if ((m >= '0') && (m <= '9'))
m-='0';
else if ((m >= 'a') && (m <= 'f'))
m=m-'a'+10;
else if ((m >= 'A') && (m <= 'F'))
m=m-'A'+10;
else
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
goto err;
}
s[num+j]<<=4;
s[num+j]|=m;
}
}
num+=i;
if (again)
bufsize=BIO_gets(bp,buf,size);
else
break;
}
bs->length=num;
bs->data=s;
ret=1;
err:
if (0)
{
err_sl:
OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
}
if (s != NULL)
OPENSSL_free(s);
return(ret);
}
for (j = 0; j < i; j++) {
if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
((buf[j] >= 'a') && (buf[j] <= 'f')) ||
((buf[j] >= 'A') && (buf[j] <= 'F')))) {
i = j;
break;
}
}
buf[i] = '\0';
/*
* We have now cleared all the crap off the end of the line
*/
if (i < 2)
goto err_sl;
bufp = (unsigned char *)buf;
if (first) {
first = 0;
if ((bufp[0] == '0') && (buf[1] == '0')) {
bufp += 2;
i -= 2;
}
}
k = 0;
i -= again;
if (i % 2 != 0) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
goto err;
}
i /= 2;
if (num + i > slen) {
if (s == NULL)
sp = (unsigned char *)OPENSSL_malloc((unsigned int)num +
i * 2);
else
sp = (unsigned char *)OPENSSL_realloc(s,
(unsigned int)num +
i * 2);
if (sp == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
s = sp;
slen = num + i * 2;
}
for (j = 0; j < i; j++, k += 2) {
for (n = 0; n < 2; n++) {
m = bufp[k + n];
if ((m >= '0') && (m <= '9'))
m -= '0';
else if ((m >= 'a') && (m <= 'f'))
m = m - 'a' + 10;
else if ((m >= 'A') && (m <= 'F'))
m = m - 'A' + 10;
else {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
goto err;
}
s[num + j] <<= 4;
s[num + j] |= m;
}
}
num += i;
if (again)
bufsize = BIO_gets(bp, buf, size);
else
break;
}
bs->length = num;
bs->data = s;
ret = 1;
err:
if (0) {
err_sl:
OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
}
if (s != NULL)
OPENSSL_free(s);
return (ret);
}
+131 -139
View File
@@ -59,152 +59,144 @@
#include <openssl/err.h>
#include <openssl/mem.h>
int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a)
{
int i,n=0;
static const char *h="0123456789ABCDEF";
char buf[2];
{
int i, n = 0;
static const char *h = "0123456789ABCDEF";
char buf[2];
if (a == NULL) return(0);
if (a == NULL)
return (0);
if (a->type & V_ASN1_NEG)
{
if (BIO_write(bp, "-", 1) != 1) goto err;
n = 1;
}
if (a->type & V_ASN1_NEG) {
if (BIO_write(bp, "-", 1) != 1)
goto err;
n = 1;
}
if (a->length == 0)
{
if (BIO_write(bp,"00",2) != 2) goto err;
n += 2;
}
else
{
for (i=0; i<a->length; i++)
{
if ((i != 0) && (i%35 == 0))
{
if (BIO_write(bp,"\\\n",2) != 2) goto err;
n+=2;
}
buf[0]=h[((unsigned char)a->data[i]>>4)&0x0f];
buf[1]=h[((unsigned char)a->data[i] )&0x0f];
if (BIO_write(bp,buf,2) != 2) goto err;
n+=2;
}
}
return(n);
err:
return(-1);
}
if (a->length == 0) {
if (BIO_write(bp, "00", 2) != 2)
goto err;
n += 2;
} else {
for (i = 0; i < a->length; i++) {
if ((i != 0) && (i % 35 == 0)) {
if (BIO_write(bp, "\\\n", 2) != 2)
goto err;
n += 2;
}
buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
if (BIO_write(bp, buf, 2) != 2)
goto err;
n += 2;
}
}
return (n);
err:
return (-1);
}
int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
{
int ret=0;
int i,j,k,m,n,again,bufsize;
unsigned char *s=NULL,*sp;
unsigned char *bufp;
int num=0,slen=0,first=1;
{
int ret = 0;
int i, j, k, m, n, again, bufsize;
unsigned char *s = NULL, *sp;
unsigned char *bufp;
int num = 0, slen = 0, first = 1;
bs->type=V_ASN1_INTEGER;
bs->type = V_ASN1_INTEGER;
bufsize=BIO_gets(bp,buf,size);
for (;;)
{
if (bufsize < 1) goto err_sl;
i=bufsize;
if (buf[i-1] == '\n') buf[--i]='\0';
if (i == 0) goto err_sl;
if (buf[i-1] == '\r') buf[--i]='\0';
if (i == 0) goto err_sl;
again=(buf[i-1] == '\\');
bufsize = BIO_gets(bp, buf, size);
for (;;) {
if (bufsize < 1)
goto err_sl;
i = bufsize;
if (buf[i - 1] == '\n')
buf[--i] = '\0';
if (i == 0)
goto err_sl;
if (buf[i - 1] == '\r')
buf[--i] = '\0';
if (i == 0)
goto err_sl;
again = (buf[i - 1] == '\\');
for (j=0; j<i; j++)
{
if (!( ((buf[j] >= '0') && (buf[j] <= '9')) ||
((buf[j] >= 'a') && (buf[j] <= 'f')) ||
((buf[j] >= 'A') && (buf[j] <= 'F'))))
{
i=j;
break;
}
}
buf[i]='\0';
/* We have now cleared all the crap off the end of the
* line */
if (i < 2) goto err_sl;
bufp=(unsigned char *)buf;
if (first)
{
first=0;
if ((bufp[0] == '0') && (buf[1] == '0'))
{
bufp+=2;
i-=2;
}
}
k=0;
i-=again;
if (i%2 != 0)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
goto err;
}
i/=2;
if (num+i > slen)
{
if (s == NULL)
sp=(unsigned char *)OPENSSL_malloc(
(unsigned int)num+i*2);
else
sp=OPENSSL_realloc_clean(s,slen,num+i*2);
if (sp == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
s=sp;
slen=num+i*2;
}
for (j=0; j<i; j++,k+=2)
{
for (n=0; n<2; n++)
{
m=bufp[k+n];
if ((m >= '0') && (m <= '9'))
m-='0';
else if ((m >= 'a') && (m <= 'f'))
m=m-'a'+10;
else if ((m >= 'A') && (m <= 'F'))
m=m-'A'+10;
else
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
goto err;
}
s[num+j]<<=4;
s[num+j]|=m;
}
}
num+=i;
if (again)
bufsize=BIO_gets(bp,buf,size);
else
break;
}
bs->length=num;
bs->data=s;
ret=1;
err:
if (0)
{
err_sl:
OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
}
if (s != NULL)
OPENSSL_free(s);
return(ret);
}
for (j = 0; j < i; j++) {
if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
((buf[j] >= 'a') && (buf[j] <= 'f')) ||
((buf[j] >= 'A') && (buf[j] <= 'F')))) {
i = j;
break;
}
}
buf[i] = '\0';
/*
* We have now cleared all the crap off the end of the line
*/
if (i < 2)
goto err_sl;
bufp = (unsigned char *)buf;
if (first) {
first = 0;
if ((bufp[0] == '0') && (buf[1] == '0')) {
bufp += 2;
i -= 2;
}
}
k = 0;
i -= again;
if (i % 2 != 0) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
goto err;
}
i /= 2;
if (num + i > slen) {
if (s == NULL)
sp = (unsigned char *)OPENSSL_malloc((unsigned int)num +
i * 2);
else
sp = OPENSSL_realloc_clean(s, slen, num + i * 2);
if (sp == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
s = sp;
slen = num + i * 2;
}
for (j = 0; j < i; j++, k += 2) {
for (n = 0; n < 2; n++) {
m = bufp[k + n];
if ((m >= '0') && (m <= '9'))
m -= '0';
else if ((m >= 'a') && (m <= 'f'))
m = m - 'a' + 10;
else if ((m >= 'A') && (m <= 'F'))
m = m - 'A' + 10;
else {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
goto err;
}
s[num + j] <<= 4;
s[num + j] |= m;
}
}
num += i;
if (again)
bufsize = BIO_gets(bp, buf, size);
else
break;
}
bs->length = num;
bs->data = s;
ret = 1;
err:
if (0) {
err_sl:
OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
}
if (s != NULL)
OPENSSL_free(s);
return (ret);
}
+125 -133
View File
@@ -59,146 +59,138 @@
#include <openssl/err.h>
#include <openssl/mem.h>
int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type)
{
int i,n=0;
static const char *h="0123456789ABCDEF";
char buf[2];
{
int i, n = 0;
static const char *h = "0123456789ABCDEF";
char buf[2];
if (a == NULL) return(0);
if (a == NULL)
return (0);
if (a->length == 0)
{
if (BIO_write(bp,"0",1) != 1) goto err;
n=1;
}
else
{
for (i=0; i<a->length; i++)
{
if ((i != 0) && (i%35 == 0))
{
if (BIO_write(bp,"\\\n",2) != 2) goto err;
n+=2;
}
buf[0]=h[((unsigned char)a->data[i]>>4)&0x0f];
buf[1]=h[((unsigned char)a->data[i] )&0x0f];
if (BIO_write(bp,buf,2) != 2) goto err;
n+=2;
}
}
return(n);
err:
return(-1);
}
if (a->length == 0) {
if (BIO_write(bp, "0", 1) != 1)
goto err;
n = 1;
} else {
for (i = 0; i < a->length; i++) {
if ((i != 0) && (i % 35 == 0)) {
if (BIO_write(bp, "\\\n", 2) != 2)
goto err;
n += 2;
}
buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
if (BIO_write(bp, buf, 2) != 2)
goto err;
n += 2;
}
}
return (n);
err:
return (-1);
}
int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
{
int ret=0;
int i,j,k,m,n,again,bufsize;
unsigned char *s=NULL,*sp;
unsigned char *bufp;
int num=0,slen=0,first=1;
{
int ret = 0;
int i, j, k, m, n, again, bufsize;
unsigned char *s = NULL, *sp;
unsigned char *bufp;
int num = 0, slen = 0, first = 1;
bufsize=BIO_gets(bp,buf,size);
for (;;)
{
if (bufsize < 1)
{
if (first)
break;
else
goto err_sl;
}
first=0;
bufsize = BIO_gets(bp, buf, size);
for (;;) {
if (bufsize < 1) {
if (first)
break;
else
goto err_sl;
}
first = 0;
i=bufsize;
if (buf[i-1] == '\n') buf[--i]='\0';
if (i == 0) goto err_sl;
if (buf[i-1] == '\r') buf[--i]='\0';
if (i == 0) goto err_sl;
again=(buf[i-1] == '\\');
i = bufsize;
if (buf[i - 1] == '\n')
buf[--i] = '\0';
if (i == 0)
goto err_sl;
if (buf[i - 1] == '\r')
buf[--i] = '\0';
if (i == 0)
goto err_sl;
again = (buf[i - 1] == '\\');
for (j=i-1; j>0; j--)
{
if (!( ((buf[j] >= '0') && (buf[j] <= '9')) ||
((buf[j] >= 'a') && (buf[j] <= 'f')) ||
((buf[j] >= 'A') && (buf[j] <= 'F'))))
{
i=j;
break;
}
}
buf[i]='\0';
/* We have now cleared all the crap off the end of the
* line */
if (i < 2) goto err_sl;
for (j = i - 1; j > 0; j--) {
if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
((buf[j] >= 'a') && (buf[j] <= 'f')) ||
((buf[j] >= 'A') && (buf[j] <= 'F')))) {
i = j;
break;
}
}
buf[i] = '\0';
/*
* We have now cleared all the crap off the end of the line
*/
if (i < 2)
goto err_sl;
bufp=(unsigned char *)buf;
k=0;
i-=again;
if (i%2 != 0)
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
goto err;
}
i/=2;
if (num+i > slen)
{
if (s == NULL)
sp=(unsigned char *)OPENSSL_malloc(
(unsigned int)num+i*2);
else
sp=(unsigned char *)OPENSSL_realloc(s,
(unsigned int)num+i*2);
if (sp == NULL)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
s=sp;
slen=num+i*2;
}
for (j=0; j<i; j++,k+=2)
{
for (n=0; n<2; n++)
{
m=bufp[k+n];
if ((m >= '0') && (m <= '9'))
m-='0';
else if ((m >= 'a') && (m <= 'f'))
m=m-'a'+10;
else if ((m >= 'A') && (m <= 'F'))
m=m-'A'+10;
else
{
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
goto err;
}
s[num+j]<<=4;
s[num+j]|=m;
}
}
num+=i;
if (again)
bufsize=BIO_gets(bp,buf,size);
else
break;
}
bs->length=num;
bs->data=s;
ret=1;
err:
if (0)
{
err_sl:
OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
}
if (s != NULL)
OPENSSL_free(s);
return(ret);
}
bufp = (unsigned char *)buf;
k = 0;
i -= again;
if (i % 2 != 0) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
goto err;
}
i /= 2;
if (num + i > slen) {
if (s == NULL)
sp = (unsigned char *)OPENSSL_malloc((unsigned int)num +
i * 2);
else
sp = (unsigned char *)OPENSSL_realloc(s,
(unsigned int)num +
i * 2);
if (sp == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
s = sp;
slen = num + i * 2;
}
for (j = 0; j < i; j++, k += 2) {
for (n = 0; n < 2; n++) {
m = bufp[k + n];
if ((m >= '0') && (m <= '9'))
m -= '0';
else if ((m >= 'a') && (m <= 'f'))
m = m - 'a' + 10;
else if ((m >= 'A') && (m <= 'F'))
m = m - 'A' + 10;
else {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
goto err;
}
s[num + j] <<= 4;
s[num + j] |= m;
}
}
num += i;
if (again)
bufsize = BIO_gets(bp, buf, size);
else
break;
}
bs->length = num;
bs->data = s;
ret = 1;
err:
if (0) {
err_sl:
OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
}
if (s != NULL)
OPENSSL_free(s);
return (ret);
}
+30 -29
View File
@@ -60,43 +60,44 @@
#include <openssl/mem.h>
int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
BIT_STRING_BITNAME *tbl, int indent)
BIT_STRING_BITNAME *tbl, int indent)
{
BIT_STRING_BITNAME *bnam;
char first = 1;
BIO_printf(out, "%*s", indent, "");
for(bnam = tbl; bnam->lname; bnam++) {
if(ASN1_BIT_STRING_get_bit(bs, bnam->bitnum)) {
if(!first) BIO_puts(out, ", ");
BIO_puts(out, bnam->lname);
first = 0;
}
}
BIO_puts(out, "\n");
return 1;
BIT_STRING_BITNAME *bnam;
char first = 1;
BIO_printf(out, "%*s", indent, "");
for (bnam = tbl; bnam->lname; bnam++) {
if (ASN1_BIT_STRING_get_bit(bs, bnam->bitnum)) {
if (!first)
BIO_puts(out, ", ");
BIO_puts(out, bnam->lname);
first = 0;
}
}
BIO_puts(out, "\n");
return 1;
}
int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value,
BIT_STRING_BITNAME *tbl)
BIT_STRING_BITNAME *tbl)
{
int bitnum;
bitnum = ASN1_BIT_STRING_num_asc(name, tbl);
if(bitnum < 0) return 0;
if(bs) {
if(!ASN1_BIT_STRING_set_bit(bs, bitnum, value))
return 0;
}
return 1;
int bitnum;
bitnum = ASN1_BIT_STRING_num_asc(name, tbl);
if (bitnum < 0)
return 0;
if (bs) {
if (!ASN1_BIT_STRING_set_bit(bs, bitnum, value))
return 0;
}
return 1;
}
int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl)
{
BIT_STRING_BITNAME *bnam;
for(bnam = tbl; bnam->lname; bnam++) {
if(!strcmp(bnam->sname, name) ||
!strcmp(bnam->lname, name) ) return bnam->bitnum;
}
return -1;
BIT_STRING_BITNAME *bnam;
for (bnam = tbl; bnam->lname; bnam++) {
if (!strcmp(bnam->sname, name) || !strcmp(bnam->lname, name))
return bnam->bitnum;
}
return -1;
}
+1029 -1148
View File
File diff suppressed because it is too large Load Diff
+508 -544
View File
File diff suppressed because it is too large Load Diff
+162 -180
View File
@@ -59,206 +59,188 @@
#include <openssl/asn1t.h>
#include <openssl/mem.h>
static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine);
static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
int combine);
/* Free up an ASN1 structure */
void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it)
{
asn1_item_combine_free(&val, it, 0);
}
{
asn1_item_combine_free(&val, it, 0);
}
void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
asn1_item_combine_free(pval, it, 0);
}
{
asn1_item_combine_free(pval, it, 0);
}
static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
{
const ASN1_TEMPLATE *tt = NULL, *seqtt;
const ASN1_EXTERN_FUNCS *ef;
const ASN1_COMPAT_FUNCS *cf;
const ASN1_AUX *aux = it->funcs;
ASN1_aux_cb *asn1_cb;
int i;
if (!pval)
return;
if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
return;
if (aux && aux->asn1_cb)
asn1_cb = aux->asn1_cb;
else
asn1_cb = 0;
static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
int combine)
{
const ASN1_TEMPLATE *tt = NULL, *seqtt;
const ASN1_EXTERN_FUNCS *ef;
const ASN1_COMPAT_FUNCS *cf;
const ASN1_AUX *aux = it->funcs;
ASN1_aux_cb *asn1_cb;
int i;
if (!pval)
return;
if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
return;
if (aux && aux->asn1_cb)
asn1_cb = aux->asn1_cb;
else
asn1_cb = 0;
switch(it->itype)
{
switch (it->itype) {
case ASN1_ITYPE_PRIMITIVE:
if (it->templates)
ASN1_template_free(pval, it->templates);
else
ASN1_primitive_free(pval, it);
break;
case ASN1_ITYPE_PRIMITIVE:
if (it->templates)
ASN1_template_free(pval, it->templates);
else
ASN1_primitive_free(pval, it);
break;
case ASN1_ITYPE_MSTRING:
ASN1_primitive_free(pval, it);
break;
case ASN1_ITYPE_MSTRING:
ASN1_primitive_free(pval, it);
break;
case ASN1_ITYPE_CHOICE:
if (asn1_cb)
{
i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
if (i == 2)
return;
}
i = asn1_get_choice_selector(pval, it);
if ((i >= 0) && (i < it->tcount))
{
ASN1_VALUE **pchval;
tt = it->templates + i;
pchval = asn1_get_field_ptr(pval, tt);
ASN1_template_free(pchval, tt);
}
if (asn1_cb)
asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
if (!combine)
{
OPENSSL_free(*pval);
*pval = NULL;
}
break;
case ASN1_ITYPE_CHOICE:
if (asn1_cb) {
i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
if (i == 2)
return;
}
i = asn1_get_choice_selector(pval, it);
if ((i >= 0) && (i < it->tcount)) {
ASN1_VALUE **pchval;
tt = it->templates + i;
pchval = asn1_get_field_ptr(pval, tt);
ASN1_template_free(pchval, tt);
}
if (asn1_cb)
asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
if (!combine) {
OPENSSL_free(*pval);
*pval = NULL;
}
break;
case ASN1_ITYPE_COMPAT:
cf = it->funcs;
if (cf && cf->asn1_free)
cf->asn1_free(*pval);
break;
case ASN1_ITYPE_COMPAT:
cf = it->funcs;
if (cf && cf->asn1_free)
cf->asn1_free(*pval);
break;
case ASN1_ITYPE_EXTERN:
ef = it->funcs;
if (ef && ef->asn1_ex_free)
ef->asn1_ex_free(pval, it);
break;
case ASN1_ITYPE_EXTERN:
ef = it->funcs;
if (ef && ef->asn1_ex_free)
ef->asn1_ex_free(pval, it);
break;
case ASN1_ITYPE_NDEF_SEQUENCE:
case ASN1_ITYPE_SEQUENCE:
if (!asn1_refcount_dec_and_test_zero(pval, it))
return;
if (asn1_cb)
{
i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
if (i == 2)
return;
}
asn1_enc_free(pval, it);
/* If we free up as normal we will invalidate any
* ANY DEFINED BY field and we wont be able to
* determine the type of the field it defines. So
* free up in reverse order.
*/
tt = it->templates + it->tcount - 1;
for (i = 0; i < it->tcount; tt--, i++)
{
ASN1_VALUE **pseqval;
seqtt = asn1_do_adb(pval, tt, 0);
if (!seqtt)
continue;
pseqval = asn1_get_field_ptr(pval, seqtt);
ASN1_template_free(pseqval, seqtt);
}
if (asn1_cb)
asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
if (!combine)
{
OPENSSL_free(*pval);
*pval = NULL;
}
break;
}
}
case ASN1_ITYPE_NDEF_SEQUENCE:
case ASN1_ITYPE_SEQUENCE:
if (!asn1_refcount_dec_and_test_zero(pval, it))
return;
if (asn1_cb) {
i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
if (i == 2)
return;
}
asn1_enc_free(pval, it);
/*
* If we free up as normal we will invalidate any ANY DEFINED BY
* field and we wont be able to determine the type of the field it
* defines. So free up in reverse order.
*/
tt = it->templates + it->tcount - 1;
for (i = 0; i < it->tcount; tt--, i++) {
ASN1_VALUE **pseqval;
seqtt = asn1_do_adb(pval, tt, 0);
if (!seqtt)
continue;
pseqval = asn1_get_field_ptr(pval, seqtt);
ASN1_template_free(pseqval, seqtt);
}
if (asn1_cb)
asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
if (!combine) {
OPENSSL_free(*pval);
*pval = NULL;
}
break;
}
}
void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
{
size_t i;
if (tt->flags & ASN1_TFLG_SK_MASK)
{
STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
for (i = 0; i < sk_ASN1_VALUE_num(sk); i++)
{
ASN1_VALUE *vtmp;
vtmp = sk_ASN1_VALUE_value(sk, i);
asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item),
0);
}
sk_ASN1_VALUE_free(sk);
*pval = NULL;
}
else
asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item),
tt->flags & ASN1_TFLG_COMBINE);
}
{
size_t i;
if (tt->flags & ASN1_TFLG_SK_MASK) {
STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
ASN1_VALUE *vtmp;
vtmp = sk_ASN1_VALUE_value(sk, i);
asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item), 0);
}
sk_ASN1_VALUE_free(sk);
*pval = NULL;
} else
asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item),
tt->flags & ASN1_TFLG_COMBINE);
}
void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
int utype;
if (it)
{
const ASN1_PRIMITIVE_FUNCS *pf;
pf = it->funcs;
if (pf && pf->prim_free)
{
pf->prim_free(pval, it);
return;
}
}
/* Special case: if 'it' is NULL free contents of ASN1_TYPE */
if (!it)
{
ASN1_TYPE *typ = (ASN1_TYPE *)*pval;
utype = typ->type;
pval = &typ->value.asn1_value;
if (!*pval)
return;
}
else if (it->itype == ASN1_ITYPE_MSTRING)
{
utype = -1;
if (!*pval)
return;
}
else
{
utype = it->utype;
if ((utype != V_ASN1_BOOLEAN) && !*pval)
return;
}
{
int utype;
if (it) {
const ASN1_PRIMITIVE_FUNCS *pf;
pf = it->funcs;
if (pf && pf->prim_free) {
pf->prim_free(pval, it);
return;
}
}
/* Special case: if 'it' is NULL free contents of ASN1_TYPE */
if (!it) {
ASN1_TYPE *typ = (ASN1_TYPE *)*pval;
utype = typ->type;
pval = &typ->value.asn1_value;
if (!*pval)
return;
} else if (it->itype == ASN1_ITYPE_MSTRING) {
utype = -1;
if (!*pval)
return;
} else {
utype = it->utype;
if ((utype != V_ASN1_BOOLEAN) && !*pval)
return;
}
switch(utype)
{
case V_ASN1_OBJECT:
ASN1_OBJECT_free((ASN1_OBJECT *)*pval);
break;
switch (utype) {
case V_ASN1_OBJECT:
ASN1_OBJECT_free((ASN1_OBJECT *)*pval);
break;
case V_ASN1_BOOLEAN:
if (it)
*(ASN1_BOOLEAN *)pval = it->size;
else
*(ASN1_BOOLEAN *)pval = -1;
return;
case V_ASN1_BOOLEAN:
if (it)
*(ASN1_BOOLEAN *)pval = it->size;
else
*(ASN1_BOOLEAN *)pval = -1;
return;
case V_ASN1_NULL:
break;
case V_ASN1_NULL:
break;
case V_ASN1_ANY:
ASN1_primitive_free(pval, NULL);
OPENSSL_free(*pval);
break;
case V_ASN1_ANY:
ASN1_primitive_free(pval, NULL);
OPENSSL_free(*pval);
break;
default:
ASN1_STRING_free((ASN1_STRING *)*pval);
*pval = NULL;
break;
}
*pval = NULL;
}
default:
ASN1_STRING_free((ASN1_STRING *)*pval);
*pval = NULL;
break;
}
*pval = NULL;
}
+251 -268
View File
@@ -63,336 +63,319 @@
#include <openssl/mem.h>
#include <openssl/obj.h>
static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
int combine);
int combine);
static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it)
{
ASN1_VALUE *ret = NULL;
if (ASN1_item_ex_new(&ret, it) > 0)
return ret;
return NULL;
}
{
ASN1_VALUE *ret = NULL;
if (ASN1_item_ex_new(&ret, it) > 0)
return ret;
return NULL;
}
/* Allocate an ASN1 structure */
int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
return asn1_item_ex_combine_new(pval, it, 0);
}
{
return asn1_item_ex_combine_new(pval, it, 0);
}
static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
int combine)
{
const ASN1_TEMPLATE *tt = NULL;
const ASN1_COMPAT_FUNCS *cf;
const ASN1_EXTERN_FUNCS *ef;
const ASN1_AUX *aux = it->funcs;
ASN1_aux_cb *asn1_cb;
ASN1_VALUE **pseqval;
int i;
if (aux && aux->asn1_cb)
asn1_cb = aux->asn1_cb;
else
asn1_cb = 0;
int combine)
{
const ASN1_TEMPLATE *tt = NULL;
const ASN1_COMPAT_FUNCS *cf;
const ASN1_EXTERN_FUNCS *ef;
const ASN1_AUX *aux = it->funcs;
ASN1_aux_cb *asn1_cb;
ASN1_VALUE **pseqval;
int i;
if (aux && aux->asn1_cb)
asn1_cb = aux->asn1_cb;
else
asn1_cb = 0;
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_push_info(it->sname);
if (it->sname)
CRYPTO_push_info(it->sname);
#endif
switch(it->itype)
{
switch (it->itype) {
case ASN1_ITYPE_EXTERN:
ef = it->funcs;
if (ef && ef->asn1_ex_new)
{
if (!ef->asn1_ex_new(pval, it))
goto memerr;
}
break;
case ASN1_ITYPE_EXTERN:
ef = it->funcs;
if (ef && ef->asn1_ex_new) {
if (!ef->asn1_ex_new(pval, it))
goto memerr;
}
break;
case ASN1_ITYPE_COMPAT:
cf = it->funcs;
if (cf && cf->asn1_new) {
*pval = cf->asn1_new();
if (!*pval)
goto memerr;
}
break;
case ASN1_ITYPE_COMPAT:
cf = it->funcs;
if (cf && cf->asn1_new) {
*pval = cf->asn1_new();
if (!*pval)
goto memerr;
}
break;
case ASN1_ITYPE_PRIMITIVE:
if (it->templates)
{
if (!ASN1_template_new(pval, it->templates))
goto memerr;
}
else if (!ASN1_primitive_new(pval, it))
goto memerr;
break;
case ASN1_ITYPE_PRIMITIVE:
if (it->templates) {
if (!ASN1_template_new(pval, it->templates))
goto memerr;
} else if (!ASN1_primitive_new(pval, it))
goto memerr;
break;
case ASN1_ITYPE_MSTRING:
if (!ASN1_primitive_new(pval, it))
goto memerr;
break;
case ASN1_ITYPE_MSTRING:
if (!ASN1_primitive_new(pval, it))
goto memerr;
break;
case ASN1_ITYPE_CHOICE:
if (asn1_cb)
{
i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
if (!i)
goto auxerr;
if (i==2)
{
case ASN1_ITYPE_CHOICE:
if (asn1_cb) {
i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
if (!i)
goto auxerr;
if (i == 2) {
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_pop_info();
if (it->sname)
CRYPTO_pop_info();
#endif
return 1;
}
}
if (!combine)
{
*pval = OPENSSL_malloc(it->size);
if (!*pval)
goto memerr;
memset(*pval, 0, it->size);
}
asn1_set_choice_selector(pval, -1, it);
if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
goto auxerr;
break;
return 1;
}
}
if (!combine) {
*pval = OPENSSL_malloc(it->size);
if (!*pval)
goto memerr;
memset(*pval, 0, it->size);
}
asn1_set_choice_selector(pval, -1, it);
if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
goto auxerr;
break;
case ASN1_ITYPE_NDEF_SEQUENCE:
case ASN1_ITYPE_SEQUENCE:
if (asn1_cb)
{
i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
if (!i)
goto auxerr;
if (i==2)
{
case ASN1_ITYPE_NDEF_SEQUENCE:
case ASN1_ITYPE_SEQUENCE:
if (asn1_cb) {
i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
if (!i)
goto auxerr;
if (i == 2) {
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_pop_info();
if (it->sname)
CRYPTO_pop_info();
#endif
return 1;
}
}
if (!combine)
{
*pval = OPENSSL_malloc(it->size);
if (!*pval)
goto memerr;
memset(*pval, 0, it->size);
asn1_refcount_set_one(pval, it);
asn1_enc_init(pval, it);
}
for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
{
pseqval = asn1_get_field_ptr(pval, tt);
if (!ASN1_template_new(pseqval, tt))
goto memerr;
}
if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
goto auxerr;
break;
}
return 1;
}
}
if (!combine) {
*pval = OPENSSL_malloc(it->size);
if (!*pval)
goto memerr;
memset(*pval, 0, it->size);
asn1_refcount_set_one(pval, it);
asn1_enc_init(pval, it);
}
for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
pseqval = asn1_get_field_ptr(pval, tt);
if (!ASN1_template_new(pseqval, tt))
goto memerr;
}
if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
goto auxerr;
break;
}
#ifdef CRYPTO_MDEBUG
if (it->sname) CRYPTO_pop_info();
if (it->sname)
CRYPTO_pop_info();
#endif
return 1;
return 1;
memerr:
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
ASN1_item_ex_free(pval, it);
memerr:
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
ASN1_item_ex_free(pval, it);
#ifdef CRYPTO_MDEBUG
if (it->sname) CRYPTO_pop_info();
if (it->sname)
CRYPTO_pop_info();
#endif
return 0;
return 0;
auxerr:
OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
ASN1_item_ex_free(pval, it);
auxerr:
OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
ASN1_item_ex_free(pval, it);
#ifdef CRYPTO_MDEBUG
if (it->sname) CRYPTO_pop_info();
if (it->sname)
CRYPTO_pop_info();
#endif
return 0;
return 0;
}
}
static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
const ASN1_EXTERN_FUNCS *ef;
{
const ASN1_EXTERN_FUNCS *ef;
switch(it->itype)
{
switch (it->itype) {
case ASN1_ITYPE_EXTERN:
ef = it->funcs;
if (ef && ef->asn1_ex_clear)
ef->asn1_ex_clear(pval, it);
else *pval = NULL;
break;
case ASN1_ITYPE_EXTERN:
ef = it->funcs;
if (ef && ef->asn1_ex_clear)
ef->asn1_ex_clear(pval, it);
else
*pval = NULL;
break;
case ASN1_ITYPE_PRIMITIVE:
if (it->templates)
asn1_template_clear(pval, it->templates);
else
asn1_primitive_clear(pval, it);
break;
case ASN1_ITYPE_PRIMITIVE:
if (it->templates)
asn1_template_clear(pval, it->templates);
else
asn1_primitive_clear(pval, it);
break;
case ASN1_ITYPE_MSTRING:
asn1_primitive_clear(pval, it);
break;
case ASN1_ITYPE_COMPAT:
case ASN1_ITYPE_CHOICE:
case ASN1_ITYPE_SEQUENCE:
case ASN1_ITYPE_NDEF_SEQUENCE:
*pval = NULL;
break;
}
}
case ASN1_ITYPE_MSTRING:
asn1_primitive_clear(pval, it);
break;
case ASN1_ITYPE_COMPAT:
case ASN1_ITYPE_CHOICE:
case ASN1_ITYPE_SEQUENCE:
case ASN1_ITYPE_NDEF_SEQUENCE:
*pval = NULL;
break;
}
}
int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
{
const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
int ret;
if (tt->flags & ASN1_TFLG_OPTIONAL)
{
asn1_template_clear(pval, tt);
return 1;
}
/* If ANY DEFINED BY nothing to do */
{
const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
int ret;
if (tt->flags & ASN1_TFLG_OPTIONAL) {
asn1_template_clear(pval, tt);
return 1;
}
/* If ANY DEFINED BY nothing to do */
if (tt->flags & ASN1_TFLG_ADB_MASK)
{
*pval = NULL;
return 1;
}
if (tt->flags & ASN1_TFLG_ADB_MASK) {
*pval = NULL;
return 1;
}
#ifdef CRYPTO_MDEBUG
if (tt->field_name)
CRYPTO_push_info(tt->field_name);
if (tt->field_name)
CRYPTO_push_info(tt->field_name);
#endif
/* If SET OF or SEQUENCE OF, its a STACK */
if (tt->flags & ASN1_TFLG_SK_MASK)
{
STACK_OF(ASN1_VALUE) *skval;
skval = sk_ASN1_VALUE_new_null();
if (!skval)
{
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
ret = 0;
goto done;
}
*pval = (ASN1_VALUE *)skval;
ret = 1;
goto done;
}
/* Otherwise pass it back to the item routine */
ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE);
done:
/* If SET OF or SEQUENCE OF, its a STACK */
if (tt->flags & ASN1_TFLG_SK_MASK) {
STACK_OF(ASN1_VALUE) *skval;
skval = sk_ASN1_VALUE_new_null();
if (!skval) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
ret = 0;
goto done;
}
*pval = (ASN1_VALUE *)skval;
ret = 1;
goto done;
}
/* Otherwise pass it back to the item routine */
ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE);
done:
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_pop_info();
if (it->sname)
CRYPTO_pop_info();
#endif
return ret;
}
return ret;
}
static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
{
/* If ADB or STACK just NULL the field */
if (tt->flags & (ASN1_TFLG_ADB_MASK|ASN1_TFLG_SK_MASK))
*pval = NULL;
else
asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item));
}
{
/* If ADB or STACK just NULL the field */
if (tt->flags & (ASN1_TFLG_ADB_MASK | ASN1_TFLG_SK_MASK))
*pval = NULL;
else
asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item));
}
/* NB: could probably combine most of the real XXX_new() behaviour and junk
/*
* NB: could probably combine most of the real XXX_new() behaviour and junk
* all the old functions.
*/
int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
ASN1_TYPE *typ;
ASN1_STRING *str;
int utype;
{
ASN1_TYPE *typ;
ASN1_STRING *str;
int utype;
if (!it)
return 0;
if (!it)
return 0;
if (it->funcs)
{
const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
if (pf->prim_new)
return pf->prim_new(pval, it);
}
if (it->funcs) {
const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
if (pf->prim_new)
return pf->prim_new(pval, it);
}
if (it->itype == ASN1_ITYPE_MSTRING)
utype = -1;
else
utype = it->utype;
switch(utype)
{
case V_ASN1_OBJECT:
*pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
return 1;
if (it->itype == ASN1_ITYPE_MSTRING)
utype = -1;
else
utype = it->utype;
switch (utype) {
case V_ASN1_OBJECT:
*pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
return 1;
case V_ASN1_BOOLEAN:
*(ASN1_BOOLEAN *)pval = it->size;
return 1;
case V_ASN1_BOOLEAN:
*(ASN1_BOOLEAN *)pval = it->size;
return 1;
case V_ASN1_NULL:
*pval = (ASN1_VALUE *)1;
return 1;
case V_ASN1_NULL:
*pval = (ASN1_VALUE *)1;
return 1;
case V_ASN1_ANY:
typ = OPENSSL_malloc(sizeof(ASN1_TYPE));
if (!typ)
return 0;
typ->value.ptr = NULL;
typ->type = -1;
*pval = (ASN1_VALUE *)typ;
break;
case V_ASN1_ANY:
typ = OPENSSL_malloc(sizeof(ASN1_TYPE));
if (!typ)
return 0;
typ->value.ptr = NULL;
typ->type = -1;
*pval = (ASN1_VALUE *)typ;
break;
default:
str = ASN1_STRING_type_new(utype);
if (it->itype == ASN1_ITYPE_MSTRING && str)
str->flags |= ASN1_STRING_FLAG_MSTRING;
*pval = (ASN1_VALUE *)str;
break;
}
if (*pval)
return 1;
return 0;
}
default:
str = ASN1_STRING_type_new(utype);
if (it->itype == ASN1_ITYPE_MSTRING && str)
str->flags |= ASN1_STRING_FLAG_MSTRING;
*pval = (ASN1_VALUE *)str;
break;
}
if (*pval)
return 1;
return 0;
}
static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
int utype;
if (it && it->funcs)
{
const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
if (pf->prim_clear)
pf->prim_clear(pval, it);
else
*pval = NULL;
return;
}
if (!it || (it->itype == ASN1_ITYPE_MSTRING))
utype = -1;
else
utype = it->utype;
if (utype == V_ASN1_BOOLEAN)
*(ASN1_BOOLEAN *)pval = it->size;
else *pval = NULL;
}
{
int utype;
if (it && it->funcs) {
const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
if (pf->prim_clear)
pf->prim_clear(pval, it);
else
*pval = NULL;
return;
}
if (!it || (it->itype == ASN1_ITYPE_MSTRING))
utype = -1;
else
utype = it->utype;
if (utype == V_ASN1_BOOLEAN)
*(ASN1_BOOLEAN *)pval = it->size;
else
*pval = NULL;
}
+437 -483
View File
File diff suppressed because it is too large Load Diff
+28 -21
View File
@@ -58,20 +58,19 @@
#include <openssl/asn1t.h>
/* Declarations for string types */
#define IMPLEMENT_ASN1_STRING_FUNCTIONS(sname) \
IMPLEMENT_ASN1_TYPE(sname) \
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(sname, sname, sname) \
sname *sname##_new(void) \
{ \
return ASN1_STRING_type_new(V_##sname); \
} \
void sname##_free(sname *x) \
{ \
ASN1_STRING_free(x); \
}
IMPLEMENT_ASN1_TYPE(sname) \
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(sname, sname, sname) \
sname *sname##_new(void) \
{ \
return ASN1_STRING_type_new(V_##sname); \
} \
void sname##_free(sname *x) \
{ \
ASN1_STRING_free(x); \
}
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_OCTET_STRING)
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_INTEGER)
@@ -95,12 +94,16 @@ IMPLEMENT_ASN1_TYPE(ASN1_OBJECT);
IMPLEMENT_ASN1_TYPE(ASN1_ANY);
/* Just swallow an ASN1_SEQUENCE in an ASN1_STRING */;
/*
* Just swallow an ASN1_SEQUENCE in an ASN1_STRING
*/ ;
IMPLEMENT_ASN1_TYPE(ASN1_SEQUENCE);
IMPLEMENT_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE);
/* Multistring types */;
/*
* Multistring types
*/ ;
IMPLEMENT_ASN1_MSTRING(ASN1_PRINTABLE, B_ASN1_PRINTABLE);
IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE);
@@ -111,18 +114,23 @@ IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT);
IMPLEMENT_ASN1_MSTRING(DIRECTORYSTRING, B_ASN1_DIRECTORYSTRING);
IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING);
/* Three separate BOOLEAN type: normal, DEFAULT TRUE and DEFAULT FALSE */;
/*
* Three separate BOOLEAN type: normal, DEFAULT TRUE and DEFAULT FALSE
*/ ;
IMPLEMENT_ASN1_TYPE_ex(ASN1_BOOLEAN, ASN1_BOOLEAN, -1);
IMPLEMENT_ASN1_TYPE_ex(ASN1_TBOOLEAN, ASN1_BOOLEAN, 1);
IMPLEMENT_ASN1_TYPE_ex(ASN1_FBOOLEAN, ASN1_BOOLEAN, 0);
/* Special, OCTET STRING with indefinite length constructed support */;
/*
* Special, OCTET STRING with indefinite length constructed support
*/ ;
IMPLEMENT_ASN1_TYPE_ex(ASN1_OCTET_STRING_NDEF, ASN1_OCTET_STRING,
ASN1_TFLG_NDEF);
ASN1_TFLG_NDEF);
ASN1_ITEM_TEMPLATE(ASN1_SEQUENCE_ANY) = ASN1_EX_TEMPLATE_TYPE(
ASN1_TFLG_SEQUENCE_OF, 0, ASN1_SEQUENCE_ANY, ASN1_ANY);
ASN1_ITEM_TEMPLATE(ASN1_SEQUENCE_ANY) =
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, ASN1_SEQUENCE_ANY,
ASN1_ANY);
ASN1_ITEM_TEMPLATE_END(ASN1_SEQUENCE_ANY);
ASN1_ITEM_TEMPLATE(ASN1_SET_ANY) = ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0,
@@ -131,7 +139,6 @@ ASN1_ITEM_TEMPLATE(ASN1_SET_ANY) = ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0,
ASN1_ITEM_TEMPLATE_END(ASN1_SET_ANY);
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY,
ASN1_SEQUENCE_ANY,
ASN1_SEQUENCE_ANY);
ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY);
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SET_ANY,
ASN1_SET_ANY);
ASN1_SET_ANY);
+62 -51
View File
@@ -59,84 +59,95 @@
#include <openssl/asn1t.h>
#include <openssl/bn.h>
/* Custom primitive type for BIGNUM handling. This reads in an ASN1_INTEGER as a
* BIGNUM directly. Currently it ignores the sign which isn't a problem since all
* BIGNUMs used are non negative and anything that looks negative is normally due
* to an encoding error.
/*
* Custom primitive type for BIGNUM handling. This reads in an ASN1_INTEGER
* as a BIGNUM directly. Currently it ignores the sign which isn't a problem
* since all BIGNUMs used are non negative and anything that looks negative
* is normally due to an encoding error.
*/
#define BN_SENSITIVE 1
#define BN_SENSITIVE 1
static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
const ASN1_ITEM *it);
static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
int utype, char *free_cont, const ASN1_ITEM *it);
static const ASN1_PRIMITIVE_FUNCS bignum_pf = {
NULL, 0,
bn_new,
bn_free,
0,
bn_c2i,
bn_i2c
NULL, 0,
bn_new,
bn_free,
0,
bn_c2i,
bn_i2c,
NULL /* prim_print */ ,
};
ASN1_ITEM_start(BIGNUM)
ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, 0, "BIGNUM"
ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, 0, "BIGNUM"
ASN1_ITEM_end(BIGNUM)
ASN1_ITEM_start(CBIGNUM)
ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, BN_SENSITIVE, "BIGNUM"
ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, BN_SENSITIVE, "BIGNUM"
ASN1_ITEM_end(CBIGNUM)
static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
*pval = (ASN1_VALUE *)BN_new();
if(*pval) return 1;
else return 0;
*pval = (ASN1_VALUE *)BN_new();
if (*pval)
return 1;
else
return 0;
}
static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
if(!*pval) return;
if(it->size & BN_SENSITIVE) BN_clear_free((BIGNUM *)*pval);
else BN_free((BIGNUM *)*pval);
*pval = NULL;
if (!*pval)
return;
if (it->size & BN_SENSITIVE)
BN_clear_free((BIGNUM *)*pval);
else
BN_free((BIGNUM *)*pval);
*pval = NULL;
}
static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it)
static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
const ASN1_ITEM *it)
{
BIGNUM *bn;
int pad;
if(!*pval) return -1;
bn = (BIGNUM *)*pval;
/* If MSB set in an octet we need a padding byte */
if(BN_num_bits(bn) & 0x7) pad = 0;
else pad = 1;
if(cont) {
if(pad) *cont++ = 0;
BN_bn2bin(bn, cont);
}
return pad + BN_num_bytes(bn);
BIGNUM *bn;
int pad;
if (!*pval)
return -1;
bn = (BIGNUM *)*pval;
/* If MSB set in an octet we need a padding byte */
if (BN_num_bits(bn) & 0x7)
pad = 0;
else
pad = 1;
if (cont) {
if (pad)
*cont++ = 0;
BN_bn2bin(bn, cont);
}
return pad + BN_num_bytes(bn);
}
static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
int utype, char *free_cont, const ASN1_ITEM *it)
int utype, char *free_cont, const ASN1_ITEM *it)
{
BIGNUM *bn;
if(!*pval)
{
if (!bn_new(pval, it))
{
return 0;
}
}
bn = (BIGNUM *)*pval;
if(!BN_bin2bn(cont, len, bn)) {
bn_free(pval, it);
return 0;
}
return 1;
BIGNUM *bn;
if (!*pval) {
if (!bn_new(pval, it)) {
return 0;
}
}
bn = (BIGNUM *)*pval;
if (!BN_bin2bn(cont, len, bn)) {
bn_free(pval, it);
return 0;
}
return 1;
}
+97 -82
View File
@@ -63,120 +63,135 @@
#include <openssl/err.h>
#include <openssl/mem.h>
/* Custom primitive type for long handling. This converts between an ASN1_INTEGER
* and a long directly.
/*
* Custom primitive type for long handling. This converts between an
* ASN1_INTEGER and a long directly.
*/
static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx);
static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
const ASN1_ITEM *it);
static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
int utype, char *free_cont, const ASN1_ITEM *it);
static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
int indent, const ASN1_PCTX *pctx);
static const ASN1_PRIMITIVE_FUNCS long_pf = {
NULL, 0,
long_new,
long_free,
long_free, /* Clear should set to initial value */
long_c2i,
long_i2c,
long_print
NULL, 0,
long_new,
long_free,
long_free, /* Clear should set to initial value */
long_c2i,
long_i2c,
long_print
};
ASN1_ITEM_start(LONG)
ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, ASN1_LONG_UNDEF, "LONG"
ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, ASN1_LONG_UNDEF, "LONG"
ASN1_ITEM_end(LONG)
ASN1_ITEM_start(ZLONG)
ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, 0, "ZLONG"
ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, 0, "ZLONG"
ASN1_ITEM_end(ZLONG)
static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
*(long *)pval = it->size;
return 1;
*(long *)pval = it->size;
return 1;
}
static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
*(long *)pval = it->size;
*(long *)pval = it->size;
}
static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it)
static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
const ASN1_ITEM *it)
{
long ltmp;
unsigned long utmp;
int clen, pad, i;
/* this exists to bypass broken gcc optimization */
char *cp = (char *)pval;
long ltmp;
unsigned long utmp;
int clen, pad, i;
/* this exists to bypass broken gcc optimization */
char *cp = (char *)pval;
/* use memcpy, because we may not be long aligned */
memcpy(&ltmp, cp, sizeof(long));
/* use memcpy, because we may not be long aligned */
memcpy(&ltmp, cp, sizeof(long));
if(ltmp == it->size) return -1;
/* Convert the long to positive: we subtract one if negative so
* we can cleanly handle the padding if only the MSB of the leading
* octet is set.
*/
if(ltmp < 0) utmp = -ltmp - 1;
else utmp = ltmp;
clen = BN_num_bits_word(utmp);
/* If MSB of leading octet set we need to pad */
if(!(clen & 0x7)) pad = 1;
else pad = 0;
if (ltmp == it->size)
return -1;
/*
* Convert the long to positive: we subtract one if negative so we can
* cleanly handle the padding if only the MSB of the leading octet is
* set.
*/
if (ltmp < 0)
utmp = -ltmp - 1;
else
utmp = ltmp;
clen = BN_num_bits_word(utmp);
/* If MSB of leading octet set we need to pad */
if (!(clen & 0x7))
pad = 1;
else
pad = 0;
/* Convert number of bits to number of octets */
clen = (clen + 7) >> 3;
/* Convert number of bits to number of octets */
clen = (clen + 7) >> 3;
if(cont) {
if(pad) *cont++ = (ltmp < 0) ? 0xff : 0;
for(i = clen - 1; i >= 0; i--) {
cont[i] = (unsigned char)(utmp & 0xff);
if(ltmp < 0) cont[i] ^= 0xff;
utmp >>= 8;
}
}
return clen + pad;
if (cont) {
if (pad)
*cont++ = (ltmp < 0) ? 0xff : 0;
for (i = clen - 1; i >= 0; i--) {
cont[i] = (unsigned char)(utmp & 0xff);
if (ltmp < 0)
cont[i] ^= 0xff;
utmp >>= 8;
}
}
return clen + pad;
}
static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
int utype, char *free_cont, const ASN1_ITEM *it)
int utype, char *free_cont, const ASN1_ITEM *it)
{
int neg, i;
long ltmp;
unsigned long utmp = 0;
char *cp = (char *)pval;
if(len > (int)sizeof(long)) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
return 0;
}
/* Is it negative? */
if(len && (cont[0] & 0x80)) neg = 1;
else neg = 0;
utmp = 0;
for(i = 0; i < len; i++) {
utmp <<= 8;
if(neg) utmp |= cont[i] ^ 0xff;
else utmp |= cont[i];
}
ltmp = (long)utmp;
if(neg) {
ltmp++;
ltmp = -ltmp;
}
if(ltmp == it->size) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
return 0;
}
memcpy(cp, &ltmp, sizeof(long));
return 1;
int neg, i;
long ltmp;
unsigned long utmp = 0;
char *cp = (char *)pval;
if (len > (int)sizeof(long)) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
return 0;
}
/* Is it negative? */
if (len && (cont[0] & 0x80))
neg = 1;
else
neg = 0;
utmp = 0;
for (i = 0; i < len; i++) {
utmp <<= 8;
if (neg)
utmp |= cont[i] ^ 0xff;
else
utmp |= cont[i];
}
ltmp = (long)utmp;
if (neg) {
ltmp++;
ltmp = -ltmp;
}
if (ltmp == it->size) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
return 0;
}
memcpy(cp, &ltmp, sizeof(long));
return 1;
}
static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
int indent, const ASN1_PCTX *pctx)
{
return BIO_printf(out, "%ld\n", *(long *)pval);
}
int indent, const ASN1_PCTX *pctx)
{
return BIO_printf(out, "%ld\n", *(long *)pval);
}
+2 -1
View File
@@ -1,4 +1,4 @@
include_directories(. .. ../../include)
include_directories(../../include)
add_library(
base64
@@ -17,3 +17,4 @@ add_executable(
)
target_link_libraries(base64_test crypto)
add_dependencies(all_tests base64_test)
-1
View File
@@ -116,7 +116,6 @@ static bool TestDecode() {
int main(void) {
CRYPTO_library_init();
ERR_load_crypto_strings();
if (!TestEncode() ||
!TestDecode()) {
+2 -1
View File
@@ -1,4 +1,4 @@
include_directories(. .. ../../include)
include_directories(../../include)
add_library(
bio
@@ -30,3 +30,4 @@ target_link_libraries(bio_test crypto)
if (WIN32)
target_link_libraries(bio_test ws2_32)
endif()
add_dependencies(all_tests bio_test)
+6 -4
View File
@@ -529,7 +529,7 @@ int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len, size_t max_len) {
uint8_t header[6];
static const size_t kInitialHeaderLen = 2;
if (BIO_read(bio, header, kInitialHeaderLen) != kInitialHeaderLen) {
if (BIO_read(bio, header, kInitialHeaderLen) != (int) kInitialHeaderLen) {
return 0;
}
@@ -559,7 +559,8 @@ int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len, size_t max_len) {
return 0;
}
if (BIO_read(bio, header + kInitialHeaderLen, num_bytes) != num_bytes) {
if (BIO_read(bio, header + kInitialHeaderLen, num_bytes) !=
(int)num_bytes) {
return 0;
}
header_len = kInitialHeaderLen + num_bytes;
@@ -585,7 +586,8 @@ int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len, size_t max_len) {
}
if (len + header_len < len ||
len + header_len > max_len) {
len + header_len > max_len ||
len > INT_MAX) {
return 0;
}
len += header_len;
@@ -597,7 +599,7 @@ int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len, size_t max_len) {
}
memcpy(*out, header, header_len);
if (BIO_read(bio, (*out) + header_len, len - header_len) !=
len - header_len) {
(int) (len - header_len)) {
OPENSSL_free(*out);
return 0;
}
+4 -3
View File
@@ -64,7 +64,7 @@
#include <openssl/mem.h>
BIO *BIO_new_mem_buf(void *buf, int len) {
BIO *BIO_new_mem_buf(const void *buf, int len) {
BIO *ret;
BUF_MEM *b;
const size_t size = len < 0 ? strlen((char *)buf) : (size_t)len;
@@ -80,7 +80,8 @@ BIO *BIO_new_mem_buf(void *buf, int len) {
}
b = (BUF_MEM *)ret->ptr;
b->data = buf;
/* BIO_FLAGS_MEM_RDONLY ensures |b->data| is not written to. */
b->data = (void *)buf;
b->length = size;
b->max = size;
@@ -176,7 +177,7 @@ static int mem_write(BIO *bio, const char *in, int inl) {
if (INT_MAX - blen < inl) {
goto err;
}
if (BUF_MEM_grow_clean(b, blen + inl) != (blen + inl)) {
if (BUF_MEM_grow_clean(b, blen + inl) != ((size_t) blen) + inl) {
goto err;
}
memcpy(&b->data[blen], in, inl);
+1 -2
View File
@@ -331,7 +331,7 @@ static bool TestPrintf() {
static bool ReadASN1(bool should_succeed, const uint8_t *data, size_t data_len,
size_t expected_len, size_t max_len) {
ScopedBIO bio(BIO_new_mem_buf(const_cast<uint8_t*>(data), data_len));
ScopedBIO bio(BIO_new_mem_buf(data, data_len));
uint8_t *out;
size_t out_len;
@@ -412,7 +412,6 @@ static bool TestASN1() {
int main(void) {
CRYPTO_library_init();
ERR_load_crypto_strings();
#if defined(OPENSSL_WINDOWS)
// Initialize Winsock.
+3 -3
View File
@@ -100,7 +100,7 @@ static int buffer_new(BIO *bio) {
if (ctx->ibuf == NULL) {
goto err1;
}
ctx->obuf = (char *)OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
ctx->obuf = OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
if (ctx->obuf == NULL) {
goto err2;
}
@@ -340,13 +340,13 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr) {
p1 = ctx->ibuf;
p2 = ctx->obuf;
if (ibs > DEFAULT_BUFFER_SIZE && ibs != ctx->ibuf_size) {
p1 = (char *)OPENSSL_malloc(ibs);
p1 = OPENSSL_malloc(ibs);
if (p1 == NULL) {
goto malloc_error;
}
}
if (obs > DEFAULT_BUFFER_SIZE && obs != ctx->obuf_size) {
p2 = (char *)OPENSSL_malloc(obs);
p2 = OPENSSL_malloc(obs);
if (p2 == NULL) {
if (p1 != ctx->ibuf) {
OPENSSL_free(p1);
+74 -65
View File
@@ -58,7 +58,6 @@
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#if !defined(OPENSSL_WINDOWS)
@@ -93,7 +92,6 @@ typedef struct bio_connect_st {
char *param_port;
int nbio;
uint8_t ip[4];
unsigned short port;
struct sockaddr_storage them;
@@ -114,23 +112,59 @@ static int closesocket(int sock) {
}
#endif
/* maybe_copy_ipv4_address sets |*ipv4| to the IPv4 address from |ss| (in
* big-endian order), if |ss| contains an IPv4 socket address. */
static void maybe_copy_ipv4_address(uint8_t *ipv4,
const struct sockaddr_storage *ss) {
const struct sockaddr_in *sin;
/* split_host_and_port sets |*out_host| and |*out_port| to the host and port
* parsed from |name|. It returns one on success or zero on error. Even when
* successful, |*out_port| may be NULL on return if no port was specified. */
static int split_host_and_port(char **out_host, char **out_port, const char *name) {
const char *host, *port = NULL;
size_t host_len = 0;
if (ss->ss_family != AF_INET) {
return;
*out_host = NULL;
*out_port = NULL;
if (name[0] == '[') { /* bracketed IPv6 address */
const char *close = strchr(name, ']');
if (close == NULL) {
return 0;
}
host = name + 1;
host_len = close - host;
if (close[1] == ':') { /* [IP]:port */
port = close + 2;
} else if (close[1] != 0) {
return 0;
}
} else {
const char *colon = strchr(name, ':');
if (colon == NULL || strchr(colon + 1, ':') != NULL) { /* IPv6 address */
host = name;
host_len = strlen(name);
} else { /* host:port */
host = name;
host_len = colon - name;
port = colon + 1;
}
}
sin = (const struct sockaddr_in*) ss;
memcpy(ipv4, &sin->sin_addr, 4);
*out_host = BUF_strndup(host, host_len);
if (*out_host == NULL) {
return 0;
}
if (port == NULL) {
*out_port = NULL;
return 1;
}
*out_port = OPENSSL_strdup(port);
if (*out_port == NULL) {
OPENSSL_free(*out_host);
*out_host = NULL;
return 0;
}
return 1;
}
static int conn_state(BIO *bio, BIO_CONNECT *c) {
int ret = -1, i;
char *p, *q;
int (*cb)(const BIO *, int, int) = NULL;
if (c->info_callback != NULL) {
@@ -140,36 +174,30 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
for (;;) {
switch (c->state) {
case BIO_CONN_S_BEFORE:
p = c->param_hostname;
if (p == NULL) {
/* If there's a hostname and a port, assume that both are
* exactly what they say. If there is only a hostname, try
* (just once) to split it into a hostname and port. */
if (c->param_hostname == NULL) {
OPENSSL_PUT_ERROR(BIO, BIO_R_NO_HOSTNAME_SPECIFIED);
goto exit_loop;
}
for (; *p != 0; p++) {
if (*p == ':' || *p == '/') {
break;
}
}
i = *p;
if (i == ':' || i == '/') {
*(p++) = 0;
if (i == ':') {
for (q = p; *q; q++) {
if (*q == '/') {
*q = 0;
break;
}
}
OPENSSL_free(c->param_port);
c->param_port = BUF_strdup(p);
}
}
if (c->param_port == NULL) {
OPENSSL_PUT_ERROR(BIO, BIO_R_NO_PORT_SPECIFIED);
ERR_add_error_data(2, "host=", c->param_hostname);
goto exit_loop;
char *host, *port;
if (!split_host_and_port(&host, &port, c->param_hostname) ||
port == NULL) {
OPENSSL_free(host);
OPENSSL_free(port);
OPENSSL_PUT_ERROR(BIO, BIO_R_NO_PORT_SPECIFIED);
ERR_add_error_data(2, "host=", c->param_hostname);
goto exit_loop;
}
OPENSSL_free(c->param_port);
c->param_port = port;
OPENSSL_free(c->param_hostname);
c->param_hostname = host;
}
if (!bio_ip_and_port_to_socket_and_addr(
@@ -180,9 +208,6 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
goto exit_loop;
}
memset(c->ip, 0, 4);
maybe_copy_ipv4_address(c->ip, &c->them);
if (c->nbio) {
if (!bio_socket_nbio(bio->num, 1)) {
OPENSSL_PUT_ERROR(BIO, BIO_R_ERROR_SETTING_NBIO);
@@ -196,7 +221,7 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
ret = setsockopt(bio->num, SOL_SOCKET, SO_KEEPALIVE, (char *)&i,
sizeof(i));
if (ret < 0) {
OPENSSL_PUT_SYSTEM_ERROR(setsockopt);
OPENSSL_PUT_SYSTEM_ERROR();
OPENSSL_PUT_ERROR(BIO, BIO_R_KEEPALIVE);
ERR_add_error_data(4, "host=", c->param_hostname, ":", c->param_port);
goto exit_loop;
@@ -210,7 +235,7 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
c->state = BIO_CONN_S_BLOCKED_CONNECT;
bio->retry_reason = BIO_RR_CONNECT;
} else {
OPENSSL_PUT_SYSTEM_ERROR(connect);
OPENSSL_PUT_SYSTEM_ERROR();
OPENSSL_PUT_ERROR(BIO, BIO_R_CONNECT_ERROR);
ERR_add_error_data(4, "host=", c->param_hostname, ":",
c->param_port);
@@ -231,7 +256,7 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
ret = -1;
} else {
BIO_clear_retry_flags(bio);
OPENSSL_PUT_SYSTEM_ERROR(connect);
OPENSSL_PUT_SYSTEM_ERROR();
OPENSSL_PUT_ERROR(BIO, BIO_R_NBIO_CONNECT_ERROR);
ERR_add_error_data(4, "host=", c->param_hostname, ":", c->param_port);
ret = 0;
@@ -376,7 +401,6 @@ static int conn_write(BIO *bio, const char *in, int in_len) {
static long conn_ctrl(BIO *bio, int cmd, long num, void *ptr) {
int *ip;
const char **pptr;
long ret = 1;
BIO_CONNECT *data;
@@ -397,25 +421,6 @@ static long conn_ctrl(BIO *bio, int cmd, long num, void *ptr) {
ret = 1;
}
break;
case BIO_C_GET_CONNECT:
/* TODO(fork): can this be removed? (Or maybe this whole file). */
if (ptr != NULL) {
pptr = (const char **)ptr;
if (num == 0) {
*pptr = data->param_hostname;
} else if (num == 1) {
*pptr = data->param_port;
} else if (num == 2) {
*pptr = (char *) &data->ip[0];
} else if (num == 3) {
*((int *)ptr) = data->port;
}
if (!bio->init) {
*pptr = "not initialized";
}
ret = 1;
}
break;
case BIO_C_SET_CONNECT:
if (ptr != NULL) {
bio->init = 1;
@@ -445,9 +450,9 @@ static long conn_ctrl(BIO *bio, int cmd, long num, void *ptr) {
if (ip != NULL) {
*ip = bio->num;
}
ret = 1;
ret = bio->num;
} else {
ret = 0;
ret = -1;
}
break;
case BIO_CTRL_GET_CLOSE:
@@ -536,3 +541,7 @@ int BIO_set_conn_port(BIO *bio, const char *port_str) {
int BIO_set_nbio(BIO *bio, int on) {
return BIO_ctrl(bio, BIO_C_SET_NBIO, on, NULL);
}
int BIO_do_connect(BIO *bio) {
return BIO_ctrl(bio, BIO_C_DO_STATE_MACHINE, 0, NULL);
}
+4 -2
View File
@@ -72,6 +72,8 @@
#include <openssl/err.h>
#include <openssl/mem.h>
#include "internal.h"
static int bio_fd_non_fatal_error(int err) {
if (
@@ -208,9 +210,9 @@ static long fd_ctrl(BIO *b, int cmd, long num, void *ptr) {
if (ip != NULL) {
*ip = b->num;
}
return 1;
return b->num;
} else {
ret = 0;
ret = -1;
}
break;
case BIO_CTRL_GET_CLOSE:
+9 -46
View File
@@ -87,49 +87,13 @@
#define BIO_FP_WRITE 0x04
#define BIO_FP_APPEND 0x08
static FILE *open_file(const char *filename, const char *mode) {
#if defined(OPENSSL_WINDOWS) && defined(CP_UTF8)
int sz, len_0 = (int)strlen(filename) + 1;
DWORD flags;
/* Basically there are three cases to cover: a) filename is pure ASCII
* string; b) actual UTF-8 encoded string and c) locale-ized string, i.e. one
* containing 8-bit characters that are meaningful in current system locale.
* If filename is pure ASCII or real UTF-8 encoded string,
* MultiByteToWideChar succeeds and _wfopen works. If filename is locale-ized
* string, chances are that MultiByteToWideChar fails reporting
* ERROR_NO_UNICODE_TRANSLATION, in which case we fall back to fopen... */
if ((sz = MultiByteToWideChar(CP_UTF8, (flags = MB_ERR_INVALID_CHARS),
filename, len_0, NULL, 0)) > 0 ||
(GetLastError() == ERROR_INVALID_FLAGS &&
(sz = MultiByteToWideChar(CP_UTF8, (flags = 0), filename, len_0, NULL,
0)) > 0)) {
WCHAR wmode[8];
WCHAR *wfilename = _alloca(sz * sizeof(WCHAR));
if (MultiByteToWideChar(CP_UTF8, flags, filename, len_0, wfilename, sz) &&
MultiByteToWideChar(CP_UTF8, 0, mode, strlen(mode) + 1, wmode,
sizeof(wmode) / sizeof(wmode[0])) &&
(file = _wfopen(wfilename, wmode)) == NULL &&
(errno == ENOENT ||
errno == EBADF)) /* UTF-8 decode succeeded, but no file, filename
* could still have been locale-ized... */
return fopen(filename, mode);
} else if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) {
return fopen(filename, mode);
}
#else
return fopen(filename, mode);
#endif
}
BIO *BIO_new_file(const char *filename, const char *mode) {
BIO *ret;
FILE *file;
file = open_file(filename, mode);
file = fopen(filename, mode);
if (file == NULL) {
OPENSSL_PUT_SYSTEM_ERROR(fopen);
OPENSSL_PUT_SYSTEM_ERROR();
ERR_add_error_data(5, "fopen('", filename, "','", mode, "')");
if (errno == ENOENT) {
@@ -182,20 +146,19 @@ static int file_free(BIO *bio) {
}
static int file_read(BIO *b, char *out, int outl) {
int ret = 0;
if (!b->init) {
return 0;
}
ret = fread(out, 1, outl, (FILE *)b->ptr);
size_t ret = fread(out, 1, outl, (FILE *)b->ptr);
if (ret == 0 && ferror((FILE *)b->ptr)) {
OPENSSL_PUT_SYSTEM_ERROR(fread);
OPENSSL_PUT_SYSTEM_ERROR();
OPENSSL_PUT_ERROR(BIO, ERR_R_SYS_LIB);
ret = -1;
return -1;
}
return ret;
/* fread reads at most |outl| bytes, so |ret| fits in an int. */
return (int)ret;
}
static int file_write(BIO *b, const char *in, int inl) {
@@ -257,9 +220,9 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) {
ret = 0;
break;
}
fp = open_file(ptr, p);
fp = fopen(ptr, p);
if (fp == NULL) {
OPENSSL_PUT_SYSTEM_ERROR(fopen);
OPENSSL_PUT_SYSTEM_ERROR();
ERR_add_error_data(5, "fopen('", ptr, "','", p, "')");
OPENSSL_PUT_ERROR(BIO, ERR_R_SYS_LIB);
ret = 0;
+3
View File
@@ -67,6 +67,9 @@ typedef unsigned short u_short;
#include <sys/types.h>
#include <sys/socket.h>
#else
#pragma warning(push, 3)
#include <winsock2.h>
#pragma warning(pop)
typedef int socklen_t;
#endif
+2 -2
View File
@@ -256,8 +256,8 @@ int BIO_zero_copy_get_read_buf_done(BIO* bio, size_t bytes_read) {
return 0;
}
assert(peer_b->len >= bytes_read);
peer_b->len -= bytes_read;
assert(peer_b->len >= 0);
assert(peer_b->offset + bytes_read <= peer_b->size);
/* Move read offset. If zero_copy_write_lock == 1 we must advance the
@@ -742,7 +742,7 @@ static const BIO_METHOD methods_biop = {
bio_free, NULL /* no bio_callback_ctrl */
};
const BIO_METHOD *bio_s_bio(void) { return &methods_biop; }
static const BIO_METHOD *bio_s_bio(void) { return &methods_biop; }
int BIO_new_bio_pair(BIO** bio1_p, size_t writebuf1,
BIO** bio2_p, size_t writebuf2) {
+5 -1
View File
@@ -87,7 +87,11 @@ int BIO_printf(BIO *bio, const char *format, ...) {
}
#endif
if (out_len >= sizeof(buf)) {
if (out_len < 0) {
return -1;
}
if ((size_t) out_len >= sizeof(buf)) {
const int requested_len = out_len;
/* The output was truncated. Note that vsnprintf's return value
* does not include a trailing NUL, but the buffer must be sized
+2 -2
View File
@@ -59,7 +59,7 @@ int bio_ip_and_port_to_socket_and_addr(int *out_sock,
ret = 0;
for (cur = result; cur; cur = cur->ai_next) {
if (cur->ai_addrlen > sizeof(struct sockaddr_storage)) {
if ((size_t) cur->ai_addrlen > sizeof(struct sockaddr_storage)) {
continue;
}
memset(out_addr, 0, sizeof(struct sockaddr_storage));
@@ -68,7 +68,7 @@ int bio_ip_and_port_to_socket_and_addr(int *out_sock,
*out_sock = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol);
if (*out_sock < 0) {
OPENSSL_PUT_SYSTEM_ERROR(socket);
OPENSSL_PUT_SYSTEM_ERROR();
goto out;
}
+11 -1
View File
@@ -1,4 +1,4 @@
include_directories(. .. ../../include)
include_directories(../../include)
if (${ARCH} STREQUAL "x86_64")
set(
@@ -31,6 +31,14 @@ if (${ARCH} STREQUAL "arm")
)
endif()
if (${ARCH} STREQUAL "aarch64")
set(
BN_ARCH_SOURCES
armv8-mont.${ASM_EXT}
)
endif()
add_library(
bn
@@ -66,6 +74,7 @@ perlasm(bn-586.${ASM_EXT} asm/bn-586.pl)
perlasm(co-586.${ASM_EXT} asm/co-586.pl)
perlasm(x86-mont.${ASM_EXT} asm/x86-mont.pl)
perlasm(armv4-mont.${ASM_EXT} asm/armv4-mont.pl)
perlasm(armv8-mont.${ASM_EXT} asm/armv8-mont.pl)
add_executable(
bn_test
@@ -76,3 +85,4 @@ add_executable(
)
target_link_libraries(bn_test crypto)
add_dependencies(all_tests bn_test)
+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;
+2 -3
View File
@@ -79,7 +79,7 @@ $_n0="$num,#14*4";
$_num="$num,#15*4"; $_bpend=$_num;
$code=<<___;
#include "arm_arch.h"
#include <openssl/arm_arch.h>
.text
.code 32
@@ -91,7 +91,6 @@ $code=<<___;
#endif
.global bn_mul_mont
.hidden bn_mul_mont
.type bn_mul_mont,%function
.align 5
@@ -108,7 +107,7 @@ bn_mul_mont:
#ifdef __APPLE__
ldr r0,[r0]
#endif
tst r0,#1 @ NEON available?
tst r0,#ARMV7_NEON @ NEON available?
ldmia sp, {r0,r2}
beq .Lialu
add sp,sp,#8
File diff suppressed because it is too large Load Diff
Regular → Executable
+146 -99
View File
@@ -79,29 +79,13 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
$avx = ($1>=2.19) + ($1>=2.22);
$addx = ($1>=2.23);
}
if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
`nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
$avx = ($1>=2.09) + ($1>=2.10);
$addx = ($1>=2.10);
}
if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
`ml64 2>&1` =~ /Version ([0-9]+)\./) {
$avx = ($1>=10) + ($1>=11);
$addx = ($1>=11);
}
if (!$avx && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([3-9])\.([0-9]+)/) {
my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10
$avx = ($ver>=3.0) + ($ver>=3.01);
$addx = ($ver>=3.03);
}
# 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 these after testing. $avx goes up to 2 and $addx to 1.
$avx = 0;
$addx = 0;
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT = *OUT;
@@ -443,7 +427,7 @@ $TEMP2 = $B2;
$TEMP3 = $Y1;
$TEMP4 = $Y2;
$code.=<<___;
#we need to fix indexes 32-39 to avoid overflow
# we need to fix indices 32-39 to avoid overflow
vmovdqu 32*8(%rsp), $ACC8 # 32*8-192($tp0),
vmovdqu 32*9(%rsp), $ACC1 # 32*9-192($tp0)
vmovdqu 32*10(%rsp), $ACC2 # 32*10-192($tp0)
@@ -1592,68 +1576,128 @@ rsaz_1024_scatter5_avx2:
.type rsaz_1024_gather5_avx2,\@abi-omnipotent
.align 32
rsaz_1024_gather5_avx2:
vzeroupper
mov %rsp,%r11
___
$code.=<<___ if ($win64);
lea -0x88(%rsp),%rax
vzeroupper
.LSEH_begin_rsaz_1024_gather5:
# I can't trust assembler to use specific encoding:-(
.byte 0x48,0x8d,0x60,0xe0 #lea -0x20(%rax),%rsp
.byte 0xc5,0xf8,0x29,0x70,0xe0 #vmovaps %xmm6,-0x20(%rax)
.byte 0xc5,0xf8,0x29,0x78,0xf0 #vmovaps %xmm7,-0x10(%rax)
.byte 0xc5,0x78,0x29,0x40,0x00 #vmovaps %xmm8,0(%rax)
.byte 0xc5,0x78,0x29,0x48,0x10 #vmovaps %xmm9,0x10(%rax)
.byte 0xc5,0x78,0x29,0x50,0x20 #vmovaps %xmm10,0x20(%rax)
.byte 0xc5,0x78,0x29,0x58,0x30 #vmovaps %xmm11,0x30(%rax)
.byte 0xc5,0x78,0x29,0x60,0x40 #vmovaps %xmm12,0x40(%rax)
.byte 0xc5,0x78,0x29,0x68,0x50 #vmovaps %xmm13,0x50(%rax)
.byte 0xc5,0x78,0x29,0x70,0x60 #vmovaps %xmm14,0x60(%rax)
.byte 0xc5,0x78,0x29,0x78,0x70 #vmovaps %xmm15,0x70(%rax)
.byte 0x48,0x8d,0x60,0xe0 # lea -0x20(%rax),%rsp
.byte 0xc5,0xf8,0x29,0x70,0xe0 # vmovaps %xmm6,-0x20(%rax)
.byte 0xc5,0xf8,0x29,0x78,0xf0 # vmovaps %xmm7,-0x10(%rax)
.byte 0xc5,0x78,0x29,0x40,0x00 # vmovaps %xmm8,0(%rax)
.byte 0xc5,0x78,0x29,0x48,0x10 # vmovaps %xmm9,0x10(%rax)
.byte 0xc5,0x78,0x29,0x50,0x20 # vmovaps %xmm10,0x20(%rax)
.byte 0xc5,0x78,0x29,0x58,0x30 # vmovaps %xmm11,0x30(%rax)
.byte 0xc5,0x78,0x29,0x60,0x40 # vmovaps %xmm12,0x40(%rax)
.byte 0xc5,0x78,0x29,0x68,0x50 # vmovaps %xmm13,0x50(%rax)
.byte 0xc5,0x78,0x29,0x70,0x60 # vmovaps %xmm14,0x60(%rax)
.byte 0xc5,0x78,0x29,0x78,0x70 # vmovaps %xmm15,0x70(%rax)
___
$code.=<<___;
lea .Lgather_table(%rip),%r11
mov $power,%eax
and \$3,$power
shr \$2,%eax # cache line number
shl \$4,$power # offset within cache line
lea -0x100(%rsp),%rsp
and \$-32, %rsp
lea .Linc(%rip), %r10
lea -128(%rsp),%rax # control u-op density
vmovdqu -32(%r11),%ymm7 # .Lgather_permd
vpbroadcastb 8(%r11,%rax), %xmm8
vpbroadcastb 7(%r11,%rax), %xmm9
vpbroadcastb 6(%r11,%rax), %xmm10
vpbroadcastb 5(%r11,%rax), %xmm11
vpbroadcastb 4(%r11,%rax), %xmm12
vpbroadcastb 3(%r11,%rax), %xmm13
vpbroadcastb 2(%r11,%rax), %xmm14
vpbroadcastb 1(%r11,%rax), %xmm15
vmovd $power, %xmm4
vmovdqa (%r10),%ymm0
vmovdqa 32(%r10),%ymm1
vmovdqa 64(%r10),%ymm5
vpbroadcastd %xmm4,%ymm4
lea 64($inp,$power),$inp
mov \$64,%r11 # size optimization
mov \$9,%eax
jmp .Loop_gather_1024
vpaddd %ymm5, %ymm0, %ymm2
vpcmpeqd %ymm4, %ymm0, %ymm0
vpaddd %ymm5, %ymm1, %ymm3
vpcmpeqd %ymm4, %ymm1, %ymm1
vmovdqa %ymm0, 32*0+128(%rax)
vpaddd %ymm5, %ymm2, %ymm0
vpcmpeqd %ymm4, %ymm2, %ymm2
vmovdqa %ymm1, 32*1+128(%rax)
vpaddd %ymm5, %ymm3, %ymm1
vpcmpeqd %ymm4, %ymm3, %ymm3
vmovdqa %ymm2, 32*2+128(%rax)
vpaddd %ymm5, %ymm0, %ymm2
vpcmpeqd %ymm4, %ymm0, %ymm0
vmovdqa %ymm3, 32*3+128(%rax)
vpaddd %ymm5, %ymm1, %ymm3
vpcmpeqd %ymm4, %ymm1, %ymm1
vmovdqa %ymm0, 32*4+128(%rax)
vpaddd %ymm5, %ymm2, %ymm8
vpcmpeqd %ymm4, %ymm2, %ymm2
vmovdqa %ymm1, 32*5+128(%rax)
vpaddd %ymm5, %ymm3, %ymm9
vpcmpeqd %ymm4, %ymm3, %ymm3
vmovdqa %ymm2, 32*6+128(%rax)
vpaddd %ymm5, %ymm8, %ymm10
vpcmpeqd %ymm4, %ymm8, %ymm8
vmovdqa %ymm3, 32*7+128(%rax)
vpaddd %ymm5, %ymm9, %ymm11
vpcmpeqd %ymm4, %ymm9, %ymm9
vpaddd %ymm5, %ymm10, %ymm12
vpcmpeqd %ymm4, %ymm10, %ymm10
vpaddd %ymm5, %ymm11, %ymm13
vpcmpeqd %ymm4, %ymm11, %ymm11
vpaddd %ymm5, %ymm12, %ymm14
vpcmpeqd %ymm4, %ymm12, %ymm12
vpaddd %ymm5, %ymm13, %ymm15
vpcmpeqd %ymm4, %ymm13, %ymm13
vpcmpeqd %ymm4, %ymm14, %ymm14
vpcmpeqd %ymm4, %ymm15, %ymm15
vmovdqa -32(%r10),%ymm7 # .Lgather_permd
lea 128($inp), $inp
mov \$9,$power
.align 32
.Loop_gather_1024:
vpand -64($inp), %xmm8,%xmm0
vpand ($inp), %xmm9,%xmm1
vpand 64($inp), %xmm10,%xmm2
vpand ($inp,%r11,2), %xmm11,%xmm3
vpor %xmm0,%xmm1,%xmm1
vpand 64($inp,%r11,2), %xmm12,%xmm4
vpor %xmm2,%xmm3,%xmm3
vpand ($inp,%r11,4), %xmm13,%xmm5
vpor %xmm1,%xmm3,%xmm3
vpand 64($inp,%r11,4), %xmm14,%xmm6
vpor %xmm4,%xmm5,%xmm5
vpand -128($inp,%r11,8), %xmm15,%xmm2
lea ($inp,%r11,8),$inp
vpor %xmm3,%xmm5,%xmm5
vpor %xmm2,%xmm6,%xmm6
vpor %xmm5,%xmm6,%xmm6
vpermd %ymm6,%ymm7,%ymm6
vmovdqu %ymm6,($out)
vmovdqa 32*0-128($inp), %ymm0
vmovdqa 32*1-128($inp), %ymm1
vmovdqa 32*2-128($inp), %ymm2
vmovdqa 32*3-128($inp), %ymm3
vpand 32*0+128(%rax), %ymm0, %ymm0
vpand 32*1+128(%rax), %ymm1, %ymm1
vpand 32*2+128(%rax), %ymm2, %ymm2
vpor %ymm0, %ymm1, %ymm4
vpand 32*3+128(%rax), %ymm3, %ymm3
vmovdqa 32*4-128($inp), %ymm0
vmovdqa 32*5-128($inp), %ymm1
vpor %ymm2, %ymm3, %ymm5
vmovdqa 32*6-128($inp), %ymm2
vmovdqa 32*7-128($inp), %ymm3
vpand 32*4+128(%rax), %ymm0, %ymm0
vpand 32*5+128(%rax), %ymm1, %ymm1
vpand 32*6+128(%rax), %ymm2, %ymm2
vpor %ymm0, %ymm4, %ymm4
vpand 32*7+128(%rax), %ymm3, %ymm3
vpand 32*8-128($inp), %ymm8, %ymm0
vpor %ymm1, %ymm5, %ymm5
vpand 32*9-128($inp), %ymm9, %ymm1
vpor %ymm2, %ymm4, %ymm4
vpand 32*10-128($inp),%ymm10, %ymm2
vpor %ymm3, %ymm5, %ymm5
vpand 32*11-128($inp),%ymm11, %ymm3
vpor %ymm0, %ymm4, %ymm4
vpand 32*12-128($inp),%ymm12, %ymm0
vpor %ymm1, %ymm5, %ymm5
vpand 32*13-128($inp),%ymm13, %ymm1
vpor %ymm2, %ymm4, %ymm4
vpand 32*14-128($inp),%ymm14, %ymm2
vpor %ymm3, %ymm5, %ymm5
vpand 32*15-128($inp),%ymm15, %ymm3
lea 32*16($inp), $inp
vpor %ymm0, %ymm4, %ymm4
vpor %ymm1, %ymm5, %ymm5
vpor %ymm2, %ymm4, %ymm4
vpor %ymm3, %ymm5, %ymm5
vpor %ymm5, %ymm4, %ymm4
vextracti128 \$1, %ymm4, %xmm5 # upper half is cleared
vpor %xmm4, %xmm5, %xmm5
vpermd %ymm5,%ymm7,%ymm5
vmovdqu %ymm5,($out)
lea 32($out),$out
dec %eax
dec $power
jnz .Loop_gather_1024
vpxor %ymm0,%ymm0,%ymm0
@@ -1661,20 +1705,20 @@ $code.=<<___;
vzeroupper
___
$code.=<<___ if ($win64);
movaps (%rsp),%xmm6
movaps 0x10(%rsp),%xmm7
movaps 0x20(%rsp),%xmm8
movaps 0x30(%rsp),%xmm9
movaps 0x40(%rsp),%xmm10
movaps 0x50(%rsp),%xmm11
movaps 0x60(%rsp),%xmm12
movaps 0x70(%rsp),%xmm13
movaps 0x80(%rsp),%xmm14
movaps 0x90(%rsp),%xmm15
lea 0xa8(%rsp),%rsp
movaps -0xa8(%r11),%xmm6
movaps -0x98(%r11),%xmm7
movaps -0x88(%r11),%xmm8
movaps -0x78(%r11),%xmm9
movaps -0x68(%r11),%xmm10
movaps -0x58(%r11),%xmm11
movaps -0x48(%r11),%xmm12
movaps -0x38(%r11),%xmm13
movaps -0x28(%r11),%xmm14
movaps -0x18(%r11),%xmm15
.LSEH_end_rsaz_1024_gather5:
___
$code.=<<___;
lea (%r11),%rsp
ret
.size rsaz_1024_gather5_avx2,.-rsaz_1024_gather5_avx2
___
@@ -1708,8 +1752,10 @@ $code.=<<___;
.long 0,2,4,6,7,7,7,7
.Lgather_permd:
.long 0,7,1,7,2,7,3,7
.Lgather_table:
.byte 0,0,0,0,0,0,0,0, 0xff,0,0,0,0,0,0,0
.Linc:
.long 0,0,0,0, 1,1,1,1
.long 2,2,2,2, 3,3,3,3
.long 4,4,4,4, 4,4,4,4
.align 64
___
@@ -1837,18 +1883,19 @@ rsaz_se_handler:
.rva rsaz_se_handler
.rva .Lmul_1024_body,.Lmul_1024_epilogue
.LSEH_info_rsaz_1024_gather5:
.byte 0x01,0x33,0x16,0x00
.byte 0x36,0xf8,0x09,0x00 #vmovaps 0x90(rsp),xmm15
.byte 0x31,0xe8,0x08,0x00 #vmovaps 0x80(rsp),xmm14
.byte 0x2c,0xd8,0x07,0x00 #vmovaps 0x70(rsp),xmm13
.byte 0x27,0xc8,0x06,0x00 #vmovaps 0x60(rsp),xmm12
.byte 0x22,0xb8,0x05,0x00 #vmovaps 0x50(rsp),xmm11
.byte 0x1d,0xa8,0x04,0x00 #vmovaps 0x40(rsp),xmm10
.byte 0x18,0x98,0x03,0x00 #vmovaps 0x30(rsp),xmm9
.byte 0x13,0x88,0x02,0x00 #vmovaps 0x20(rsp),xmm8
.byte 0x0e,0x78,0x01,0x00 #vmovaps 0x10(rsp),xmm7
.byte 0x09,0x68,0x00,0x00 #vmovaps 0x00(rsp),xmm6
.byte 0x04,0x01,0x15,0x00 #sub rsp,0xa8
.byte 0x01,0x36,0x17,0x0b
.byte 0x36,0xf8,0x09,0x00 # vmovaps 0x90(rsp),xmm15
.byte 0x31,0xe8,0x08,0x00 # vmovaps 0x80(rsp),xmm14
.byte 0x2c,0xd8,0x07,0x00 # vmovaps 0x70(rsp),xmm13
.byte 0x27,0xc8,0x06,0x00 # vmovaps 0x60(rsp),xmm12
.byte 0x22,0xb8,0x05,0x00 # vmovaps 0x50(rsp),xmm11
.byte 0x1d,0xa8,0x04,0x00 # vmovaps 0x40(rsp),xmm10
.byte 0x18,0x98,0x03,0x00 # vmovaps 0x30(rsp),xmm9
.byte 0x13,0x88,0x02,0x00 # vmovaps 0x20(rsp),xmm8
.byte 0x0e,0x78,0x01,0x00 # vmovaps 0x10(rsp),xmm7
.byte 0x09,0x68,0x00,0x00 # vmovaps 0x00(rsp),xmm6
.byte 0x04,0x01,0x15,0x00 # sub rsp,0xa8
.byte 0x00,0xb3,0x00,0x00 # set_frame r11
___
}
Regular → Executable
+297 -103
View File
@@ -98,25 +98,12 @@ die "can't locate x86_64-xlate.pl";
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT=*OUT;
if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
$addx = ($1>=2.23);
}
if (!$addx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
`nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
$addx = ($1>=2.10);
}
if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
`ml64 2>&1` =~ /Version ([0-9]+)\./) {
$addx = ($1>=12);
}
if (!$addx && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([3-9])\.([0-9]+)/) {
my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10
$addx = ($ver>=3.03);
}
# 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. $addx goes up to 1.
$addx = 0;
($out, $inp, $mod) = ("%rdi", "%rsi", "%rbp"); # common internal API
{
@@ -915,9 +902,76 @@ rsaz_512_mul_gather4:
push %r14
push %r15
mov $pwr, $pwr
subq \$128+24, %rsp
subq \$`128+24+($win64?0xb0:0)`, %rsp
___
$code.=<<___ if ($win64);
movaps %xmm6,0xa0(%rsp)
movaps %xmm7,0xb0(%rsp)
movaps %xmm8,0xc0(%rsp)
movaps %xmm9,0xd0(%rsp)
movaps %xmm10,0xe0(%rsp)
movaps %xmm11,0xf0(%rsp)
movaps %xmm12,0x100(%rsp)
movaps %xmm13,0x110(%rsp)
movaps %xmm14,0x120(%rsp)
movaps %xmm15,0x130(%rsp)
___
$code.=<<___;
.Lmul_gather4_body:
movd $pwr,%xmm8
movdqa .Linc+16(%rip),%xmm1 # 00000002000000020000000200000002
movdqa .Linc(%rip),%xmm0 # 00000001000000010000000000000000
pshufd \$0,%xmm8,%xmm8 # broadcast $power
movdqa %xmm1,%xmm7
movdqa %xmm1,%xmm2
___
########################################################################
# calculate mask by comparing 0..15 to $power
#
for($i=0;$i<4;$i++) {
$code.=<<___;
paddd %xmm`$i`,%xmm`$i+1`
pcmpeqd %xmm8,%xmm`$i`
movdqa %xmm7,%xmm`$i+3`
___
}
for(;$i<7;$i++) {
$code.=<<___;
paddd %xmm`$i`,%xmm`$i+1`
pcmpeqd %xmm8,%xmm`$i`
___
}
$code.=<<___;
pcmpeqd %xmm8,%xmm7
movdqa 16*0($bp),%xmm8
movdqa 16*1($bp),%xmm9
movdqa 16*2($bp),%xmm10
movdqa 16*3($bp),%xmm11
pand %xmm0,%xmm8
movdqa 16*4($bp),%xmm12
pand %xmm1,%xmm9
movdqa 16*5($bp),%xmm13
pand %xmm2,%xmm10
movdqa 16*6($bp),%xmm14
pand %xmm3,%xmm11
movdqa 16*7($bp),%xmm15
leaq 128($bp), %rbp
pand %xmm4,%xmm12
pand %xmm5,%xmm13
pand %xmm6,%xmm14
pand %xmm7,%xmm15
por %xmm10,%xmm8
por %xmm11,%xmm9
por %xmm12,%xmm8
por %xmm13,%xmm9
por %xmm14,%xmm8
por %xmm15,%xmm9
por %xmm9,%xmm8
pshufd \$0x4e,%xmm8,%xmm9
por %xmm9,%xmm8
___
$code.=<<___ if ($addx);
movl \$0x80100,%r11d
@@ -926,45 +980,38 @@ $code.=<<___ if ($addx);
je .Lmulx_gather
___
$code.=<<___;
movl 64($bp,$pwr,4), %eax
movq $out, %xmm0 # off-load arguments
movl ($bp,$pwr,4), %ebx
movq $mod, %xmm1
movq $n0, 128(%rsp)
movq %xmm8,%rbx
movq $n0, 128(%rsp) # off-load arguments
movq $out, 128+8(%rsp)
movq $mod, 128+16(%rsp)
shlq \$32, %rax
or %rax, %rbx
movq ($ap), %rax
movq 8($ap), %rcx
leaq 128($bp,$pwr,4), %rbp
mulq %rbx # 0 iteration
movq %rax, (%rsp)
movq %rcx, %rax
movq %rdx, %r8
mulq %rbx
movd (%rbp), %xmm4
addq %rax, %r8
movq 16($ap), %rax
movq %rdx, %r9
adcq \$0, %r9
mulq %rbx
movd 64(%rbp), %xmm5
addq %rax, %r9
movq 24($ap), %rax
movq %rdx, %r10
adcq \$0, %r10
mulq %rbx
pslldq \$4, %xmm5
addq %rax, %r10
movq 32($ap), %rax
movq %rdx, %r11
adcq \$0, %r11
mulq %rbx
por %xmm5, %xmm4
addq %rax, %r11
movq 40($ap), %rax
movq %rdx, %r12
@@ -977,14 +1024,12 @@ $code.=<<___;
adcq \$0, %r13
mulq %rbx
leaq 128(%rbp), %rbp
addq %rax, %r13
movq 56($ap), %rax
movq %rdx, %r14
adcq \$0, %r14
mulq %rbx
movq %xmm4, %rbx
addq %rax, %r14
movq ($ap), %rax
movq %rdx, %r15
@@ -996,6 +1041,35 @@ $code.=<<___;
.align 32
.Loop_mul_gather:
movdqa 16*0(%rbp),%xmm8
movdqa 16*1(%rbp),%xmm9
movdqa 16*2(%rbp),%xmm10
movdqa 16*3(%rbp),%xmm11
pand %xmm0,%xmm8
movdqa 16*4(%rbp),%xmm12
pand %xmm1,%xmm9
movdqa 16*5(%rbp),%xmm13
pand %xmm2,%xmm10
movdqa 16*6(%rbp),%xmm14
pand %xmm3,%xmm11
movdqa 16*7(%rbp),%xmm15
leaq 128(%rbp), %rbp
pand %xmm4,%xmm12
pand %xmm5,%xmm13
pand %xmm6,%xmm14
pand %xmm7,%xmm15
por %xmm10,%xmm8
por %xmm11,%xmm9
por %xmm12,%xmm8
por %xmm13,%xmm9
por %xmm14,%xmm8
por %xmm15,%xmm9
por %xmm9,%xmm8
pshufd \$0x4e,%xmm8,%xmm9
por %xmm9,%xmm8
movq %xmm8,%rbx
mulq %rbx
addq %rax, %r8
movq 8($ap), %rax
@@ -1004,7 +1078,6 @@ $code.=<<___;
adcq \$0, %r8
mulq %rbx
movd (%rbp), %xmm4
addq %rax, %r9
movq 16($ap), %rax
adcq \$0, %rdx
@@ -1013,7 +1086,6 @@ $code.=<<___;
adcq \$0, %r9
mulq %rbx
movd 64(%rbp), %xmm5
addq %rax, %r10
movq 24($ap), %rax
adcq \$0, %rdx
@@ -1022,7 +1094,6 @@ $code.=<<___;
adcq \$0, %r10
mulq %rbx
pslldq \$4, %xmm5
addq %rax, %r11
movq 32($ap), %rax
adcq \$0, %rdx
@@ -1031,7 +1102,6 @@ $code.=<<___;
adcq \$0, %r11
mulq %rbx
por %xmm5, %xmm4
addq %rax, %r12
movq 40($ap), %rax
adcq \$0, %rdx
@@ -1056,7 +1126,6 @@ $code.=<<___;
adcq \$0, %r14
mulq %rbx
movq %xmm4, %rbx
addq %rax, %r15
movq ($ap), %rax
adcq \$0, %rdx
@@ -1064,7 +1133,6 @@ $code.=<<___;
movq %rdx, %r15
adcq \$0, %r15
leaq 128(%rbp), %rbp
leaq 8(%rdi), %rdi
decl %ecx
@@ -1079,8 +1147,8 @@ $code.=<<___;
movq %r14, 48(%rdi)
movq %r15, 56(%rdi)
movq %xmm0, $out
movq %xmm1, %rbp
movq 128+8(%rsp), $out
movq 128+16(%rsp), %rbp
movq (%rsp), %r8
movq 8(%rsp), %r9
@@ -1098,45 +1166,37 @@ $code.=<<___ if ($addx);
.align 32
.Lmulx_gather:
mov 64($bp,$pwr,4), %eax
movq $out, %xmm0 # off-load arguments
lea 128($bp,$pwr,4), %rbp
mov ($bp,$pwr,4), %edx
movq $mod, %xmm1
mov $n0, 128(%rsp)
movq %xmm8,%rdx
mov $n0, 128(%rsp) # off-load arguments
mov $out, 128+8(%rsp)
mov $mod, 128+16(%rsp)
shl \$32, %rax
or %rax, %rdx
mulx ($ap), %rbx, %r8 # 0 iteration
mov %rbx, (%rsp)
xor %edi, %edi # cf=0, of=0
mulx 8($ap), %rax, %r9
movd (%rbp), %xmm4
mulx 16($ap), %rbx, %r10
movd 64(%rbp), %xmm5
adcx %rax, %r8
mulx 24($ap), %rax, %r11
pslldq \$4, %xmm5
adcx %rbx, %r9
mulx 32($ap), %rbx, %r12
por %xmm5, %xmm4
adcx %rax, %r10
mulx 40($ap), %rax, %r13
adcx %rbx, %r11
mulx 48($ap), %rbx, %r14
lea 128(%rbp), %rbp
adcx %rax, %r12
mulx 56($ap), %rax, %r15
movq %xmm4, %rdx
adcx %rbx, %r13
adcx %rax, %r14
.byte 0x67
mov %r8, %rbx
adcx %rdi, %r15 # %rdi is 0
@@ -1145,24 +1205,48 @@ $code.=<<___ if ($addx);
.align 32
.Loop_mulx_gather:
mulx ($ap), %rax, %r8
movdqa 16*0(%rbp),%xmm8
movdqa 16*1(%rbp),%xmm9
movdqa 16*2(%rbp),%xmm10
movdqa 16*3(%rbp),%xmm11
pand %xmm0,%xmm8
movdqa 16*4(%rbp),%xmm12
pand %xmm1,%xmm9
movdqa 16*5(%rbp),%xmm13
pand %xmm2,%xmm10
movdqa 16*6(%rbp),%xmm14
pand %xmm3,%xmm11
movdqa 16*7(%rbp),%xmm15
leaq 128(%rbp), %rbp
pand %xmm4,%xmm12
pand %xmm5,%xmm13
pand %xmm6,%xmm14
pand %xmm7,%xmm15
por %xmm10,%xmm8
por %xmm11,%xmm9
por %xmm12,%xmm8
por %xmm13,%xmm9
por %xmm14,%xmm8
por %xmm15,%xmm9
por %xmm9,%xmm8
pshufd \$0x4e,%xmm8,%xmm9
por %xmm9,%xmm8
movq %xmm8,%rdx
.byte 0xc4,0x62,0xfb,0xf6,0x86,0x00,0x00,0x00,0x00 # mulx ($ap), %rax, %r8
adcx %rax, %rbx
adox %r9, %r8
mulx 8($ap), %rax, %r9
.byte 0x66,0x0f,0x6e,0xa5,0x00,0x00,0x00,0x00 # movd (%rbp), %xmm4
adcx %rax, %r8
adox %r10, %r9
mulx 16($ap), %rax, %r10
movd 64(%rbp), %xmm5
lea 128(%rbp), %rbp
adcx %rax, %r9
adox %r11, %r10
.byte 0xc4,0x62,0xfb,0xf6,0x9e,0x18,0x00,0x00,0x00 # mulx 24($ap), %rax, %r11
pslldq \$4, %xmm5
por %xmm5, %xmm4
adcx %rax, %r10
adox %r12, %r11
@@ -1176,10 +1260,10 @@ $code.=<<___ if ($addx);
.byte 0xc4,0x62,0xfb,0xf6,0xb6,0x30,0x00,0x00,0x00 # mulx 48($ap), %rax, %r14
adcx %rax, %r13
.byte 0x67
adox %r15, %r14
mulx 56($ap), %rax, %r15
movq %xmm4, %rdx
mov %rbx, 64(%rsp,%rcx,8)
adcx %rax, %r14
adox %rdi, %r15
@@ -1198,10 +1282,10 @@ $code.=<<___ if ($addx);
mov %r14, 64+48(%rsp)
mov %r15, 64+56(%rsp)
movq %xmm0, $out
movq %xmm1, %rbp
mov 128(%rsp), %rdx # pull arguments
mov 128+8(%rsp), $out
mov 128+16(%rsp), %rbp
mov 128(%rsp), %rdx # pull $n0
mov (%rsp), %r8
mov 8(%rsp), %r9
mov 16(%rsp), %r10
@@ -1229,6 +1313,21 @@ $code.=<<___;
call __rsaz_512_subtract
leaq 128+24+48(%rsp), %rax
___
$code.=<<___ if ($win64);
movaps 0xa0-0xc8(%rax),%xmm6
movaps 0xb0-0xc8(%rax),%xmm7
movaps 0xc0-0xc8(%rax),%xmm8
movaps 0xd0-0xc8(%rax),%xmm9
movaps 0xe0-0xc8(%rax),%xmm10
movaps 0xf0-0xc8(%rax),%xmm11
movaps 0x100-0xc8(%rax),%xmm12
movaps 0x110-0xc8(%rax),%xmm13
movaps 0x120-0xc8(%rax),%xmm14
movaps 0x130-0xc8(%rax),%xmm15
lea 0xb0(%rax),%rax
___
$code.=<<___;
movq -48(%rax), %r15
movq -40(%rax), %r14
movq -32(%rax), %r13
@@ -1258,7 +1357,7 @@ rsaz_512_mul_scatter4:
mov $pwr, $pwr
subq \$128+24, %rsp
.Lmul_scatter4_body:
leaq ($tbl,$pwr,4), $tbl
leaq ($tbl,$pwr,8), $tbl
movq $out, %xmm0 # off-load arguments
movq $mod, %xmm1
movq $tbl, %xmm2
@@ -1329,30 +1428,14 @@ $code.=<<___;
call __rsaz_512_subtract
movl %r8d, 64*0($inp) # scatter
shrq \$32, %r8
movl %r9d, 64*2($inp)
shrq \$32, %r9
movl %r10d, 64*4($inp)
shrq \$32, %r10
movl %r11d, 64*6($inp)
shrq \$32, %r11
movl %r12d, 64*8($inp)
shrq \$32, %r12
movl %r13d, 64*10($inp)
shrq \$32, %r13
movl %r14d, 64*12($inp)
shrq \$32, %r14
movl %r15d, 64*14($inp)
shrq \$32, %r15
movl %r8d, 64*1($inp)
movl %r9d, 64*3($inp)
movl %r10d, 64*5($inp)
movl %r11d, 64*7($inp)
movl %r12d, 64*9($inp)
movl %r13d, 64*11($inp)
movl %r14d, 64*13($inp)
movl %r15d, 64*15($inp)
movq %r8, 128*0($inp) # scatter
movq %r9, 128*1($inp)
movq %r10, 128*2($inp)
movq %r11, 128*3($inp)
movq %r12, 128*4($inp)
movq %r13, 128*5($inp)
movq %r14, 128*6($inp)
movq %r15, 128*7($inp)
leaq 128+24+48(%rsp), %rax
movq -48(%rax), %r15
@@ -1956,16 +2039,14 @@ $code.=<<___;
.type rsaz_512_scatter4,\@abi-omnipotent
.align 16
rsaz_512_scatter4:
leaq ($out,$power,4), $out
leaq ($out,$power,8), $out
movl \$8, %r9d
jmp .Loop_scatter
.align 16
.Loop_scatter:
movq ($inp), %rax
leaq 8($inp), $inp
movl %eax, ($out)
shrq \$32, %rax
movl %eax, 64($out)
movq %rax, ($out)
leaq 128($out), $out
decl %r9d
jnz .Loop_scatter
@@ -1976,22 +2057,106 @@ rsaz_512_scatter4:
.type rsaz_512_gather4,\@abi-omnipotent
.align 16
rsaz_512_gather4:
leaq ($inp,$power,4), $inp
___
$code.=<<___ if ($win64);
.LSEH_begin_rsaz_512_gather4:
.byte 0x48,0x81,0xec,0xa8,0x00,0x00,0x00 # sub $0xa8,%rsp
.byte 0x0f,0x29,0x34,0x24 # movaps %xmm6,(%rsp)
.byte 0x0f,0x29,0x7c,0x24,0x10 # movaps %xmm7,0x10(%rsp)
.byte 0x44,0x0f,0x29,0x44,0x24,0x20 # movaps %xmm8,0x20(%rsp)
.byte 0x44,0x0f,0x29,0x4c,0x24,0x30 # movaps %xmm9,0x30(%rsp)
.byte 0x44,0x0f,0x29,0x54,0x24,0x40 # movaps %xmm10,0x40(%rsp)
.byte 0x44,0x0f,0x29,0x5c,0x24,0x50 # movaps %xmm11,0x50(%rsp)
.byte 0x44,0x0f,0x29,0x64,0x24,0x60 # movaps %xmm12,0x60(%rsp)
.byte 0x44,0x0f,0x29,0x6c,0x24,0x70 # movaps %xmm13,0x70(%rsp)
.byte 0x44,0x0f,0x29,0xb4,0x24,0x80,0,0,0 # movaps %xmm14,0x80(%rsp)
.byte 0x44,0x0f,0x29,0xbc,0x24,0x90,0,0,0 # movaps %xmm15,0x90(%rsp)
___
$code.=<<___;
movd $power,%xmm8
movdqa .Linc+16(%rip),%xmm1 # 00000002000000020000000200000002
movdqa .Linc(%rip),%xmm0 # 00000001000000010000000000000000
pshufd \$0,%xmm8,%xmm8 # broadcast $power
movdqa %xmm1,%xmm7
movdqa %xmm1,%xmm2
___
########################################################################
# calculate mask by comparing 0..15 to $power
#
for($i=0;$i<4;$i++) {
$code.=<<___;
paddd %xmm`$i`,%xmm`$i+1`
pcmpeqd %xmm8,%xmm`$i`
movdqa %xmm7,%xmm`$i+3`
___
}
for(;$i<7;$i++) {
$code.=<<___;
paddd %xmm`$i`,%xmm`$i+1`
pcmpeqd %xmm8,%xmm`$i`
___
}
$code.=<<___;
pcmpeqd %xmm8,%xmm7
movl \$8, %r9d
jmp .Loop_gather
.align 16
.Loop_gather:
movl ($inp), %eax
movl 64($inp), %r8d
movdqa 16*0($inp),%xmm8
movdqa 16*1($inp),%xmm9
movdqa 16*2($inp),%xmm10
movdqa 16*3($inp),%xmm11
pand %xmm0,%xmm8
movdqa 16*4($inp),%xmm12
pand %xmm1,%xmm9
movdqa 16*5($inp),%xmm13
pand %xmm2,%xmm10
movdqa 16*6($inp),%xmm14
pand %xmm3,%xmm11
movdqa 16*7($inp),%xmm15
leaq 128($inp), $inp
shlq \$32, %r8
or %r8, %rax
movq %rax, ($out)
pand %xmm4,%xmm12
pand %xmm5,%xmm13
pand %xmm6,%xmm14
pand %xmm7,%xmm15
por %xmm10,%xmm8
por %xmm11,%xmm9
por %xmm12,%xmm8
por %xmm13,%xmm9
por %xmm14,%xmm8
por %xmm15,%xmm9
por %xmm9,%xmm8
pshufd \$0x4e,%xmm8,%xmm9
por %xmm9,%xmm8
movq %xmm8,($out)
leaq 8($out), $out
decl %r9d
jnz .Loop_gather
___
$code.=<<___ if ($win64);
movaps 0x00(%rsp),%xmm6
movaps 0x10(%rsp),%xmm7
movaps 0x20(%rsp),%xmm8
movaps 0x30(%rsp),%xmm9
movaps 0x40(%rsp),%xmm10
movaps 0x50(%rsp),%xmm11
movaps 0x60(%rsp),%xmm12
movaps 0x70(%rsp),%xmm13
movaps 0x80(%rsp),%xmm14
movaps 0x90(%rsp),%xmm15
add \$0xa8,%rsp
___
$code.=<<___;
ret
.LSEH_end_rsaz_512_gather4:
.size rsaz_512_gather4,.-rsaz_512_gather4
.align 64
.Linc:
.long 0,0, 1,1
.long 2,2, 2,2
___
}
@@ -2039,6 +2204,18 @@ se_handler:
lea 128+24+48(%rax),%rax
lea .Lmul_gather4_epilogue(%rip),%rbx
cmp %r10,%rbx
jne .Lse_not_in_mul_gather4
lea 0xb0(%rax),%rax
lea -48-0xa8(%rax),%rsi
lea 512($context),%rdi
mov \$20,%ecx
.long 0xa548f3fc # cld; rep movsq
.Lse_not_in_mul_gather4:
mov -8(%rax),%rbx
mov -16(%rax),%rbp
mov -24(%rax),%r12
@@ -2090,7 +2267,7 @@ se_handler:
pop %rdi
pop %rsi
ret
.size sqr_handler,.-sqr_handler
.size se_handler,.-se_handler
.section .pdata
.align 4
@@ -2114,6 +2291,10 @@ se_handler:
.rva .LSEH_end_rsaz_512_mul_by_one
.rva .LSEH_info_rsaz_512_mul_by_one
.rva .LSEH_begin_rsaz_512_gather4
.rva .LSEH_end_rsaz_512_gather4
.rva .LSEH_info_rsaz_512_gather4
.section .xdata
.align 8
.LSEH_info_rsaz_512_sqr:
@@ -2136,6 +2317,19 @@ se_handler:
.byte 9,0,0,0
.rva se_handler
.rva .Lmul_by_one_body,.Lmul_by_one_epilogue # HandlerData[]
.LSEH_info_rsaz_512_gather4:
.byte 0x01,0x46,0x16,0x00
.byte 0x46,0xf8,0x09,0x00 # vmovaps 0x90(rsp),xmm15
.byte 0x3d,0xe8,0x08,0x00 # vmovaps 0x80(rsp),xmm14
.byte 0x34,0xd8,0x07,0x00 # vmovaps 0x70(rsp),xmm13
.byte 0x2e,0xc8,0x06,0x00 # vmovaps 0x60(rsp),xmm12
.byte 0x28,0xb8,0x05,0x00 # vmovaps 0x50(rsp),xmm11
.byte 0x22,0xa8,0x04,0x00 # vmovaps 0x40(rsp),xmm10
.byte 0x1c,0x98,0x03,0x00 # vmovaps 0x30(rsp),xmm9
.byte 0x16,0x88,0x02,0x00 # vmovaps 0x20(rsp),xmm8
.byte 0x10,0x78,0x01,0x00 # vmovaps 0x10(rsp),xmm7
.byte 0x0b,0x68,0x00,0x00 # vmovaps 0x00(rsp),xmm6
.byte 0x07,0x01,0x15,0x00 # sub rsp,0xa8
___
}
+8 -76
View File
@@ -1,9 +1,3 @@
#include <openssl/bn.h>
#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && !defined(OPENSSL_WINDOWS)
#include "../internal.h"
/* x86_64 BIGNUM accelerator version 0.1, December 2002.
*
* Implemented by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
@@ -56,7 +50,13 @@
* machine.
*/
/* TODO(davidben): Get this file working on Windows x64. */
#include <openssl/bn.h>
/* TODO(davidben): Get this file working on Windows x64. */
#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && defined(__GNUC__)
#include "../internal.h"
#undef mul
#undef mul_add
@@ -186,14 +186,6 @@ void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) {
}
}
BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) {
BN_ULONG ret, waste;
asm("divq %4" : "=a"(ret), "=d"(waste) : "a"(l), "d"(h), "g"(d) : "cc");
return ret;
}
BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
int n) {
BN_ULONG ret;
@@ -220,7 +212,6 @@ BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
return ret & 1;
}
#ifndef SIMICS
BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
int n) {
BN_ULONG ret;
@@ -246,65 +237,6 @@ BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
return ret & 1;
}
#else
/* Simics 1.4<7 has buggy sbbq:-( */
#define BN_MASK2 0xffffffffffffffffL
BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) {
BN_ULONG t1, t2;
int c = 0;
if (n <= 0) {
return (BN_ULONG)0;
}
for (;;) {
t1 = a[0];
t2 = b[0];
r[0] = (t1 - t2 - c) & BN_MASK2;
if (t1 != t2) {
c = (t1 < t2);
}
if (--n <= 0) {
break;
}
t1 = a[1];
t2 = b[1];
r[1] = (t1 - t2 - c) & BN_MASK2;
if (t1 != t2) {
c = (t1 < t2);
}
if (--n <= 0) {
break;
}
t1 = a[2];
t2 = b[2];
r[2] = (t1 - t2 - c) & BN_MASK2;
if (t1 != t2) {
c = (t1 < t2);
}
if (--n <= 0) {
break;
}
t1 = a[3];
t2 = b[3];
r[3] = (t1 - t2 - c) & BN_MASK2;
if (t1 != t2) {
c = (t1 < t2);
}
if (--n <= 0) {
break;
}
a += 4;
b += 4;
r += 4;
}
return c;
}
#endif
/* mul_add_c(a,b,c0,c1,c2) -- c+=a*b for three word number c=(c2,c1,c0) */
/* mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) */
@@ -596,4 +528,4 @@ void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) {
r[7] = c2;
}
#endif /* !NO_ASM && X86_64 && !WINDOWS */
#endif /* !NO_ASM && X86_64 && __GNUC__ */
Regular → Executable
+142 -113
View File
@@ -53,20 +53,12 @@ die "can't locate x86_64-xlate.pl";
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT=*OUT;
if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
$addx = ($1>=2.23);
}
if (!$addx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
`nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
$addx = ($1>=2.10);
}
if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
`ml64 2>&1` =~ /Version ([0-9]+)\./) {
$addx = ($1>=12);
}
# 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 option after testing. $addx goes up to 1.
$addx = 0;
# int bn_mul_mont(
$rp="%rdi"; # BN_ULONG *rp,
@@ -769,100 +761,126 @@ bn_sqr8x_mont:
# 4096. this is done to allow memory disambiguation logic
# do its job.
#
lea -64(%rsp,$num,4),%r11
lea -64(%rsp,$num,2),%r11
mov ($n0),$n0 # *n0
sub $aptr,%r11
and \$4095,%r11
cmp %r11,%r10
jb .Lsqr8x_sp_alt
sub %r11,%rsp # align with $aptr
lea -64(%rsp,$num,4),%rsp # alloca(frame+4*$num)
lea -64(%rsp,$num,2),%rsp # alloca(frame+2*$num)
jmp .Lsqr8x_sp_done
.align 32
.Lsqr8x_sp_alt:
lea 4096-64(,$num,4),%r10 # 4096-frame-4*$num
lea -64(%rsp,$num,4),%rsp # alloca(frame+4*$num)
lea 4096-64(,$num,2),%r10 # 4096-frame-2*$num
lea -64(%rsp,$num,2),%rsp # alloca(frame+2*$num)
sub %r10,%r11
mov \$0,%r10
cmovc %r10,%r11
sub %r11,%rsp
.Lsqr8x_sp_done:
and \$-64,%rsp
mov $num,%r10
mov $num,%r10
neg $num
lea 64(%rsp,$num,2),%r11 # copy of modulus
mov $n0, 32(%rsp)
mov %rax, 40(%rsp) # save original %rsp
.Lsqr8x_body:
mov $num,$i
movq %r11, %xmm2 # save pointer to modulus copy
shr \$3+2,$i
mov OPENSSL_ia32cap_P+8(%rip),%eax
jmp .Lsqr8x_copy_n
.align 32
.Lsqr8x_copy_n:
movq 8*0($nptr),%xmm0
movq 8*1($nptr),%xmm1
movq 8*2($nptr),%xmm3
movq 8*3($nptr),%xmm4
lea 8*4($nptr),$nptr
movdqa %xmm0,16*0(%r11)
movdqa %xmm1,16*1(%r11)
movdqa %xmm3,16*2(%r11)
movdqa %xmm4,16*3(%r11)
lea 16*4(%r11),%r11
dec $i
jnz .Lsqr8x_copy_n
movq $nptr, %xmm2 # save pointer to modulus
pxor %xmm0,%xmm0
movq $rptr,%xmm1 # save $rptr
movq %r10, %xmm3 # -$num
___
$code.=<<___ if ($addx);
mov OPENSSL_ia32cap_P+8(%rip),%eax
and \$0x80100,%eax
cmp \$0x80100,%eax
jne .Lsqr8x_nox
call bn_sqrx8x_internal # see x86_64-mont5 module
pxor %xmm0,%xmm0
lea 48(%rsp),%rax
lea 64(%rsp,$num,2),%rdx
shr \$3+2,$num
mov 40(%rsp),%rsi # restore %rsp
jmp .Lsqr8x_zero
# %rax top-most carry
# %rbp nptr
# %rcx -8*num
# %r8 end of tp[2*num]
lea (%r8,%rcx),%rbx
mov %rcx,$num
mov %rcx,%rdx
movq %xmm1,$rptr
sar \$3+2,%rcx # %cf=0
jmp .Lsqr8x_sub
.align 32
.Lsqr8x_nox:
___
$code.=<<___;
call bn_sqr8x_internal # see x86_64-mont5 module
pxor %xmm0,%xmm0
lea 48(%rsp),%rax
lea 64(%rsp,$num,2),%rdx
shr \$3+2,$num
mov 40(%rsp),%rsi # restore %rsp
jmp .Lsqr8x_zero
# %rax top-most carry
# %rbp nptr
# %r8 -8*num
# %rdi end of tp[2*num]
lea (%rdi,$num),%rbx
mov $num,%rcx
mov $num,%rdx
movq %xmm1,$rptr
sar \$3+2,%rcx # %cf=0
jmp .Lsqr8x_sub
.align 32
.Lsqr8x_zero:
movdqa %xmm0,16*0(%rax) # wipe t
movdqa %xmm0,16*1(%rax)
movdqa %xmm0,16*2(%rax)
movdqa %xmm0,16*3(%rax)
lea 16*4(%rax),%rax
movdqa %xmm0,16*0(%rdx) # wipe n
movdqa %xmm0,16*1(%rdx)
movdqa %xmm0,16*2(%rdx)
movdqa %xmm0,16*3(%rdx)
lea 16*4(%rdx),%rdx
dec $num
jnz .Lsqr8x_zero
.Lsqr8x_sub:
mov 8*0(%rbx),%r12
mov 8*1(%rbx),%r13
mov 8*2(%rbx),%r14
mov 8*3(%rbx),%r15
lea 8*4(%rbx),%rbx
sbb 8*0(%rbp),%r12
sbb 8*1(%rbp),%r13
sbb 8*2(%rbp),%r14
sbb 8*3(%rbp),%r15
lea 8*4(%rbp),%rbp
mov %r12,8*0($rptr)
mov %r13,8*1($rptr)
mov %r14,8*2($rptr)
mov %r15,8*3($rptr)
lea 8*4($rptr),$rptr
inc %rcx # preserves %cf
jnz .Lsqr8x_sub
sbb \$0,%rax # top-most carry
lea (%rbx,$num),%rbx # rewind
lea ($rptr,$num),$rptr # rewind
movq %rax,%xmm1
pxor %xmm0,%xmm0
pshufd \$0,%xmm1,%xmm1
mov 40(%rsp),%rsi # restore %rsp
jmp .Lsqr8x_cond_copy
.align 32
.Lsqr8x_cond_copy:
movdqa 16*0(%rbx),%xmm2
movdqa 16*1(%rbx),%xmm3
lea 16*2(%rbx),%rbx
movdqu 16*0($rptr),%xmm4
movdqu 16*1($rptr),%xmm5
lea 16*2($rptr),$rptr
movdqa %xmm0,-16*2(%rbx) # zero tp
movdqa %xmm0,-16*1(%rbx)
movdqa %xmm0,-16*2(%rbx,%rdx)
movdqa %xmm0,-16*1(%rbx,%rdx)
pcmpeqd %xmm1,%xmm0
pand %xmm1,%xmm2
pand %xmm1,%xmm3
pand %xmm0,%xmm4
pand %xmm0,%xmm5
pxor %xmm0,%xmm0
por %xmm2,%xmm4
por %xmm3,%xmm5
movdqu %xmm4,-16*2($rptr)
movdqu %xmm5,-16*1($rptr)
add \$32,$num
jnz .Lsqr8x_cond_copy
mov \$1,%rax
mov -48(%rsi),%r15
@@ -1129,64 +1147,75 @@ $code.=<<___;
adc $zero,%r15 # modulo-scheduled
sub 0*8($tptr),$zero # pull top-most carry
adc %r15,%r14
mov -8($nptr),$mi
sbb %r15,%r15 # top-most carry
mov %r14,-1*8($tptr)
cmp 16(%rsp),$bptr
jne .Lmulx4x_outer
sub %r14,$mi # compare top-most words
sbb $mi,$mi
or $mi,%r15
neg $num
xor %rdx,%rdx
mov 32(%rsp),$rptr # restore rp
lea 64(%rsp),$tptr
pxor %xmm0,%xmm0
mov 0*8($nptr,$num),%r8
mov 1*8($nptr,$num),%r9
neg %r8
jmp .Lmulx4x_sub_entry
sub $num,$nptr # rewind $nptr
neg %r15
mov $num,%rdx
shr \$3+2,$num # %cf=0
mov 32(%rsp),$rptr # restore rp
jmp .Lmulx4x_sub
.align 32
.Lmulx4x_sub:
mov 0*8($nptr,$num),%r8
mov 1*8($nptr,$num),%r9
not %r8
.Lmulx4x_sub_entry:
mov 2*8($nptr,$num),%r10
not %r9
and %r15,%r8
mov 3*8($nptr,$num),%r11
not %r10
and %r15,%r9
not %r11
and %r15,%r10
and %r15,%r11
neg %rdx # mov %rdx,%cf
adc 0*8($tptr),%r8
adc 1*8($tptr),%r9
movdqa %xmm0,($tptr)
adc 2*8($tptr),%r10
adc 3*8($tptr),%r11
movdqa %xmm0,16($tptr)
lea 4*8($tptr),$tptr
sbb %rdx,%rdx # mov %cf,%rdx
mov %r8,0*8($rptr)
mov %r9,1*8($rptr)
mov %r10,2*8($rptr)
mov %r11,3*8($rptr)
lea 4*8($rptr),$rptr
add \$32,$num
mov 8*0($tptr),%r11
mov 8*1($tptr),%r12
mov 8*2($tptr),%r13
mov 8*3($tptr),%r14
lea 8*4($tptr),$tptr
sbb 8*0($nptr),%r11
sbb 8*1($nptr),%r12
sbb 8*2($nptr),%r13
sbb 8*3($nptr),%r14
lea 8*4($nptr),$nptr
mov %r11,8*0($rptr)
mov %r12,8*1($rptr)
mov %r13,8*2($rptr)
mov %r14,8*3($rptr)
lea 8*4($rptr),$rptr
dec $num # preserves %cf
jnz .Lmulx4x_sub
sbb \$0,%r15 # top-most carry
lea 64(%rsp),$tptr
sub %rdx,$rptr # rewind
movq %r15,%xmm1
pxor %xmm0,%xmm0
pshufd \$0,%xmm1,%xmm1
mov 40(%rsp),%rsi # restore %rsp
jmp .Lmulx4x_cond_copy
.align 32
.Lmulx4x_cond_copy:
movdqa 16*0($tptr),%xmm2
movdqa 16*1($tptr),%xmm3
lea 16*2($tptr),$tptr
movdqu 16*0($rptr),%xmm4
movdqu 16*1($rptr),%xmm5
lea 16*2($rptr),$rptr
movdqa %xmm0,-16*2($tptr) # zero tp
movdqa %xmm0,-16*1($tptr)
pcmpeqd %xmm1,%xmm0
pand %xmm1,%xmm2
pand %xmm1,%xmm3
pand %xmm0,%xmm4
pand %xmm0,%xmm5
pxor %xmm0,%xmm0
por %xmm2,%xmm4
por %xmm3,%xmm5
movdqu %xmm4,-16*2($rptr)
movdqu %xmm5,-16*1($rptr)
sub \$32,%rdx
jnz .Lmulx4x_cond_copy
mov %rdx,($tptr)
mov \$1,%rax
mov -48(%rsi),%r15
mov -40(%rsi),%r14
Regular → Executable
+745 -575
View File
File diff suppressed because it is too large Load Diff
+16 -5
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) {
@@ -267,6 +266,18 @@ int BN_set_word(BIGNUM *bn, BN_ULONG value) {
return 1;
}
int bn_set_words(BIGNUM *bn, const BN_ULONG *words, size_t num) {
if (bn_wexpand(bn, num) == NULL) {
return 0;
}
memmove(bn->d, words, num * sizeof(BN_ULONG));
/* |bn_wexpand| verified that |num| isn't too large. */
bn->top = (int)num;
bn_correct_top(bn);
bn->neg = 0;
return 1;
}
int BN_is_negative(const BIGNUM *bn) {
return bn->neg != 0;
}
@@ -296,7 +307,7 @@ BIGNUM *bn_wexpand(BIGNUM *bn, size_t words) {
return NULL;
}
a = (BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG) * words);
a = OPENSSL_malloc(sizeof(BN_ULONG) * words);
if (a == NULL) {
OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
return NULL;
+9 -22
View File
@@ -18,7 +18,7 @@
#include <openssl/err.h>
int BN_cbs2unsigned(CBS *cbs, BIGNUM *ret) {
int BN_parse_asn1_unsigned(CBS *cbs, BIGNUM *ret) {
CBS child;
if (!CBS_get_asn1(cbs, &child, CBS_ASN1_INTEGER) ||
CBS_len(&child) == 0) {
@@ -42,7 +42,7 @@ int BN_cbs2unsigned(CBS *cbs, BIGNUM *ret) {
return BN_bin2bn(CBS_data(&child), CBS_len(&child), ret) != NULL;
}
int BN_cbs2unsigned_buggy(CBS *cbs, BIGNUM *ret) {
int BN_parse_asn1_unsigned_buggy(CBS *cbs, BIGNUM *ret) {
CBS child;
if (!CBS_get_asn1(cbs, &child, CBS_ASN1_INTEGER) ||
CBS_len(&child) == 0) {
@@ -58,7 +58,7 @@ int BN_cbs2unsigned_buggy(CBS *cbs, BIGNUM *ret) {
return BN_bin2bn(CBS_data(&child), CBS_len(&child), ret) != NULL;
}
int BN_bn2cbb(CBB *cbb, const BIGNUM *bn) {
int BN_marshal_asn1(CBB *cbb, const BIGNUM *bn) {
/* Negative numbers are unsupported. */
if (BN_is_negative(bn)) {
OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
@@ -66,28 +66,15 @@ int BN_bn2cbb(CBB *cbb, const BIGNUM *bn) {
}
CBB child;
if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) {
if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER) ||
/* The number must be padded with a leading zero if the high bit would
* otherwise be set or if |bn| is zero. */
(BN_num_bits(bn) % 8 == 0 && !CBB_add_u8(&child, 0x00)) ||
!BN_bn2cbb_padded(&child, BN_num_bytes(bn), bn) ||
!CBB_flush(cbb)) {
OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR);
return 0;
}
/* The number must be padded with a leading zero if the high bit would
* otherwise be set (or |bn| is zero). */
if (BN_num_bits(bn) % 8 == 0 &&
!CBB_add_u8(&child, 0x00)) {
OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR);
return 0;
}
uint8_t *out;
if (!CBB_add_space(&child, &out, BN_num_bytes(bn))) {
OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR);
return 0;
}
BN_bn2bin(bn, out);
if (!CBB_flush(cbb)) {
OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR);
return 0;
}
return 1;
}
+142 -59
View File
@@ -76,6 +76,8 @@
#include <stdio.h>
#include <string.h>
#include <utility>
#include <openssl/bn.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
@@ -211,7 +213,7 @@ int main(int argc, char *argv[]) {
if (!sample) {
return 1;
}
if (!test_lshift(bc_file.get(), ctx.get(), bssl::move(sample))) {
if (!test_lshift(bc_file.get(), ctx.get(), std::move(sample))) {
return 1;
}
flush_fp(bc_file.get());
@@ -328,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());
@@ -423,6 +432,16 @@ static bool test_div(FILE *fp, BN_CTX *ctx) {
return false;
}
if (!BN_one(a.get())) {
return false;
}
BN_zero(b.get());
if (BN_div(d.get(), c.get(), a.get(), b.get(), ctx)) {
fprintf(stderr, "Division by zero succeeded!\n");
return false;
}
ERR_clear_error();
for (int i = 0; i < num0 + num1; i++) {
if (i < num1) {
if (!BN_rand(a.get(), 400, 0, 0) ||
@@ -491,14 +510,6 @@ static bool test_div(FILE *fp, BN_CTX *ctx) {
return false;
}
// Test the BN_div checks for division by zero.
BN_zero(b.get());
if (BN_div(d.get(), c.get(), a.get(), b.get(), ctx)) {
fprintf(stderr, "Divided by zero!\n");
return false;
}
ERR_clear_error();
return true;
}
@@ -828,18 +839,17 @@ static bool test_div_word(FILE *fp) {
}
for (int i = 0; i < num0; i++) {
BN_ULONG s;
do {
if (!BN_rand(a.get(), 512, -1, 0) ||
!BN_rand(b.get(), BN_BITS2, -1, 0)) {
return false;
}
s = b->d[0];
} while (!s);
} while (BN_is_zero(b.get()));
if (!BN_copy(b.get(), a.get())) {
return false;
}
BN_ULONG s = b->d[0];
BN_ULONG r = BN_div_word(b.get(), s);
if (r == (BN_ULONG)-1) {
return false;
@@ -882,8 +892,27 @@ static bool test_mont(FILE *fp, BN_CTX *ctx) {
ScopedBIGNUM B(BN_new());
ScopedBIGNUM n(BN_new());
ScopedBN_MONT_CTX mont(BN_MONT_CTX_new());
if (!a || !b || !c || !d || !A || !B || !n || !mont ||
!BN_rand(a.get(), 100, 0, 0) ||
if (!a || !b || !c || !d || !A || !B || !n || !mont) {
return false;
}
BN_zero(n.get());
if (BN_MONT_CTX_set(mont.get(), n.get(), ctx)) {
fprintf(stderr, "BN_MONT_CTX_set succeeded for zero modulus!\n");
return false;
}
ERR_clear_error();
if (!BN_set_word(n.get(), 16)) {
return false;
}
if (BN_MONT_CTX_set(mont.get(), n.get(), ctx)) {
fprintf(stderr, "BN_MONT_CTX_set succeeded for even modulus!\n");
return false;
}
ERR_clear_error();
if (!BN_rand(a.get(), 100, 0, 0) ||
!BN_rand(b.get(), 100, 0, 0)) {
return false;
}
@@ -924,13 +953,6 @@ static bool test_mont(FILE *fp, BN_CTX *ctx) {
}
}
BN_zero(n.get());
if (BN_MONT_CTX_set(mont.get(), n.get(), ctx)) {
fprintf(stderr, "Division by zero!\n");
return false;
}
ERR_clear_error();
return true;
}
@@ -984,6 +1006,16 @@ static bool test_mod_mul(FILE *fp, BN_CTX *ctx) {
return false;
}
if (!BN_one(a.get()) || !BN_one(b.get())) {
return false;
}
BN_zero(c.get());
if (BN_mod_mul(e.get(), a.get(), b.get(), c.get(), ctx)) {
fprintf(stderr, "BN_mod_mul with zero modulus succeeded!\n");
return false;
}
ERR_clear_error();
for (int j = 0; j < 3; j++) {
if (!BN_rand(c.get(), 1024, 0, 0)) {
return false;
@@ -1038,8 +1070,21 @@ static bool test_mod_exp(FILE *fp, BN_CTX *ctx) {
ScopedBIGNUM c(BN_new());
ScopedBIGNUM d(BN_new());
ScopedBIGNUM e(BN_new());
if (!a || !b || !c || !d || !e ||
!BN_rand(c.get(), 30, 0, 1)) { // must be odd for montgomery
if (!a || !b || !c || !d || !e) {
return false;
}
if (!BN_one(a.get()) || !BN_one(b.get())) {
return false;
}
BN_zero(c.get());
if (BN_mod_exp(d.get(), a.get(), b.get(), c.get(), ctx)) {
fprintf(stderr, "BN_mod_exp with zero modulus succeeded!\n");
return 0;
}
ERR_clear_error();
if (!BN_rand(c.get(), 30, 0, 1)) { // must be odd for montgomery
return false;
}
for (int i = 0; i < num2; i++) {
@@ -1069,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;
}
@@ -1078,8 +1144,32 @@ static bool test_mod_exp_mont_consttime(FILE *fp, BN_CTX *ctx) {
ScopedBIGNUM c(BN_new());
ScopedBIGNUM d(BN_new());
ScopedBIGNUM e(BN_new());
if (!a || !b || !c || !d || !e ||
!BN_rand(c.get(), 30, 0, 1)) { // must be odd for montgomery
if (!a || !b || !c || !d || !e) {
return false;
}
if (!BN_one(a.get()) || !BN_one(b.get())) {
return false;
}
BN_zero(c.get());
if (BN_mod_exp_mont_consttime(d.get(), a.get(), b.get(), c.get(), ctx,
nullptr)) {
fprintf(stderr, "BN_mod_exp_mont_consttime with zero modulus succeeded!\n");
return 0;
}
ERR_clear_error();
if (!BN_set_word(c.get(), 16)) {
return false;
}
if (BN_mod_exp_mont_consttime(d.get(), a.get(), b.get(), c.get(), ctx,
nullptr)) {
fprintf(stderr, "BN_mod_exp_mont_consttime with even modulus succeeded!\n");
return 0;
}
ERR_clear_error();
if (!BN_rand(c.get(), 30, 0, 1)) { // must be odd for montgomery
return false;
}
for (int i = 0; i < num2; i++) {
@@ -1226,23 +1316,23 @@ static bool test_exp(FILE *fp, BN_CTX *ctx) {
// test_exp_mod_zero tests that 1**0 mod 1 == 0.
static bool test_exp_mod_zero(void) {
ScopedBIGNUM zero(BN_new());
if (!zero) {
ScopedBIGNUM zero(BN_new()), a(BN_new()), r(BN_new());
if (!zero || !a || !r || !BN_rand(a.get(), 1024, 0, 0)) {
return false;
}
BN_zero(zero.get());
ScopedBN_CTX ctx(BN_CTX_new());
ScopedBIGNUM r(BN_new());
if (!ctx || !r ||
!BN_mod_exp(r.get(), BN_value_one(), zero.get(), BN_value_one(), ctx.get())) {
return false;
}
if (!BN_is_zero(r.get())) {
fprintf(stderr, "1**0 mod 1 = ");
BN_print_fp(stderr, r.get());
fprintf(stderr, ", should be 0\n");
if (!BN_mod_exp(r.get(), a.get(), zero.get(), BN_value_one(), nullptr) ||
!BN_is_zero(r.get()) ||
!BN_mod_exp_mont(r.get(), a.get(), zero.get(), BN_value_one(), nullptr,
nullptr) ||
!BN_is_zero(r.get()) ||
!BN_mod_exp_mont_consttime(r.get(), a.get(), zero.get(), BN_value_one(),
nullptr, nullptr) ||
!BN_is_zero(r.get()) ||
!BN_mod_exp_mont_word(r.get(), 42, zero.get(), BN_value_one(), nullptr,
nullptr) ||
!BN_is_zero(r.get())) {
return false;
}
@@ -1483,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");
@@ -1716,8 +1799,8 @@ static const ASN1InvalidTest kASN1InvalidTests[] = {
{"\x02\x00", 2},
};
// kASN1BuggyTests are incorrect encodings and how |BN_cbs2unsigned_buggy|
// should interpret them.
// kASN1BuggyTests contains incorrect encodings and the corresponding, expected
// results of |BN_parse_asn1_unsigned_buggy| given that input.
static const ASN1Test kASN1BuggyTests[] = {
// Negative numbers.
{"128", "\x02\x01\x80", 3},
@@ -1740,7 +1823,7 @@ static bool test_asn1() {
}
CBS cbs;
CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
if (!BN_cbs2unsigned(&cbs, bn2.get()) || CBS_len(&cbs) != 0) {
if (!BN_parse_asn1_unsigned(&cbs, bn2.get()) || CBS_len(&cbs) != 0) {
fprintf(stderr, "Parsing ASN.1 INTEGER failed.\n");
return false;
}
@@ -1755,7 +1838,7 @@ static bool test_asn1() {
size_t der_len;
CBB_zero(&cbb);
if (!CBB_init(&cbb, 0) ||
!BN_bn2cbb(&cbb, bn.get()) ||
!BN_marshal_asn1(&cbb, bn.get()) ||
!CBB_finish(&cbb, &der, &der_len)) {
CBB_cleanup(&cbb);
return false;
@@ -1767,9 +1850,9 @@ static bool test_asn1() {
return false;
}
// |BN_cbs2unsigned_buggy| parses all valid input.
// |BN_parse_asn1_unsigned_buggy| parses all valid input.
CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
if (!BN_cbs2unsigned_buggy(&cbs, bn2.get()) || CBS_len(&cbs) != 0) {
if (!BN_parse_asn1_unsigned_buggy(&cbs, bn2.get()) || CBS_len(&cbs) != 0) {
fprintf(stderr, "Parsing ASN.1 INTEGER failed.\n");
return false;
}
@@ -1786,16 +1869,16 @@ static bool test_asn1() {
}
CBS cbs;
CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
if (BN_cbs2unsigned(&cbs, bn.get())) {
if (BN_parse_asn1_unsigned(&cbs, bn.get())) {
fprintf(stderr, "Parsed invalid input.\n");
return false;
}
ERR_clear_error();
// All tests in kASN1InvalidTests are also rejected by
// |BN_cbs2unsigned_buggy|.
// |BN_parse_asn1_unsigned_buggy|.
CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
if (BN_cbs2unsigned_buggy(&cbs, bn.get())) {
if (BN_parse_asn1_unsigned_buggy(&cbs, bn.get())) {
fprintf(stderr, "Parsed invalid input.\n");
return false;
}
@@ -1803,7 +1886,7 @@ static bool test_asn1() {
}
for (const ASN1Test &test : kASN1BuggyTests) {
// These broken encodings are rejected by |BN_cbs2unsigned|.
// These broken encodings are rejected by |BN_parse_asn1_unsigned|.
ScopedBIGNUM bn(BN_new());
if (!bn) {
return false;
@@ -1811,20 +1894,20 @@ static bool test_asn1() {
CBS cbs;
CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
if (BN_cbs2unsigned(&cbs, bn.get())) {
if (BN_parse_asn1_unsigned(&cbs, bn.get())) {
fprintf(stderr, "Parsed invalid input.\n");
return false;
}
ERR_clear_error();
// However |BN_cbs2unsigned_buggy| accepts them.
// However |BN_parse_asn1_unsigned_buggy| accepts them.
ScopedBIGNUM bn2 = ASCIIToBIGNUM(test.value_ascii);
if (!bn2) {
return false;
}
CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
if (!BN_cbs2unsigned_buggy(&cbs, bn.get()) || CBS_len(&cbs) != 0) {
if (!BN_parse_asn1_unsigned_buggy(&cbs, bn.get()) || CBS_len(&cbs) != 0) {
fprintf(stderr, "Parsing (invalid) ASN.1 INTEGER failed.\n");
return false;
}
@@ -1843,7 +1926,7 @@ static bool test_asn1() {
CBB cbb;
CBB_zero(&cbb);
if (!CBB_init(&cbb, 0) ||
BN_bn2cbb(&cbb, bn.get())) {
BN_marshal_asn1(&cbb, bn.get())) {
fprintf(stderr, "Serialized negative number.\n");
CBB_cleanup(&cbb);
return false;
+9 -4
View File
@@ -63,6 +63,7 @@
#include <string.h>
#include <openssl/bio.h>
#include <openssl/bytestring.h>
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -195,6 +196,11 @@ int BN_bn2bin_padded(uint8_t *out, size_t len, const BIGNUM *in) {
return 1;
}
int BN_bn2cbb_padded(CBB *out, size_t len, const BIGNUM *in) {
uint8_t *ptr;
return CBB_add_space(out, &ptr, len) && BN_bn2bin_padded(ptr, len, in);
}
static const char hextable[] = "0123456789abcdef";
char *BN_bn2hex(const BIGNUM *bn) {
@@ -202,7 +208,7 @@ char *BN_bn2hex(const BIGNUM *bn) {
char *buf;
char *p;
buf = (char *)OPENSSL_malloc(bn->top * BN_BYTES * 2 + 2);
buf = OPENSSL_malloc(bn->top * BN_BYTES * 2 + 2);
if (buf == NULL) {
OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
return NULL;
@@ -379,9 +385,8 @@ char *BN_bn2dec(const BIGNUM *a) {
*/
i = BN_num_bits(a) * 3;
num = i / 10 + i / 1000 + 1 + 1;
bn_data =
(BN_ULONG *)OPENSSL_malloc((num / BN_DEC_NUM + 1) * sizeof(BN_ULONG));
buf = (char *)OPENSSL_malloc(num + 3);
bn_data = OPENSSL_malloc((num / BN_DEC_NUM + 1) * sizeof(BN_ULONG));
buf = OPENSSL_malloc(num + 3);
if ((buf == NULL) || (bn_data == NULL)) {
OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
goto err;
+125 -93
View File
@@ -56,55 +56,126 @@
#include <openssl/bn.h>
#include <assert.h>
#include <limits.h>
#include <openssl/err.h>
#include "internal.h"
#define asm __asm__
#if !defined(BN_ULLONG)
/* bn_div_words divides a double-width |h|,|l| by |d| and returns the result,
* which must fit in a |BN_ULONG|. */
static BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) {
BN_ULONG dh, dl, q, ret = 0, th, tl, t;
int i, count = 2;
#if !defined(OPENSSL_NO_ASM)
# if defined(__GNUC__) && __GNUC__>=2
# if defined(OPENSSL_X86)
/*
* There were two reasons for implementing this template:
* - GNU C generates a call to a function (__udivdi3 to be exact)
* in reply to ((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0 (I fail to
* understand why...);
* - divl doesn't only calculate quotient, but also leaves
* remainder in %edx which we can definitely use here:-)
*
* <appro@fy.chalmers.se>
*/
#undef div_asm
# define div_asm(n0,n1,d0) \
({ asm volatile ( \
"divl %4" \
: "=a"(q), "=d"(rem) \
: "a"(n1), "d"(n0), "g"(d0) \
: "cc"); \
q; \
})
# define REMAINDER_IS_ALREADY_CALCULATED
# elif defined(OPENSSL_X86_64)
/*
* Same story here, but it's 128-bit by 64-bit division. Wow!
* <appro@fy.chalmers.se>
*/
# undef div_asm
# define div_asm(n0,n1,d0) \
({ asm volatile ( \
"divq %4" \
: "=a"(q), "=d"(rem) \
: "a"(n1), "d"(n0), "g"(d0) \
: "cc"); \
q; \
})
# define REMAINDER_IS_ALREADY_CALCULATED
# endif /* __<cpu> */
# endif /* __GNUC__ */
#endif /* OPENSSL_NO_ASM */
if (d == 0) {
return BN_MASK2;
}
i = BN_num_bits_word(d);
assert((i == BN_BITS2) || (h <= (BN_ULONG)1 << i));
i = BN_BITS2 - i;
if (h >= d) {
h -= d;
}
if (i) {
d <<= i;
h = (h << i) | (l >> (BN_BITS2 - i));
l <<= i;
}
dh = (d & BN_MASK2h) >> BN_BITS4;
dl = (d & BN_MASK2l);
for (;;) {
if ((h >> BN_BITS4) == dh) {
q = BN_MASK2l;
} else {
q = h / dh;
}
th = q * dh;
tl = dl * q;
for (;;) {
t = h - th;
if ((t & BN_MASK2h) ||
((tl) <= ((t << BN_BITS4) | ((l & BN_MASK2h) >> BN_BITS4)))) {
break;
}
q--;
th -= dh;
tl -= dl;
}
t = (tl >> BN_BITS4);
tl = (tl << BN_BITS4) & BN_MASK2h;
th += t;
if (l < tl) {
th++;
}
l -= tl;
if (h < th) {
h += d;
q--;
}
h -= th;
if (--count == 0) {
break;
}
ret = q << BN_BITS4;
h = ((h << BN_BITS4) | (l >> BN_BITS4)) & BN_MASK2;
l = (l & BN_MASK2l) << BN_BITS4;
}
ret |= q;
return ret;
}
#endif /* !defined(BN_ULLONG) */
static inline void bn_div_rem_words(BN_ULONG *quotient_out, BN_ULONG *rem_out,
BN_ULONG n0, BN_ULONG n1, BN_ULONG d0) {
/* GCC and Clang generate function calls to |__udivdi3| and |__umoddi3| when
* the |BN_ULLONG|-based C code is used.
*
* GCC bugs:
* * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=14224
* * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43721
* * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54183
* * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58897
* * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65668
*
* Clang bugs:
* * https://llvm.org/bugs/show_bug.cgi?id=6397
* * https://llvm.org/bugs/show_bug.cgi?id=12418
*
* These issues aren't specific to x86 and x86_64, so it might be worthwhile
* to add more assembly language implementations. */
#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86) && defined(__GNUC__)
__asm__ volatile (
"divl %4"
: "=a"(*quotient_out), "=d"(*rem_out)
: "a"(n1), "d"(n0), "g"(d0)
: "cc" );
#elif !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && defined(__GNUC__)
__asm__ volatile (
"divq %4"
: "=a"(*quotient_out), "=d"(*rem_out)
: "a"(n1), "d"(n0), "g"(d0)
: "cc" );
#else
#if defined(BN_ULLONG)
BN_ULLONG n = (((BN_ULLONG)n0) << BN_BITS2) | n1;
*quotient_out = (BN_ULONG)(n / d0);
#else
*quotient_out = bn_div_words(n0, n1, d0);
#endif
*rem_out = n1 - (*quotient_out * d0);
#endif
}
/* BN_div computes dv := num / divisor, rounding towards
* zero, and sets up rm such that dv*divisor + rm = num holds.
@@ -260,23 +331,10 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
q = BN_MASK2;
} else {
/* n0 < d0 */
#ifdef BN_LLONG
BN_ULLONG t2;
#if defined(BN_LLONG) && !defined(div_asm)
q = (BN_ULONG)(((((BN_ULLONG)n0) << BN_BITS2) | n1) / d0);
#else
q = div_asm(n0, n1, d0);
#endif
#ifndef REMAINDER_IS_ALREADY_CALCULATED
/* rem doesn't have to be BN_ULLONG. The least we know it's less that d0,
* isn't it? */
rem = (n1 - q * d0) & BN_MASK2;
#endif
t2 = (BN_ULLONG)d1 * q;
bn_div_rem_words(&q, &rem, n0, n1, d0);
#ifdef BN_ULLONG
BN_ULLONG t2 = (BN_ULLONG)d1 * q;
for (;;) {
if (t2 <= ((((BN_ULLONG)rem) << BN_BITS2) | wnump[-2])) {
break;
@@ -288,35 +346,9 @@ 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)
q = div_asm(n0, n1, d0);
#else
q = bn_div_words(n0, n1, d0);
#endif
#ifndef REMAINDER_IS_ALREADY_CALCULATED
rem = (n1 - q * d0) & BN_MASK2;
#endif
#if defined(BN_UMULT_LOHI)
BN_UMULT_LOHI(t2l, t2h, d1, q);
#elif defined(BN_UMULT_HIGH)
t2l = d1 * q;
t2h = BN_UMULT_HIGH(d1, q);
#else
{
BN_ULONG ql, qh;
t2l = LBITS(d1);
t2h = HBITS(d1);
ql = LBITS(q);
qh = HBITS(q);
mul64(t2l, t2h, ql, qh); /* t2=(BN_ULLONG)d1*q; */
}
#endif
for (;;) {
if ((t2h < rem) || ((t2h == rem) && (t2l <= wnump[-2]))) {
break;
@@ -331,7 +363,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);
@@ -576,7 +608,7 @@ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) {
return 0;
}
/* normalize input (so bn_div_words doesn't complain) */
/* normalize input for |bn_div_rem_words|. */
j = BN_BITS2 - BN_num_bits_word(w);
w <<= j;
if (!BN_lshift(a, a, j)) {
@@ -584,10 +616,10 @@ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) {
}
for (i = a->top - 1; i >= 0; i--) {
BN_ULONG l, d;
l = a->d[i];
d = bn_div_words(ret, l, w);
BN_ULONG l = a->d[i];
BN_ULONG d;
BN_ULONG unused_rem;
bn_div_rem_words(&d, &unused_rem, ret, l, w);
ret = (l - ((d * w) & BN_MASK2)) & BN_MASK2;
a->d[i] = d;
}
@@ -601,7 +633,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 +646,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
+138 -115
View File
@@ -123,6 +123,17 @@
#define RSAZ_ENABLED
#include "rsaz_exp.h"
void bn_mul_mont_gather5(BN_ULONG *rp, const BN_ULONG *ap, const void *table,
const BN_ULONG *np, const BN_ULONG *n0, int num,
int power);
void bn_scatter5(const BN_ULONG *inp, size_t num, void *table, size_t power);
void bn_gather5(BN_ULONG *out, size_t num, void *table, size_t power);
void bn_power5(BN_ULONG *rp, const BN_ULONG *ap, const void *table,
const BN_ULONG *np, const BN_ULONG *n0, int num, int power);
int bn_from_montgomery(BN_ULONG *rp, const BN_ULONG *ap,
const BN_ULONG *not_used, const BN_ULONG *np,
const BN_ULONG *n0, int num);
#endif
int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
@@ -198,6 +209,7 @@ static void BN_RECP_CTX_init(BN_RECP_CTX *recp) {
BN_init(&recp->N);
BN_init(&recp->Nr);
recp->num_bits = 0;
recp->shift = 0;
recp->flags = 0;
}
@@ -274,10 +286,10 @@ static int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
goto err;
}
if (BN_ucmp(m, &(recp->N)) < 0) {
if (BN_ucmp(m, &recp->N) < 0) {
BN_zero(d);
if (!BN_copy(r, m)) {
return 0;
goto err;
}
BN_CTX_end(ctx);
return 1;
@@ -434,8 +446,12 @@ static int mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
bits = BN_num_bits(p);
if (bits == 0) {
ret = BN_one(r);
return ret;
/* x**0 mod 1 is still zero. */
if (BN_is_one(m)) {
BN_zero(r);
return 1;
}
return BN_one(r);
}
BN_CTX_start(ctx);
@@ -602,17 +618,17 @@ int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
}
int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) {
const BIGNUM *m, BN_CTX *ctx, const BN_MONT_CTX *mont) {
int i, j, bits, ret = 0, wstart, window;
int start = 1;
BIGNUM *d, *r;
const BIGNUM *aa;
/* Table of variables obtained from 'ctx' */
BIGNUM *val[TABLE_SIZE];
BN_MONT_CTX *mont = NULL;
BN_MONT_CTX *new_mont = NULL;
if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont);
return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, mont);
}
if (!BN_is_odd(m)) {
@@ -621,8 +637,12 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
}
bits = BN_num_bits(p);
if (bits == 0) {
ret = BN_one(rr);
return ret;
/* x**0 mod 1 is still zero. */
if (BN_is_one(m)) {
BN_zero(rr);
return 1;
}
return BN_one(rr);
}
BN_CTX_start(ctx);
@@ -633,18 +653,13 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
goto err;
}
/* If this is not done, things will break in the montgomery part */
if (in_mont != NULL) {
mont = in_mont;
} else {
mont = BN_MONT_CTX_new();
if (mont == NULL) {
goto err;
}
if (!BN_MONT_CTX_set(mont, m, ctx)) {
/* Allocate a montgomery context if it was not supplied by the caller. */
if (mont == NULL) {
new_mont = BN_MONT_CTX_new();
if (new_mont == NULL || !BN_MONT_CTX_set(new_mont, m, ctx)) {
goto err;
}
mont = new_mont;
}
if (a->neg || BN_ucmp(a, m) >= 0) {
@@ -763,9 +778,7 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
ret = 1;
err:
if (in_mont == NULL) {
BN_MONT_CTX_free(mont);
}
BN_MONT_CTX_free(new_mont);
BN_CTX_end(ctx);
return ret;
}
@@ -775,29 +788,65 @@ err:
* pattern as far as cache lines are concerned. The following functions are
* used to transfer a BIGNUM from/to that table. */
static int copy_to_prebuf(const BIGNUM *b, int top, unsigned char *buf, int idx,
int width) {
size_t i, j;
int window) {
int i, j;
const int width = 1 << window;
BN_ULONG *table = (BN_ULONG *) buf;
if (top > b->top) {
top = b->top; /* this works because 'buf' is explicitly zeroed */
}
for (i = 0, j = idx; i < top * sizeof b->d[0]; i++, j += width) {
buf[j] = ((unsigned char *)b->d)[i];
for (i = 0, j = idx; i < top; i++, j += width) {
table[j] = b->d[i];
}
return 1;
}
static int copy_from_prebuf(BIGNUM *b, int top, unsigned char *buf, int idx,
int width) {
size_t i, j;
int window) {
int i, j;
const int width = 1 << window;
volatile BN_ULONG *table = (volatile BN_ULONG *)buf;
if (bn_wexpand(b, top) == NULL) {
return 0;
}
for (i = 0, j = idx; i < top * sizeof b->d[0]; i++, j += width) {
((unsigned char *)b->d)[i] = buf[j];
if (window <= 3) {
for (i = 0; i < top; i++, table += width) {
BN_ULONG acc = 0;
for (j = 0; j < width; j++) {
acc |= table[j] & ((BN_ULONG)0 - (constant_time_eq_int(j, idx) & 1));
}
b->d[i] = acc;
}
} else {
int xstride = 1 << (window - 2);
BN_ULONG y0, y1, y2, y3;
i = idx >> (window - 2); /* equivalent of idx / xstride */
idx &= xstride - 1; /* equivalent of idx % xstride */
y0 = (BN_ULONG)0 - (constant_time_eq_int(i, 0) & 1);
y1 = (BN_ULONG)0 - (constant_time_eq_int(i, 1) & 1);
y2 = (BN_ULONG)0 - (constant_time_eq_int(i, 2) & 1);
y3 = (BN_ULONG)0 - (constant_time_eq_int(i, 3) & 1);
for (i = 0; i < top; i++, table += width) {
BN_ULONG acc = 0;
for (j = 0; j < xstride; j++) {
acc |= ((table[j + 0 * xstride] & y0) | (table[j + 1 * xstride] & y1) |
(table[j + 2 * xstride] & y2) | (table[j + 3 * xstride] & y3)) &
((BN_ULONG)0 - (constant_time_eq_int(j, idx) & 1));
}
b->d[i] = acc;
}
}
b->top = top;
@@ -851,10 +900,10 @@ static int copy_from_prebuf(BIGNUM *b, int top, unsigned char *buf, int idx,
*/
int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx,
BN_MONT_CTX *in_mont) {
const BN_MONT_CTX *mont) {
int i, bits, ret = 0, window, wvalue;
int top;
BN_MONT_CTX *mont = NULL;
BN_MONT_CTX *new_mont = NULL;
int numPowers;
unsigned char *powerbufFree = NULL;
@@ -862,29 +911,30 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
unsigned char *powerbuf = NULL;
BIGNUM tmp, am;
top = m->top;
if (!(m->d[0] & 1)) {
if (!BN_is_odd(m)) {
OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
return 0;
}
top = m->top;
bits = BN_num_bits(p);
if (bits == 0) {
ret = BN_one(rr);
return ret;
/* x**0 mod 1 is still zero. */
if (BN_is_one(m)) {
BN_zero(rr);
return 1;
}
return BN_one(rr);
}
BN_CTX_start(ctx);
/* Allocate a montgomery context if it was not supplied by the caller.
* If this is not done, things will break in the montgomery part. */
if (in_mont != NULL) {
mont = in_mont;
} else {
mont = BN_MONT_CTX_new();
if (mont == NULL || !BN_MONT_CTX_set(mont, m, ctx)) {
/* Allocate a montgomery context if it was not supplied by the caller. */
if (mont == NULL) {
new_mont = BN_MONT_CTX_new();
if (new_mont == NULL || !BN_MONT_CTX_set(new_mont, m, ctx)) {
goto err;
}
mont = new_mont;
}
#ifdef RSAZ_ENABLED
@@ -920,9 +970,8 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
#if defined(OPENSSL_BN_ASM_MONT5)
if (window >= 5) {
window = 5; /* ~5% improvement for RSA2048 sign, and even for RSA4096 */
if ((top & 7) == 0) {
powerbufLen += 2 * top * sizeof(m->d[0]);
}
/* reserve space for mont->N.d[] copy */
powerbufLen += top * sizeof(mont->N.d[0]);
}
#endif
@@ -939,7 +988,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
} else
#endif
{
if ((powerbufFree = (unsigned char *)OPENSSL_malloc(
if ((powerbufFree = OPENSSL_malloc(
powerbufLen + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH)) == NULL) {
goto err;
}
@@ -993,20 +1042,8 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
/* Dedicated window==4 case improves 512-bit RSA sign by ~15%, but as
* 512-bit RSA is hardly relevant, we omit it to spare size... */
if (window == 5 && top > 1) {
void bn_mul_mont_gather5(BN_ULONG * rp, const BN_ULONG * ap,
const void * table, const BN_ULONG * np,
const BN_ULONG * n0, int num, int power);
void bn_scatter5(const BN_ULONG * inp, size_t num, void * table,
size_t power);
void bn_gather5(BN_ULONG * out, size_t num, void * table, size_t power);
void bn_power5(BN_ULONG * rp, const BN_ULONG * ap, const void * table,
const BN_ULONG * np, const BN_ULONG * n0, int num,
int power);
int bn_from_montgomery(BN_ULONG * rp, const BN_ULONG * ap,
const BN_ULONG * not_used, const BN_ULONG * np,
const BN_ULONG * n0, int num);
BN_ULONG *np = mont->N.d, *n0 = mont->n0, *np2;
const BN_ULONG *n0 = mont->n0;
BN_ULONG *np;
/* BN_to_montgomery can contaminate words above .top
* [in BN_DEBUG[_DEBUG] build]... */
@@ -1017,12 +1054,9 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
tmp.d[i] = 0;
}
if (top & 7) {
np2 = np;
} else {
for (np2 = am.d + top, i = 0; i < top; i++) {
np2[2 * i] = np[i];
}
/* copy mont->N.d[] to improve cache locality */
for (np = am.d + top, i = 0; i < top; i++) {
np[i] = mont->N.d[i];
}
bn_scatter5(tmp.d, top, powerbuf, 0);
@@ -1037,7 +1071,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
}
for (i = 3; i < 8; i += 2) {
int j;
bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np2, n0, top, i - 1);
bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
bn_scatter5(tmp.d, top, powerbuf, i);
for (j = 2 * i; j < 32; j *= 2) {
bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
@@ -1045,13 +1079,13 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
}
}
for (; i < 16; i += 2) {
bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np2, n0, top, i - 1);
bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
bn_scatter5(tmp.d, top, powerbuf, i);
bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
bn_scatter5(tmp.d, top, powerbuf, 2 * i);
}
for (; i < 32; i += 2) {
bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np2, n0, top, i - 1);
bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
bn_scatter5(tmp.d, top, powerbuf, i);
}
@@ -1099,7 +1133,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
wvalue >>= (bits - 4) & 7;
wvalue &= 0x1f;
bits -= 5;
bn_power5(tmp.d, tmp.d, powerbuf, np2, n0, top, wvalue);
bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue);
}
while (bits >= 0) {
/* Read five bits from |bits-4| through |bits|, inclusive. */
@@ -1108,11 +1142,11 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
wvalue >>= first_bit & 7;
wvalue &= 0x1f;
bits -= 5;
bn_power5(tmp.d, tmp.d, powerbuf, np2, n0, top, wvalue);
bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue);
}
}
ret = bn_from_montgomery(tmp.d, tmp.d, NULL, np2, n0, top);
ret = bn_from_montgomery(tmp.d, tmp.d, NULL, np, n0, top);
tmp.top = top;
bn_correct_top(&tmp);
if (ret) {
@@ -1124,8 +1158,8 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
} else
#endif
{
if (!copy_to_prebuf(&tmp, top, powerbuf, 0, numPowers) ||
!copy_to_prebuf(&am, top, powerbuf, 1, numPowers)) {
if (!copy_to_prebuf(&tmp, top, powerbuf, 0, window) ||
!copy_to_prebuf(&am, top, powerbuf, 1, window)) {
goto err;
}
@@ -1136,13 +1170,13 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
*/
if (window > 1) {
if (!BN_mod_mul_montgomery(&tmp, &am, &am, mont, ctx) ||
!copy_to_prebuf(&tmp, top, powerbuf, 2, numPowers)) {
!copy_to_prebuf(&tmp, top, powerbuf, 2, window)) {
goto err;
}
for (i = 3; i < numPowers; i++) {
/* Calculate a^i = a^(i-1) * a */
if (!BN_mod_mul_montgomery(&tmp, &am, &tmp, mont, ctx) ||
!copy_to_prebuf(&tmp, top, powerbuf, i, numPowers)) {
!copy_to_prebuf(&tmp, top, powerbuf, i, window)) {
goto err;
}
}
@@ -1152,7 +1186,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
for (wvalue = 0, i = bits % window; i >= 0; i--, bits--) {
wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
}
if (!copy_from_prebuf(&tmp, top, powerbuf, wvalue, numPowers)) {
if (!copy_from_prebuf(&tmp, top, powerbuf, wvalue, window)) {
goto err;
}
@@ -1171,7 +1205,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
}
/* Fetch the appropriate pre-computed value from the pre-buf */
if (!copy_from_prebuf(&am, top, powerbuf, wvalue, numPowers)) {
if (!copy_from_prebuf(&am, top, powerbuf, wvalue, window)) {
goto err;
}
@@ -1187,21 +1221,20 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
goto err;
}
ret = 1;
err:
if (in_mont == NULL) {
BN_MONT_CTX_free(mont);
}
BN_MONT_CTX_free(new_mont);
if (powerbuf != NULL) {
OPENSSL_cleanse(powerbuf, powerbufLen);
OPENSSL_free(powerbufFree);
}
BN_CTX_end(ctx);
return (ret);
}
int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) {
BN_MONT_CTX *mont = NULL;
const BIGNUM *m, BN_CTX *ctx,
const BN_MONT_CTX *mont) {
BN_MONT_CTX *new_mont = NULL;
int b, bits, ret = 0;
int r_is_one;
BN_ULONG w, next_w;
@@ -1238,17 +1271,14 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
if (bits == 0) {
/* x**0 mod 1 is still zero. */
if (BN_is_one(m)) {
ret = 1;
BN_zero(rr);
} else {
ret = BN_one(rr);
return 1;
}
return ret;
return BN_one(rr);
}
if (a == 0) {
BN_zero(rr);
ret = 1;
return ret;
return 1;
}
BN_CTX_start(ctx);
@@ -1259,13 +1289,13 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
goto err;
}
if (in_mont != NULL) {
mont = in_mont;
} else {
mont = BN_MONT_CTX_new();
if (mont == NULL || !BN_MONT_CTX_set(mont, m, ctx)) {
/* Allocate a montgomery context if it was not supplied by the caller. */
if (mont == NULL) {
new_mont = BN_MONT_CTX_new();
if (new_mont == NULL || !BN_MONT_CTX_set(new_mont, m, ctx)) {
goto err;
}
mont = new_mont;
}
r_is_one = 1; /* except for Montgomery factor */
@@ -1347,9 +1377,7 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
ret = 1;
err:
if (in_mont == NULL) {
BN_MONT_CTX_free(mont);
}
BN_MONT_CTX_free(new_mont);
BN_CTX_end(ctx);
return ret;
}
@@ -1358,7 +1386,7 @@ err:
int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m,
BN_CTX *ctx, BN_MONT_CTX *in_mont) {
BN_CTX *ctx, const BN_MONT_CTX *mont) {
int i, j, bits, b, bits1, bits2, ret = 0, wpos1, wpos2, window1, window2,
wvalue1, wvalue2;
int r_is_one = 1;
@@ -1366,7 +1394,7 @@ int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
const BIGNUM *a_mod_m;
/* Tables of variables obtained from 'ctx' */
BIGNUM *val1[TABLE_SIZE], *val2[TABLE_SIZE];
BN_MONT_CTX *mont = NULL;
BN_MONT_CTX *new_mont = NULL;
if (!(m->d[0] & 1)) {
OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
@@ -1390,16 +1418,13 @@ int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
goto err;
}
if (in_mont != NULL) {
mont = in_mont;
} else {
mont = BN_MONT_CTX_new();
if (mont == NULL) {
goto err;
}
if (!BN_MONT_CTX_set(mont, m, ctx)) {
/* Allocate a montgomery context if it was not supplied by the caller. */
if (mont == NULL) {
new_mont = BN_MONT_CTX_new();
if (new_mont == NULL || !BN_MONT_CTX_set(new_mont, m, ctx)) {
goto err;
}
mont = new_mont;
}
window1 = BN_window_bits_for_exponent_size(bits1);
@@ -1551,9 +1576,7 @@ int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
ret = 1;
err:
if (in_mont == NULL) {
BN_MONT_CTX_free(mont);
}
BN_MONT_CTX_free(new_mont);
BN_CTX_end(ctx);
return ret;
}
+22 -8
View File
@@ -223,20 +223,23 @@ err:
}
/* solves ax == 1 (mod n) */
static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, const BIGNUM *a,
const BIGNUM *n, BN_CTX *ctx);
static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, int *out_no_inverse,
const BIGNUM *a, const BIGNUM *n,
BN_CTX *ctx);
BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n,
BN_CTX *ctx) {
BIGNUM *BN_mod_inverse_ex(BIGNUM *out, int *out_no_inverse, const BIGNUM *a,
const BIGNUM *n, BN_CTX *ctx) {
BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
BIGNUM *ret = NULL;
int sign;
if ((a->flags & BN_FLG_CONSTTIME) != 0 ||
(n->flags & BN_FLG_CONSTTIME) != 0) {
return BN_mod_inverse_no_branch(out, a, n, ctx);
return BN_mod_inverse_no_branch(out, out_no_inverse, a, n, ctx);
}
*out_no_inverse = 0;
BN_CTX_start(ctx);
A = BN_CTX_get(ctx);
B = BN_CTX_get(ctx);
@@ -276,7 +279,7 @@ BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n,
* 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
@@ -522,6 +525,7 @@ BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n,
}
}
} else {
*out_no_inverse = 1;
OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE);
goto err;
}
@@ -535,16 +539,25 @@ err:
return ret;
}
BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n,
BN_CTX *ctx) {
int no_inverse;
return BN_mod_inverse_ex(out, &no_inverse, a, n, ctx);
}
/* BN_mod_inverse_no_branch is a special version of BN_mod_inverse.
* It does not contain branches that may leak sensitive information. */
static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, const BIGNUM *a,
const BIGNUM *n, BN_CTX *ctx) {
static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, int *out_no_inverse,
const BIGNUM *a, const BIGNUM *n,
BN_CTX *ctx) {
BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
BIGNUM local_A, local_B;
BIGNUM *pA, *pB;
BIGNUM *ret = NULL;
int sign;
*out_no_inverse = 0;
BN_CTX_start(ctx);
A = BN_CTX_get(ctx);
B = BN_CTX_get(ctx);
@@ -682,6 +695,7 @@ static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, const BIGNUM *a,
}
}
} else {
*out_no_inverse = 1;
OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE);
goto err;
}
+13 -441
View File
@@ -61,21 +61,12 @@
#include "internal.h"
/* Generic implementations of most operations are needed for:
* - Configurations without inline assembly.
* - Architectures other than x86 or x86_64.
* - Windows x84_64; x86_64-gcc.c does not build on MSVC. */
/* This file has two other implementations: x86 assembly language in
* asm/bn-586.pl and x86_64 inline assembly in asm/x86_64-gcc.c. */
#if defined(OPENSSL_NO_ASM) || \
(!defined(OPENSSL_X86_64) && !defined(OPENSSL_X86)) || \
(defined(OPENSSL_X86_64) && defined(OPENSSL_WINDOWS))
!(defined(OPENSSL_X86) || (defined(OPENSSL_X86_64) && defined(__GNUC__)))
#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; \
@@ -100,7 +91,8 @@
(r1) = Hw(t); \
}
#elif defined(BN_UMULT_LOHI)
#else
#define mul_add(r, a, w, c) \
{ \
BN_ULONG high, low, ret, tmp = (a); \
@@ -130,101 +122,7 @@
BN_UMULT_LOHI(r0, r1, tmp, tmp); \
}
#else
/*************************************************************
* No long long type
*/
#define LBITS(a) ((a) & BN_MASK2l)
#define HBITS(a) (((a) >> BN_BITS4) & BN_MASK2l)
#define L2HBITS(a) (((a) << BN_BITS4) & BN_MASK2)
#define LLBITS(a) ((a) & BN_MASKl)
#define LHBITS(a) (((a) >> BN_BITS2) & BN_MASKl)
#define LL2HBITS(a) ((BN_ULLONG)((a) & BN_MASKl) << BN_BITS2)
#define mul64(l, h, bl, bh) \
{ \
BN_ULONG m, m1, lt, ht; \
\
lt = l; \
ht = h; \
m = (bh) * (lt); \
lt = (bl) * (lt); \
m1 = (bl) * (ht); \
ht = (bh) * (ht); \
m = (m + m1) & BN_MASK2; \
if (m < m1) \
ht += L2HBITS((BN_ULONG)1); \
ht += HBITS(m); \
m1 = L2HBITS(m); \
lt = (lt + m1) & BN_MASK2; \
if (lt < m1) \
ht++; \
(l) = lt; \
(h) = ht; \
}
#define sqr64(lo, ho, in) \
{ \
BN_ULONG l, h, m; \
\
h = (in); \
l = LBITS(h); \
h = HBITS(h); \
m = (l) * (h); \
l *= l; \
h *= h; \
h += (m & BN_MASK2h1) >> (BN_BITS4 - 1); \
m = (m & BN_MASK2l) << (BN_BITS4 + 1); \
l = (l + m) & BN_MASK2; \
if (l < m) \
h++; \
(lo) = l; \
(ho) = h; \
}
#define mul_add(r, a, bl, bh, c) \
{ \
BN_ULONG l, h; \
\
h = (a); \
l = LBITS(h); \
h = HBITS(h); \
mul64(l, h, (bl), (bh)); \
\
/* non-multiply part */ \
l = (l + (c)) & BN_MASK2; \
if (l < (c)) \
h++; \
(c) = (r); \
l = (l + (c)) & BN_MASK2; \
if (l < (c)) \
h++; \
(c) = h & BN_MASK2; \
(r) = l; \
}
#define mul(r, a, bl, bh, c) \
{ \
BN_ULONG l, h; \
\
h = (a); \
l = LBITS(h); \
h = HBITS(h); \
mul64(l, h, (bl), (bh)); \
\
/* non-multiply part */ \
l += (c); \
if ((l & BN_MASK2) < (c)) \
h++; \
(c) = h & BN_MASK2; \
(r) = l & BN_MASK2; \
}
#endif /* !BN_LLONG */
#if defined(BN_LLONG) || defined(BN_UMULT_HIGH)
#endif /* !BN_ULLONG */
BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
BN_ULONG w) {
@@ -304,175 +202,7 @@ void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) {
}
}
#else /* !(defined(BN_LLONG) || defined(BN_UMULT_HIGH)) */
BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
BN_ULONG w) {
BN_ULONG c = 0;
BN_ULONG bl, bh;
assert(num >= 0);
if (num <= 0) {
return (BN_ULONG)0;
}
bl = LBITS(w);
bh = HBITS(w);
while (num & ~3) {
mul_add(rp[0], ap[0], bl, bh, c);
mul_add(rp[1], ap[1], bl, bh, c);
mul_add(rp[2], ap[2], bl, bh, c);
mul_add(rp[3], ap[3], bl, bh, c);
ap += 4;
rp += 4;
num -= 4;
}
while (num) {
mul_add(rp[0], ap[0], bl, bh, c);
ap++;
rp++;
num--;
}
return c;
}
BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) {
BN_ULONG carry = 0;
BN_ULONG bl, bh;
assert(num >= 0);
if (num <= 0) {
return (BN_ULONG)0;
}
bl = LBITS(w);
bh = HBITS(w);
while (num & ~3) {
mul(rp[0], ap[0], bl, bh, carry);
mul(rp[1], ap[1], bl, bh, carry);
mul(rp[2], ap[2], bl, bh, carry);
mul(rp[3], ap[3], bl, bh, carry);
ap += 4;
rp += 4;
num -= 4;
}
while (num) {
mul(rp[0], ap[0], bl, bh, carry);
ap++;
rp++;
num--;
}
return carry;
}
void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) {
assert(n >= 0);
if (n <= 0) {
return;
}
while (n & ~3) {
sqr64(r[0], r[1], a[0]);
sqr64(r[2], r[3], a[1]);
sqr64(r[4], r[5], a[2]);
sqr64(r[6], r[7], a[3]);
a += 4;
r += 8;
n -= 4;
}
while (n) {
sqr64(r[0], r[1], a[0]);
a++;
r += 2;
n--;
}
}
#endif /* !(defined(BN_LLONG) || defined(BN_UMULT_HIGH)) */
#if defined(BN_LLONG)
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);
}
#else
/* Divide h,l by d and return the result. */
BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) {
BN_ULONG dh, dl, q, ret = 0, th, tl, t;
int i, count = 2;
if (d == 0) {
return BN_MASK2;
}
i = BN_num_bits_word(d);
assert((i == BN_BITS2) || (h <= (BN_ULONG)1 << i));
i = BN_BITS2 - i;
if (h >= d) {
h -= d;
}
if (i) {
d <<= i;
h = (h << i) | (l >> (BN_BITS2 - i));
l <<= i;
}
dh = (d & BN_MASK2h) >> BN_BITS4;
dl = (d & BN_MASK2l);
for (;;) {
if ((h >> BN_BITS4) == dh) {
q = BN_MASK2l;
} else {
q = h / dh;
}
th = q * dh;
tl = dl * q;
for (;;) {
t = h - th;
if ((t & BN_MASK2h) ||
((tl) <= ((t << BN_BITS4) | ((l & BN_MASK2h) >> BN_BITS4)))) {
break;
}
q--;
th -= dh;
tl -= dl;
}
t = (tl >> BN_BITS4);
tl = (tl << BN_BITS4) & BN_MASK2h;
th += t;
if (l < tl) {
th++;
}
l -= tl;
if (h < th) {
h += d;
q--;
}
h -= th;
if (--count == 0) {
break;
}
ret = q << BN_BITS4;
h = ((h << BN_BITS4) | (l >> BN_BITS4)) & BN_MASK2;
l = (l & BN_MASK2l) << BN_BITS4;
}
ret |= q;
return ret;
}
#endif /* !defined(BN_LLONG) */
#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 +242,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 +299,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 +361,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. */
@@ -679,7 +409,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)
#elif defined(BN_UMULT_LOHI)
#else
/* Keep in mind that additions to hi can not overflow, because the high word of
* a multiplication result cannot be all-ones. */
@@ -722,59 +452,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 */
/* Keep in mind that additions to hi can not overflow, because
* the high word of a multiplication result cannot be all-ones. */
#define mul_add_c(a, b, c0, c1, c2) \
do { \
BN_ULONG lo = LBITS(a), hi = HBITS(a); \
BN_ULONG bl = LBITS(b), bh = HBITS(b); \
mul64(lo, hi, bl, bh); \
c0 = (c0 + lo) & BN_MASK2; \
if (c0 < lo) \
hi++; \
c1 = (c1 + hi) & BN_MASK2; \
if (c1 < hi) \
c2++; \
} while (0)
#define mul_add_c2(a, b, c0, c1, c2) \
do { \
BN_ULONG tt; \
BN_ULONG lo = LBITS(a), hi = HBITS(a); \
BN_ULONG bl = LBITS(b), bh = HBITS(b); \
mul64(lo, hi, bl, bh); \
tt = hi; \
c0 = (c0 + lo) & BN_MASK2; \
if (c0 < lo) \
tt++; \
c1 = (c1 + tt) & BN_MASK2; \
if (c1 < tt) \
c2++; \
c0 = (c0 + lo) & BN_MASK2; \
if (c0 < lo) \
hi++; \
c1 = (c1 + hi) & BN_MASK2; \
if (c1 < hi) \
c2++; \
} while (0)
#define sqr_add_c(a, i, c0, c1, c2) \
do { \
BN_ULONG lo, hi; \
sqr64(lo, hi, (a)[i]); \
c0 = (c0 + lo) & BN_MASK2; \
if (c0 < lo) \
hi++; \
c1 = (c1 + hi) & BN_MASK2; \
if (c1 < hi) \
c2++; \
} while (0)
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
#endif /* !BN_LLONG */
#endif /* !BN_ULLONG */
void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
BN_ULONG c1, c2, c3;
@@ -1022,110 +700,4 @@ void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) {
r[7] = c2;
}
#if defined(OPENSSL_NO_ASM) || (!defined(OPENSSL_ARM) && !defined(OPENSSL_X86_64))
/* This is essentially reference implementation, which may or may not
* result in performance improvement. E.g. on IA-32 this routine was
* observed to give 40% faster rsa1024 private key operations and 10%
* faster rsa4096 ones, while on AMD64 it improves rsa1024 sign only
* by 10% and *worsens* rsa4096 sign by 15%. Once again, it's a
* reference implementation, one to be used as starting point for
* platform-specific assembler. Mentioned numbers apply to compiler
* generated code compiled with and without -DOPENSSL_BN_ASM_MONT and
* can vary not only from platform to platform, but even for compiler
* versions. Assembler vs. assembler improvement coefficients can
* [and are known to] differ and are to be documented elsewhere. */
int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
const BN_ULONG *np, const BN_ULONG *n0p, int num) {
BN_ULONG c0, c1, ml, *tp, n0;
#ifdef mul64
BN_ULONG mh;
#endif
volatile BN_ULONG *vp;
int i = 0, j;
#if 0 /* template for platform-specific implementation */
if (ap==bp) return bn_sqr_mont(rp,ap,np,n0p,num);
#endif
vp = tp = alloca((num + 2) * sizeof(BN_ULONG));
n0 = *n0p;
c0 = 0;
ml = bp[0];
#ifdef mul64
mh = HBITS(ml);
ml = LBITS(ml);
for (j = 0; j < num; ++j) {
mul(tp[j], ap[j], ml, mh, c0);
}
#else
for (j = 0; j < num; ++j) {
mul(tp[j], ap[j], ml, c0);
}
#endif
tp[num] = c0;
tp[num + 1] = 0;
goto enter;
for (i = 0; i < num; i++) {
c0 = 0;
ml = bp[i];
#ifdef mul64
mh = HBITS(ml);
ml = LBITS(ml);
for (j = 0; j < num; ++j) {
mul_add(tp[j], ap[j], ml, mh, c0);
}
#else
for (j = 0; j < num; ++j) {
mul_add(tp[j], ap[j], ml, c0);
}
#endif
c1 = (tp[num] + c0) & BN_MASK2;
tp[num] = c1;
tp[num + 1] = (c1 < c0 ? 1 : 0);
enter:
c1 = tp[0];
ml = (c1 * n0) & BN_MASK2;
c0 = 0;
#ifdef mul64
mh = HBITS(ml);
ml = LBITS(ml);
mul_add(c1, np[0], ml, mh, c0);
#else
mul_add(c1, ml, np[0], c0);
#endif
for (j = 1; j < num; j++) {
c1 = tp[j];
#ifdef mul64
mul_add(c1, np[j], ml, mh, c0);
#else
mul_add(c1, ml, np[j], c0);
#endif
tp[j - 1] = c1 & BN_MASK2;
}
c1 = (tp[num] + c0) & BN_MASK2;
tp[num - 1] = c1;
tp[num] = tp[num + 1] + (c1 < c0 ? 1 : 0);
}
if (tp[num] != 0 || tp[num - 1] >= np[num - 1]) {
c0 = bn_sub_words(rp, tp, np, num);
if (tp[num] != 0 || c0 == 0) {
for (i = 0; i < num + 2; i++) {
vp[i] = 0;
}
return 1;
}
}
for (i = 0; i < num; i++) {
rp[i] = tp[i], vp[i] = 0;
}
vp[num] = 0;
vp[num + 1] = 0;
return 1;
}
#endif
#endif
+34 -88
View File
@@ -125,13 +125,15 @@
#include <openssl/base.h>
#if defined(OPENSSL_X86_64) && defined(_MSC_VER) && _MSC_VER >= 1400
#if defined(OPENSSL_X86_64) && defined(_MSC_VER)
#pragma warning(push, 3)
#include <intrin.h>
#pragma warning(pop)
#pragma intrinsic(__umulh, _umul128)
#endif
#include "../internal.h"
#if defined(__cplusplus)
extern "C" {
#endif
@@ -144,61 +146,60 @@ 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
#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 */
#define BN_MUL_RECURSIVE_SIZE_NORMAL (16) /* 32 less than */
#define BN_SQR_RECURSIVE_SIZE_NORMAL (16) /* 32 */
#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
/* bn_set_words sets |bn| to the value encoded in the |num| words in |words|,
* least significant word first. */
int bn_set_words(BIGNUM *bn, const BN_ULONG *words, size_t num);
BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num);
BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num);
BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num);
@@ -220,67 +221,12 @@ 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(OPENSSL_X86_64) && defined(_MSC_VER)
#define BN_UMULT_LOHI(low, high, a, b) ((low) = _umul128((a), (b), &(high)))
#endif
#define LBITS(a) ((a) & BN_MASK2l)
#define HBITS(a) (((a) >> BN_BITS4) & BN_MASK2l)
#define L2HBITS(a) (((a) << BN_BITS4) & BN_MASK2)
#define LLBITS(a) ((a) & BN_MASKl)
#define LHBITS(a) (((a) >> BN_BITS2) & BN_MASKl)
#define LL2HBITS(a) ((BN_ULLONG)((a) & BN_MASKl) << BN_BITS2)
#define mul64(l, h, bl, bh) \
{ \
BN_ULONG m, m1, lt, ht; \
\
lt = l; \
ht = h; \
m = (bh) * (lt); \
lt = (bl) * (lt); \
m1 = (bl) * (ht); \
ht = (bh) * (ht); \
m = (m + m1) & BN_MASK2; \
if (m < m1) \
ht += L2HBITS((BN_ULONG)1); \
ht += HBITS(m); \
m1 = L2HBITS(m); \
lt = (lt + m1) & BN_MASK2; \
if (lt < m1) \
ht++; \
(l) = lt; \
(h) = ht; \
}
#endif /* !defined(BN_LLONG) */
#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64)
# if defined(__GNUC__) && __GNUC__ >= 2
# define BN_UMULT_HIGH(a,b) ({ \
register BN_ULONG ret,discard; \
__asm__ ("mulq %3" \
: "=a"(discard),"=d"(ret) \
: "a"(a), "g"(b) \
: "cc"); \
ret; })
# define BN_UMULT_LOHI(low,high,a,b) \
__asm__ ("mulq %3" \
: "=a"(low),"=d"(high) \
: "a"(a),"g"(b) \
: "cc");
# elif defined(_MSC_VER) && _MSC_VER >= 1400
# define BN_UMULT_HIGH(a, b) __umulh((a), (b))
# define BN_UMULT_LOHI(low, high, a, b) ((low) = _umul128((a), (b), &(high)))
# endif
#elif !defined(OPENSSL_NO_ASM) && defined(OPENSSL_AARCH64)
# if defined(__GNUC__) && __GNUC__>=2
# define BN_UMULT_HIGH(a,b) ({ \
register BN_ULONG ret; \
__asm__ ("umulh %0,%1,%2" \
: "=r"(ret) \
: "r"(a), "r"(b)); \
ret; })
# endif
#if !defined(BN_ULLONG) && !defined(BN_UMULT_LOHI)
#error "Either BN_ULLONG or BN_UMULT_LOHI must be defined on every platform."
#endif
+26 -117
View File
@@ -118,8 +118,9 @@
#include "../internal.h"
#if !defined(OPENSSL_NO_ASM) && \
(defined(OPENSSL_X86) || defined(OPENSSL_X86_64))
#if !defined(OPENSSL_NO_ASM) && \
(defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \
defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))
#define OPENSSL_BN_ASM_MONT
#endif
@@ -130,16 +131,11 @@ BN_MONT_CTX *BN_MONT_CTX_new(void) {
return NULL;
}
BN_MONT_CTX_init(ret);
ret->flags = BN_FLG_MALLOCED;
return ret;
}
memset(ret, 0, sizeof(BN_MONT_CTX));
BN_init(&ret->RR);
BN_init(&ret->N);
void BN_MONT_CTX_init(BN_MONT_CTX *mont) {
memset(mont, 0, sizeof(BN_MONT_CTX));
BN_init(&mont->RR);
BN_init(&mont->N);
BN_init(&mont->Ni);
return ret;
}
void BN_MONT_CTX_free(BN_MONT_CTX *mont) {
@@ -149,23 +145,18 @@ void BN_MONT_CTX_free(BN_MONT_CTX *mont) {
BN_free(&mont->RR);
BN_free(&mont->N);
BN_free(&mont->Ni);
if (mont->flags & BN_FLG_MALLOCED) {
OPENSSL_free(mont);
}
OPENSSL_free(mont);
}
BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from) {
BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, const BN_MONT_CTX *from) {
if (to == from) {
return to;
}
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;
@@ -198,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
@@ -283,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)) {
@@ -336,14 +326,12 @@ int BN_to_montgomery(BIGNUM *ret, const BIGNUM *a, const BN_MONT_CTX *mont,
return BN_mod_mul_montgomery(ret, a, &mont->RR, mont, ctx);
}
#if 0
static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r,
const BN_MONT_CTX *mont) {
const BIGNUM *n;
BN_ULONG *ap, *np, *rp, n0, v, carry;
int nl, max, i;
n = &mont->N;
const BIGNUM *n = &mont->N;
nl = n->top;
if (nl == 0) {
ret->top = 0;
@@ -386,13 +374,13 @@ static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r,
{
BN_ULONG *nrp;
size_t m;
uintptr_t m;
v = bn_sub_words(rp, ap, np, nl) - carry;
/* if subtraction result is real, then trick unconditional memcpy below to
* perform in-place "refresh" instead of actual copy. */
m = (0 - (size_t)v);
nrp = (BN_ULONG *)(((intptr_t)rp & ~m) | ((intptr_t)ap & m));
m = (0u - (uintptr_t)v);
nrp = (BN_ULONG *)(((uintptr_t)rp & ~m) | ((uintptr_t)ap & m));
for (i = 0, nl -= 4; i < nl; i += 4) {
BN_ULONG t1, t2, t3, t4;
@@ -421,104 +409,25 @@ static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r,
return 1;
}
#endif
#define PTR_SIZE_INT size_t
static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, const BN_MONT_CTX *mont)
{
BIGNUM *n;
BN_ULONG *ap,*np,*rp,n0,v,carry;
int nl,max,i;
n= (BIGNUM*) &(mont->N);
nl=n->top;
if (nl == 0) { ret->top=0; return(1); }
max=(2*nl); /* carry is stored separately */
if (bn_wexpand(r,max) == NULL) return(0);
r->neg^=n->neg;
np=n->d;
rp=r->d;
/* clear the top words of T */
#if 1
for (i=r->top; i<max; i++) /* memset? XXX */
rp[i]=0;
#else
memset(&(rp[r->top]),0,(max-r->top)*sizeof(BN_ULONG));
#endif
r->top=max;
n0=mont->n0[0];
for (carry=0, i=0; i<nl; i++, rp++)
{
v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2);
v = (v+carry+rp[nl])&BN_MASK2;
carry |= (v != rp[nl]);
carry &= (v <= rp[nl]);
rp[nl]=v;
}
if (bn_wexpand(ret,nl) == NULL) return(0);
ret->top=nl;
ret->neg=r->neg;
rp=ret->d;
ap=&(r->d[nl]);
{
BN_ULONG *nrp;
size_t m;
v=bn_sub_words(rp,ap,np,nl)-carry;
/* if subtraction result is real, then
* trick unconditional memcpy below to perform in-place
* "refresh" instead of actual copy. */
m=(0-(size_t)v);
nrp=(BN_ULONG *)(((PTR_SIZE_INT)rp&~m)|((PTR_SIZE_INT)ap&m));
for (i=0,nl-=4; i<nl; i+=4)
{
BN_ULONG t1,t2,t3,t4;
t1=nrp[i+0];
t2=nrp[i+1];
t3=nrp[i+2]; ap[i+0]=0;
t4=nrp[i+3]; ap[i+1]=0;
rp[i+0]=t1; ap[i+2]=0;
rp[i+1]=t2; ap[i+3]=0;
rp[i+2]=t3;
rp[i+3]=t4;
}
for (nl+=4; i<nl; i++)
rp[i]=nrp[i], ap[i]=0;
}
bn_correct_top(r);
bn_correct_top(ret);
return(1);
}
int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, const BN_MONT_CTX *mont,
int BN_from_montgomery(BIGNUM *r, const BIGNUM *a, const BN_MONT_CTX *mont,
BN_CTX *ctx) {
int retn = 0;
int ret = 0;
BIGNUM *t;
BN_CTX_start(ctx);
t = BN_CTX_get(ctx);
if (t == NULL) {
return 0;
if (t == NULL ||
!BN_copy(t, a)) {
goto err;
}
if (BN_copy(t, a)) {
retn = BN_from_montgomery_word(ret, t, mont);
}
ret = BN_from_montgomery_word(r, t, mont);
err:
BN_CTX_end(ctx);
return retn;
return ret;
}
int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+8 -27
View File
@@ -62,7 +62,12 @@
#include "internal.h"
void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb) {
#define BN_MUL_RECURSIVE_SIZE_NORMAL 16
#define BN_SQR_RECURSIVE_SIZE_NORMAL BN_MUL_RECURSIVE_SIZE_NORMAL
static void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b,
int nb) {
BN_ULONG *rr;
if (na < nb) {
@@ -107,31 +112,6 @@ void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb) {
}
}
void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) {
bn_mul_words(r, a, n, b[0]);
for (;;) {
if (--n <= 0) {
return;
}
bn_mul_add_words(&(r[1]), a, n, b[1]);
if (--n <= 0) {
return;
}
bn_mul_add_words(&(r[2]), a, n, b[2]);
if (--n <= 0) {
return;
}
bn_mul_add_words(&(r[3]), a, n, b[3]);
if (--n <= 0) {
return;
}
bn_mul_add_words(&(r[4]), a, n, b[4]);
r += 4;
b += 4;
}
}
#if !defined(OPENSSL_X86) || defined(OPENSSL_NO_ASM)
/* Here follows specialised variants of bn_add_words() and bn_sub_words(). They
* have the property performing operations on arrays of different sizes. The
@@ -618,7 +598,8 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) {
}
}
if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) {
static const int kMulNormalSize = 16;
if (al >= kMulNormalSize && bl >= kMulNormalSize) {
if (i >= -1 && i <= 1) {
/* Find out the power of two lower or equal
to the longest of the two numbers */
+1 -1
View File
@@ -710,7 +710,7 @@ loop:
if (!BN_add_word(rnd, delta)) {
return 0;
}
if (BN_num_bits(rnd) != bits) {
if (BN_num_bits(rnd) != (unsigned)bits) {
goto again;
}
+21 -28
View File
@@ -48,6 +48,9 @@
#include <openssl/mem.h>
#include "../internal.h"
/*
* See crypto/bn/asm/rsaz-avx2.pl for further details.
*/
@@ -58,42 +61,30 @@ void rsaz_1024_scatter5_avx2(void *tbl,const void *val,int i);
void rsaz_1024_gather5_avx2(void *val,const void *tbl,int i);
void rsaz_1024_red2norm_avx2(void *norm,const void *red);
#if defined(__GNUC__)
# define ALIGN64 __attribute__((aligned(64)))
#elif defined(_MSC_VER)
# define ALIGN64 __declspec(align(64))
#elif defined(__SUNPRO_C)
# define ALIGN64
# pragma align 64(one,two80)
#else
# define ALIGN64 /* not fatal, might hurt performance a little */
#endif
ALIGN64 static const BN_ULONG one[40] =
alignas(64) static const BN_ULONG one[40] =
{1,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
ALIGN64 static const BN_ULONG two80[40] =
alignas(64) static const BN_ULONG two80[40] =
{0,0,1<<22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
void RSAZ_1024_mod_exp_avx2(BN_ULONG result_norm[16],
const BN_ULONG base_norm[16], const BN_ULONG exponent[16],
const BN_ULONG m_norm[16], const BN_ULONG RR[16], BN_ULONG k0)
{
unsigned char storage[320*3+32*9*16+64]; /* 5.5KB */
unsigned char *p_str = storage + (64-((size_t)storage%64));
alignas(64) uint8_t storage[(320 * 3) + (32 * 9 * 16)]; /* 5.5KB */
unsigned char *a_inv, *m, *result,
*table_s = p_str+320*3,
*table_s = storage + (320 * 3),
*R2 = table_s; /* borrow */
int index;
int wvalue;
if ((((size_t)p_str&4095)+320)>>12) {
result = p_str;
a_inv = p_str + 320;
m = p_str + 320*2; /* should not cross page */
if (((((uintptr_t)storage & 4095) + 320) >> 12) != 0) {
result = storage;
a_inv = storage + 320;
m = storage + (320 * 2); /* should not cross page */
} else {
m = p_str; /* should not cross page */
result = p_str + 320;
a_inv = p_str + 320*2;
m = storage; /* should not cross page */
result = storage + 320;
a_inv = storage + (320 * 2);
}
rsaz_1024_norm2red_avx2(m, m_norm);
@@ -224,8 +215,9 @@ void RSAZ_1024_mod_exp_avx2(BN_ULONG result_norm[16],
rsaz_1024_scatter5_avx2(table_s,result,31);
#endif
const uint8_t *p_str = (const uint8_t *)exponent;
/* load first window */
p_str = (unsigned char*)exponent;
wvalue = p_str[127] >> 3;
rsaz_1024_gather5_avx2(result,table_s,wvalue);
@@ -235,7 +227,7 @@ void RSAZ_1024_mod_exp_avx2(BN_ULONG result_norm[16],
rsaz_1024_sqr_avx2(result, result, m, k0, 5);
wvalue = *((unsigned short*)&p_str[index/8]);
wvalue = *((const unsigned short*)&p_str[index / 8]);
wvalue = (wvalue>> (index%8)) & 31;
index-=5;
@@ -274,11 +266,10 @@ void RSAZ_512_mod_exp(BN_ULONG result[8],
const BN_ULONG base[8], const BN_ULONG exponent[8],
const BN_ULONG m[8], BN_ULONG k0, const BN_ULONG RR[8])
{
unsigned char storage[16*8*8+64*2+64]; /* 1.2KB */
unsigned char *table = storage + (64-((size_t)storage%64));
alignas(64) uint8_t storage[(16*8*8) + (64 * 2)]; /* 1.2KB */
unsigned char *table = storage;
BN_ULONG *a_inv = (BN_ULONG *)(table+16*8*8),
*temp = (BN_ULONG *)(table+16*8*8+8*8);
unsigned char *p_str = (unsigned char*)exponent;
int index;
unsigned int wvalue;
@@ -300,6 +291,8 @@ void RSAZ_512_mod_exp(BN_ULONG result[8],
for (index=3; index<16; index++)
rsaz_512_mul_scatter4(temp, a_inv, m, k0, table, index);
const uint8_t *p_str = (const uint8_t *)exponent;
/* load first window */
wvalue = p_str[63];
+1 -1
View File
@@ -1,4 +1,4 @@
include_directories(. .. ../../include)
include_directories(../../include)
add_library(
buf
+1 -1
View File
@@ -220,7 +220,7 @@ size_t BUF_strlcat(char *dst, const char *src, size_t dst_size) {
void *BUF_memdup(const void *data, size_t dst_size) {
void *ret;
if (data == NULL) {
if (dst_size == 0) {
return NULL;
}
+3 -1
View File
@@ -1,10 +1,11 @@
include_directories(. .. ../../include)
include_directories(../../include)
add_library(
bytestring
OBJECT
asn1_compat.c
ber.c
cbs.c
cbb.c
@@ -19,3 +20,4 @@ add_executable(
)
target_link_libraries(bytestring_test crypto)
add_dependencies(all_tests bytestring_test)
+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 <openssl/bytestring.h>
#include <assert.h>
#include <limits.h>
#include <string.h>
#include <openssl/mem.h>
#include "internal.h"
int CBB_finish_i2d(CBB *cbb, uint8_t **outp) {
assert(cbb->base->can_resize);
uint8_t *der;
size_t der_len;
if (!CBB_finish(cbb, &der, &der_len)) {
CBB_cleanup(cbb);
return -1;
}
if (der_len > INT_MAX) {
OPENSSL_free(der);
return -1;
}
if (outp != NULL) {
if (*outp == NULL) {
*outp = der;
der = NULL;
} else {
memcpy(*outp, der, der_len);
*outp += der_len;
}
}
OPENSSL_free(der);
return (int)der_len;
}
+130 -88
View File
@@ -14,6 +14,7 @@
#include <openssl/bytestring.h>
#include <assert.h>
#include <string.h>
#include "internal.h"
@@ -24,11 +25,37 @@
* input could otherwise cause the stack to overflow. */
static const unsigned kMaxDepth = 2048;
/* is_string_type returns one if |tag| is a string type and zero otherwise. It
* ignores the constructed bit. */
static int is_string_type(unsigned tag) {
if ((tag & 0xc0) != 0) {
return 0;
}
switch (tag & 0x1f) {
case CBS_ASN1_BITSTRING:
case CBS_ASN1_OCTETSTRING:
case CBS_ASN1_UTF8STRING:
case CBS_ASN1_NUMERICSTRING:
case CBS_ASN1_PRINTABLESTRING:
case CBS_ASN1_T16STRING:
case CBS_ASN1_VIDEOTEXSTRING:
case CBS_ASN1_IA5STRING:
case CBS_ASN1_GRAPHICSTRING:
case CBS_ASN1_VISIBLESTRING:
case CBS_ASN1_GENERALSTRING:
case CBS_ASN1_UNIVERSALSTRING:
case CBS_ASN1_BMPSTRING:
return 1;
default:
return 0;
}
}
/* cbs_find_ber walks an ASN.1 structure in |orig_in| and sets |*ber_found|
* depending on whether an indefinite length element was found. The value of
* |in| is not changed. It returns one on success (i.e. |*ber_found| was set)
* and zero on error. */
static int cbs_find_ber(CBS *orig_in, char *ber_found, unsigned depth) {
* depending on whether an indefinite length element or constructed string was
* found. The value of |orig_in| is not changed. It returns one on success (i.e.
* |*ber_found| was set) and zero on error. */
static int cbs_find_ber(const CBS *orig_in, char *ber_found, unsigned depth) {
CBS in;
if (depth > kMaxDepth) {
@@ -49,10 +76,16 @@ static int cbs_find_ber(CBS *orig_in, char *ber_found, unsigned depth) {
if (CBS_len(&contents) == header_len &&
header_len > 0 &&
CBS_data(&contents)[header_len-1] == 0x80) {
/* Found an indefinite-length element. */
*ber_found = 1;
return 1;
}
if (tag & CBS_ASN1_CONSTRUCTED) {
if (is_string_type(tag)) {
/* Constructed strings are only legal in BER and require conversion. */
*ber_found = 1;
return 1;
}
if (!CBS_skip(&contents, header_len) ||
!cbs_find_ber(&contents, ber_found, depth + 1)) {
return 0;
@@ -63,16 +96,6 @@ static int cbs_find_ber(CBS *orig_in, char *ber_found, unsigned depth) {
return 1;
}
/* is_primitive_type returns true if |tag| likely a primitive type. Normally
* one can just test the "constructed" bit in the tag but, in BER, even
* primitive tags can have the constructed bit if they have indefinite
* length. */
static char is_primitive_type(unsigned tag) {
return (tag & 0xc0) == 0 &&
(tag & 0x1f) != (CBS_ASN1_SEQUENCE & 0x1f) &&
(tag & 0x1f) != (CBS_ASN1_SET & 0x1f);
}
/* is_eoc returns true if |header_len| and |contents|, as returned by
* |CBS_get_any_ber_asn1_element|, indicate an "end of contents" (EOC) value. */
static char is_eoc(size_t header_len, CBS *contents) {
@@ -81,111 +104,86 @@ static char is_eoc(size_t header_len, CBS *contents) {
}
/* cbs_convert_ber reads BER data from |in| and writes DER data to |out|. If
* |squash_header| is set then the top-level of elements from |in| will not
* have their headers written. This is used when concatenating the fragments of
* an indefinite length, primitive value. If |looking_for_eoc| is set then any
* EOC elements found will cause the function to return after consuming it.
* It returns one on success and zero on error. */
static int cbs_convert_ber(CBS *in, CBB *out, char squash_header,
* |string_tag| is non-zero, then all elements must match |string_tag| up to the
* constructed bit and primitive element bodies are written to |out| without
* element headers. This is used when concatenating the fragments of a
* constructed string. If |looking_for_eoc| is set then any EOC elements found
* will cause the function to return after consuming it. It returns one on
* success and zero on error. */
static int cbs_convert_ber(CBS *in, CBB *out, unsigned string_tag,
char looking_for_eoc, unsigned depth) {
assert(!(string_tag & CBS_ASN1_CONSTRUCTED));
if (depth > kMaxDepth) {
return 0;
}
while (CBS_len(in) > 0) {
CBS contents;
unsigned tag;
unsigned tag, child_string_tag = string_tag;
size_t header_len;
CBB *out_contents, out_contents_storage;
if (!CBS_get_any_ber_asn1_element(in, &contents, &tag, &header_len)) {
return 0;
}
out_contents = out;
if (CBS_len(&contents) == header_len) {
if (is_eoc(header_len, &contents)) {
return looking_for_eoc;
}
if (header_len > 0 && CBS_data(&contents)[header_len - 1] == 0x80) {
/* This is an indefinite length element. If it's a SEQUENCE or SET then
* we just need to write the out the contents as normal, but with a
* concrete length prefix.
*
* If it's a something else then the contents will be a series of BER
* elements of the same type which need to be concatenated. */
const char context_specific = (tag & 0xc0) == 0x80;
char squash_child_headers = is_primitive_type(tag);
/* This is a hack, but it sufficies to handle NSS's output. If we find
* an indefinite length, context-specific tag with a definite, primtive
* tag inside it, then we assume that the context-specific tag is
* implicit and the tags within are fragments of a primitive type that
* need to be concatenated. */
if (context_specific && (tag & CBS_ASN1_CONSTRUCTED)) {
CBS in_copy, inner_contents;
unsigned inner_tag;
size_t inner_header_len;
CBS_init(&in_copy, CBS_data(in), CBS_len(in));
if (!CBS_get_any_ber_asn1_element(&in_copy, &inner_contents,
&inner_tag, &inner_header_len)) {
return 0;
}
if (CBS_len(&inner_contents) > inner_header_len &&
is_primitive_type(inner_tag)) {
squash_child_headers = 1;
}
}
if (!squash_header) {
unsigned out_tag = tag;
if (squash_child_headers) {
out_tag &= ~CBS_ASN1_CONSTRUCTED;
}
if (!CBB_add_asn1(out, &out_contents_storage, out_tag)) {
return 0;
}
out_contents = &out_contents_storage;
}
if (!cbs_convert_ber(in, out_contents,
squash_child_headers,
1 /* looking for eoc */, depth + 1)) {
return 0;
}
if (out_contents != out && !CBB_flush(out)) {
return 0;
}
continue;
}
if (is_eoc(header_len, &contents)) {
return looking_for_eoc;
}
if (!squash_header) {
if (!CBB_add_asn1(out, &out_contents_storage, tag)) {
if (string_tag != 0) {
/* This is part of a constructed string. All elements must match
* |string_tag| up to the constructed bit and get appended to |out|
* without a child element. */
if ((tag & ~CBS_ASN1_CONSTRUCTED) != string_tag) {
return 0;
}
out_contents = out;
} else {
unsigned out_tag = tag;
if ((tag & CBS_ASN1_CONSTRUCTED) && is_string_type(tag)) {
/* If a constructed string, clear the constructed bit and inform
* children to concatenate bodies. */
out_tag &= ~CBS_ASN1_CONSTRUCTED;
child_string_tag = out_tag;
}
if (!CBB_add_asn1(out, &out_contents_storage, out_tag)) {
return 0;
}
out_contents = &out_contents_storage;
}
if (CBS_len(&contents) == header_len && header_len > 0 &&
CBS_data(&contents)[header_len - 1] == 0x80) {
/* This is an indefinite length element. */
if (!cbs_convert_ber(in, out_contents, child_string_tag,
1 /* looking for eoc */, depth + 1) ||
!CBB_flush(out)) {
return 0;
}
continue;
}
if (!CBS_skip(&contents, header_len)) {
return 0;
}
if (tag & CBS_ASN1_CONSTRUCTED) {
if (!cbs_convert_ber(&contents, out_contents, 0 /* don't squash header */,
/* Recurse into children. */
if (!cbs_convert_ber(&contents, out_contents, child_string_tag,
0 /* not looking for eoc */, depth + 1)) {
return 0;
}
} else {
/* Copy primitive contents as-is. */
if (!CBB_add_bytes(out_contents, CBS_data(&contents),
CBS_len(&contents))) {
return 0;
}
}
if (out_contents != out && !CBB_flush(out)) {
if (!CBB_flush(out)) {
return 0;
}
}
@@ -209,13 +207,57 @@ int CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len) {
return 1;
}
if (!CBB_init(&cbb, CBS_len(in))) {
return 0;
}
if (!cbs_convert_ber(in, &cbb, 0, 0, 0)) {
if (!CBB_init(&cbb, CBS_len(in)) ||
!cbs_convert_ber(in, &cbb, 0, 0, 0) ||
!CBB_finish(&cbb, out, out_len)) {
CBB_cleanup(&cbb);
return 0;
}
return CBB_finish(&cbb, out, out_len);
return 1;
}
int CBS_get_asn1_implicit_string(CBS *in, CBS *out, uint8_t **out_storage,
unsigned outer_tag, unsigned inner_tag) {
assert(!(outer_tag & CBS_ASN1_CONSTRUCTED));
assert(!(inner_tag & CBS_ASN1_CONSTRUCTED));
assert(is_string_type(inner_tag));
if (CBS_peek_asn1_tag(in, outer_tag)) {
/* Normal implicitly-tagged string. */
*out_storage = NULL;
return CBS_get_asn1(in, out, outer_tag);
}
/* Otherwise, try to parse an implicitly-tagged constructed string.
* |CBS_asn1_ber_to_der| is assumed to have run, so only allow one level deep
* of nesting. */
CBB result;
CBS child;
if (!CBB_init(&result, CBS_len(in)) ||
!CBS_get_asn1(in, &child, outer_tag | CBS_ASN1_CONSTRUCTED)) {
goto err;
}
while (CBS_len(&child) > 0) {
CBS chunk;
if (!CBS_get_asn1(&child, &chunk, inner_tag) ||
!CBB_add_bytes(&result, CBS_data(&chunk), CBS_len(&chunk))) {
goto err;
}
}
uint8_t *data;
size_t len;
if (!CBB_finish(&result, &data, &len)) {
goto err;
}
CBS_init(out, data, len);
*out_storage = data;
return 1;
err:
CBB_cleanup(&result);
return 0;
}
+157 -18
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) ||
@@ -365,6 +370,55 @@ static bool TestCBBPrefixed() {
return buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0;
}
static bool TestCBBDiscardChild() {
ScopedCBB cbb;
CBB contents, inner_contents, inner_inner_contents;
if (!CBB_init(cbb.get(), 0) ||
!CBB_add_u8(cbb.get(), 0xaa)) {
return false;
}
// Discarding |cbb|'s children preserves the byte written.
CBB_discard_child(cbb.get());
if (!CBB_add_u8_length_prefixed(cbb.get(), &contents) ||
!CBB_add_u8_length_prefixed(cbb.get(), &contents) ||
!CBB_add_u8(&contents, 0xbb) ||
!CBB_add_u16_length_prefixed(cbb.get(), &contents) ||
!CBB_add_u16(&contents, 0xcccc) ||
!CBB_add_u24_length_prefixed(cbb.get(), &contents) ||
!CBB_add_u24(&contents, 0xdddddd) ||
!CBB_add_u8_length_prefixed(cbb.get(), &contents) ||
!CBB_add_u8(&contents, 0xff) ||
!CBB_add_u8_length_prefixed(&contents, &inner_contents) ||
!CBB_add_u8(&inner_contents, 0x42) ||
!CBB_add_u16_length_prefixed(&inner_contents, &inner_inner_contents) ||
!CBB_add_u8(&inner_inner_contents, 0x99)) {
return false;
}
// Discard everything from |inner_contents| down.
CBB_discard_child(&contents);
uint8_t *buf;
size_t buf_len;
if (!CBB_finish(cbb.get(), &buf, &buf_len)) {
return false;
}
ScopedOpenSSLBytes scoper(buf);
static const uint8_t kExpected[] = {
0xaa,
0,
1, 0xbb,
0, 2, 0xcc, 0xcc,
0, 0, 3, 0xdd, 0xdd, 0xdd,
1, 0xff,
};
return buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0;
}
static bool TestCBBMisuse() {
CBB cbb, child, contents;
uint8_t *buf;
@@ -434,7 +488,7 @@ static bool TestCBBASN1() {
return false;
}
if (!CBB_add_asn1(&cbb, &contents, 0x30) ||
!CBB_add_bytes(&contents, bssl::vector_data(&test_data), 130) ||
!CBB_add_bytes(&contents, test_data.data(), 130) ||
!CBB_finish(&cbb, &buf, &buf_len)) {
CBB_cleanup(&cbb);
return false;
@@ -443,7 +497,7 @@ static bool TestCBBASN1() {
if (buf_len != 3 + 130 ||
memcmp(buf, "\x30\x81\x82", 3) != 0 ||
memcmp(buf + 3, bssl::vector_data(&test_data), 130) != 0) {
memcmp(buf + 3, test_data.data(), 130) != 0) {
return false;
}
@@ -451,7 +505,7 @@ static bool TestCBBASN1() {
return false;
}
if (!CBB_add_asn1(&cbb, &contents, 0x30) ||
!CBB_add_bytes(&contents, bssl::vector_data(&test_data), 1000) ||
!CBB_add_bytes(&contents, test_data.data(), 1000) ||
!CBB_finish(&cbb, &buf, &buf_len)) {
CBB_cleanup(&cbb);
return false;
@@ -460,7 +514,7 @@ static bool TestCBBASN1() {
if (buf_len != 4 + 1000 ||
memcmp(buf, "\x30\x82\x03\xe8", 4) != 0 ||
memcmp(buf + 4, bssl::vector_data(&test_data), 1000)) {
memcmp(buf + 4, test_data.data(), 1000)) {
return false;
}
@@ -469,7 +523,7 @@ static bool TestCBBASN1() {
}
if (!CBB_add_asn1(&cbb, &contents, 0x30) ||
!CBB_add_asn1(&contents, &inner_contents, 0x30) ||
!CBB_add_bytes(&inner_contents, bssl::vector_data(&test_data), 100000) ||
!CBB_add_bytes(&inner_contents, test_data.data(), 100000) ||
!CBB_finish(&cbb, &buf, &buf_len)) {
CBB_cleanup(&cbb);
return false;
@@ -478,7 +532,7 @@ static bool TestCBBASN1() {
if (buf_len != 5 + 5 + 100000 ||
memcmp(buf, "\x30\x83\x01\x86\xa5\x30\x83\x01\x86\xa0", 10) != 0 ||
memcmp(buf + 10, bssl::vector_data(&test_data), 100000)) {
memcmp(buf + 10, test_data.data(), 100000)) {
return false;
}
@@ -525,7 +579,7 @@ static bool TestBerConvert() {
static const uint8_t kIndefBER[] = {0x30, 0x80, 0x01, 0x01, 0x02, 0x00, 0x00};
static const uint8_t kIndefDER[] = {0x30, 0x03, 0x01, 0x01, 0x02};
// kOctetStringBER contains an indefinite length OCTETSTRING with two parts.
// kOctetStringBER contains an indefinite length OCTET STRING with two parts.
// These parts need to be concatenated in DER form.
static const uint8_t kOctetStringBER[] = {0x24, 0x80, 0x04, 0x02, 0, 1,
0x04, 0x02, 2, 3, 0x00, 0x00};
@@ -555,6 +609,16 @@ static bool TestBerConvert() {
0x6e, 0x10, 0x9b, 0xb8, 0x02, 0x02, 0x07, 0xd0,
};
// kConstructedStringBER contains a deeply-nested constructed OCTET STRING.
// The BER conversion collapses this to one level deep, but not completely.
static const uint8_t kConstructedStringBER[] = {
0xa0, 0x10, 0x24, 0x06, 0x04, 0x01, 0x00, 0x04, 0x01,
0x01, 0x24, 0x06, 0x04, 0x01, 0x02, 0x04, 0x01, 0x03,
};
static const uint8_t kConstructedStringDER[] = {
0xa0, 0x08, 0x04, 0x02, 0x00, 0x01, 0x04, 0x02, 0x02, 0x03,
};
return DoBerConvert("kSimpleBER", kSimpleBER, sizeof(kSimpleBER),
kSimpleBER, sizeof(kSimpleBER)) &&
DoBerConvert("kIndefBER", kIndefDER, sizeof(kIndefDER), kIndefBER,
@@ -563,7 +627,59 @@ static bool TestBerConvert() {
sizeof(kOctetStringDER), kOctetStringBER,
sizeof(kOctetStringBER)) &&
DoBerConvert("kNSSBER", kNSSDER, sizeof(kNSSDER), kNSSBER,
sizeof(kNSSBER));
sizeof(kNSSBER)) &&
DoBerConvert("kConstructedStringBER", kConstructedStringDER,
sizeof(kConstructedStringDER), kConstructedStringBER,
sizeof(kConstructedStringBER));
}
struct ImplicitStringTest {
const char *in;
size_t in_len;
bool ok;
const char *out;
size_t out_len;
};
static const ImplicitStringTest kImplicitStringTests[] = {
// A properly-encoded string.
{"\x80\x03\x61\x61\x61", 5, true, "aaa", 3},
// An implicit-tagged string.
{"\xa0\x09\x04\x01\x61\x04\x01\x61\x04\x01\x61", 11, true, "aaa", 3},
// |CBS_get_asn1_implicit_string| only accepts one level deep of nesting.
{"\xa0\x0b\x24\x06\x04\x01\x61\x04\x01\x61\x04\x01\x61", 13, false, nullptr,
0},
// The outer tag must match.
{"\x81\x03\x61\x61\x61", 5, false, nullptr, 0},
{"\xa1\x09\x04\x01\x61\x04\x01\x61\x04\x01\x61", 11, false, nullptr, 0},
// The inner tag must match.
{"\xa1\x09\x0c\x01\x61\x0c\x01\x61\x0c\x01\x61", 11, false, nullptr, 0},
};
static bool TestImplicitString() {
for (const auto &test : kImplicitStringTests) {
uint8_t *storage = nullptr;
CBS in, out;
CBS_init(&in, reinterpret_cast<const uint8_t *>(test.in), test.in_len);
int ok = CBS_get_asn1_implicit_string(&in, &out, &storage,
CBS_ASN1_CONTEXT_SPECIFIC | 0,
CBS_ASN1_OCTETSTRING);
ScopedOpenSSLBytes scoper(storage);
if (static_cast<bool>(ok) != test.ok) {
fprintf(stderr, "CBS_get_asn1_implicit_string unexpectedly %s\n",
ok ? "succeeded" : "failed");
return false;
}
if (ok && (CBS_len(&out) != test.out_len ||
memcmp(CBS_data(&out), test.out, test.out_len) != 0)) {
fprintf(stderr, "CBS_get_asn1_implicit_string gave the wrong output\n");
return false;
}
}
return true;
}
struct ASN1Uint64Test {
@@ -578,9 +694,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},
};
@@ -649,12 +765,32 @@ static bool TestASN1Uint64() {
return true;
}
static int TestZero() {
static bool TestZero() {
CBB cbb;
CBB_zero(&cbb);
// Calling |CBB_cleanup| on a zero-state |CBB| must not crash.
CBB_cleanup(&cbb);
return 1;
return true;
}
static bool TestCBBReserve() {
uint8_t buf[10];
uint8_t *ptr;
size_t len;
ScopedCBB cbb;
if (!CBB_init_fixed(cbb.get(), buf, sizeof(buf)) ||
// Too large.
CBB_reserve(cbb.get(), &ptr, 11) ||
// Successfully reserve the entire space.
!CBB_reserve(cbb.get(), &ptr, 10) ||
ptr != buf ||
// Advancing under the maximum bytes is legal.
!CBB_did_write(cbb.get(), 5) ||
!CBB_finish(cbb.get(), NULL, &len) ||
len != 5) {
return false;
}
return true;
}
int main(void) {
@@ -670,11 +806,14 @@ int main(void) {
!TestCBBFinishChild() ||
!TestCBBMisuse() ||
!TestCBBPrefixed() ||
!TestCBBDiscardChild() ||
!TestCBBASN1() ||
!TestBerConvert() ||
!TestImplicitString() ||
!TestASN1Uint64() ||
!TestGetOptionalASN1Bool() ||
!TestZero()) {
!TestZero() ||
!TestCBBReserve()) {
return 1;
}
+77 -25
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;
}
@@ -70,6 +72,10 @@ int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len) {
void CBB_cleanup(CBB *cbb) {
if (cbb->base) {
/* Only top-level |CBB|s are cleaned up. Child |CBB|s are non-owning. They
* are implicitly discarded when the parent is flushed or cleaned up. */
assert(cbb->is_top_level);
if (cbb->base->can_resize) {
OPENSSL_free(cbb->base->buf);
}
@@ -78,8 +84,8 @@ void CBB_cleanup(CBB *cbb) {
cbb->base = NULL;
}
static int cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out,
size_t len) {
static int cbb_buffer_reserve(struct cbb_buffer_st *base, uint8_t **out,
size_t len) {
size_t newlen;
if (base == NULL) {
@@ -115,7 +121,17 @@ static int cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out,
if (out) {
*out = base->buf + base->len;
}
base->len = newlen;
return 1;
}
static int cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out,
size_t len) {
if (!cbb_buffer_reserve(base, out, len)) {
return 0;
}
/* This will not overflow or |cbb_buffer_reserve| would have failed. */
base->len += len;
return 1;
}
@@ -173,28 +189,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. */
@@ -226,12 +242,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) {
@@ -240,17 +257,20 @@ 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;
}
const uint8_t *CBB_data(const CBB *cbb) {
assert(cbb->child == NULL);
return cbb->base->buf + cbb->offset + cbb->pending_len_len;
}
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,
@@ -261,7 +281,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;
}
@@ -270,8 +290,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;
}
@@ -299,7 +320,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;
}
@@ -307,8 +328,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;
}
@@ -332,6 +354,25 @@ int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len) {
return 1;
}
int CBB_reserve(CBB *cbb, uint8_t **out_data, size_t len) {
if (!CBB_flush(cbb) ||
!cbb_buffer_reserve(cbb->base, out_data, len)) {
return 0;
}
return 1;
}
int CBB_did_write(CBB *cbb, size_t len) {
size_t newlen = cbb->base->len + len;
if (cbb->child != NULL ||
newlen < cbb->base->len ||
newlen > cbb->base->cap) {
return 0;
}
cbb->base->len = newlen;
return 1;
}
int CBB_add_u8(CBB *cbb, uint8_t value) {
if (!CBB_flush(cbb)) {
return 0;
@@ -356,6 +397,17 @@ int CBB_add_u24(CBB *cbb, uint32_t value) {
return cbb_buffer_add_u(cbb->base, value, 3);
}
void CBB_discard_child(CBB *cbb) {
if (cbb->child == NULL) {
return;
}
cbb->base->len = cbb->child->offset;
cbb->child->base = NULL;
cbb->child = NULL;
}
int CBB_add_asn1_uint64(CBB *cbb, uint64_t value) {
CBB child;
size_t i;

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