Bump revision of BoringSSL.

This depends on https://android-review.googlesource.com/#/c/153481/

af0e32c Add SSL_get_tls_unique.
691992b Minor typo fix in comment.
cc1e3df Make CBS_get_any_asn1_element accept only DER.
0976096 bytestring: Test out_header_len != NULL before writing.
ba5934b Tighten up EMS resumption behaviour.
b0eef0a runner: minor tidyups.
9f8ef2d Add |EVP_get_digestbyname|.
b7326b0 Implement |PEM_def_callback| and call it where appropriate.
e26e590 Avoid unused variable warnings with assert.
efad697 Sync vs_toolschain.py up with Chromium.
39da317 Empty commit to kick the bots.
1550a84 Allow compilation for armv6
9a4996e Fix compilation of sha256-armv4.S when using -march=armv6
485a50a Match the ifdef check in bsaes-armv7.S
e216288 Unexport and prune EVP_MD_CTX flags.
af8731f Remove HMAC_CTX_set_flags.
bf3208b Add additional HMAC tests.
a1c90a5 Further tidy up cipher logic.
0fa4012 Add a test that DTLS does not support RC4.
9a980ab Fold TLS1_PRF_* into SSL_HANDSHAKE_MAC_*
29864b5 Remove SSL_CIPHER_ALGORITHM2_AEAD.
904dc72 Fold away SSL_PROTOCOL_METHOD hooks shared between TLS and DTLS.
a602277 Split ssl_read_bytes hook into app_data and close_notify hooks.
c933a47 Switch the ssl_write_bytes hook to ssl_write_app_data.
2c36792 EVP_Digest*Update, EVP_DigestFinal, and HMAC_Update can never fail.
e2375e1 Low-level hash 'final' functions cannot fail.
049756b Fix integer types in low-level hash functions.
338e067 Reject sessions with the wrong structure version.
f297e02 Reject unknown fields in d2i_SSL_SESSION.
8a228f5 Disable the malloc interceptor without glibc.
bd15a8e Fix DTLS handling of multiple records in a packet.
15eaafb Fix bn_test's bc output and shut it up a little.
efd8eb3 Tidy up overflows in obj_cmp.
05ead68 Readd CRYPTO_{LOCK|UNLOCK|READ|WRITE}.
71106ad Add |BIO_read_asn1| to read a single ASN.1 object.
eb930b8 Fix signed/unsigned warning in bn_test.cc.
b3a7b51 Fix off-by-one in BN_rand
074cc04 Reject negative shifts for BN_rshift and BN_lshift.
75fb74a aes/asm/bsaes-armv7.pl: fix compilation with Xcode 6.3.
ff81e10 Add OPENSSL_PUT_ERROR line to X509V3_parse_list.
1590811 Fix typo in valid_star.
e76ccae Release handshake buffer when sending no certificate.
5f04b65 Release the handshake buffer on the client for abbreviated handshakes.
5c1ce29 Decide whether or not to request client certificates early.
4b30b28 Remove server-side renego session resumption check.
5aea93e Deprecate and no-op SSL_VERIFY_CLIENT_ONCE.
34a1635 Remove fake RLE compression OID.
9c0918f Fix typo in objects.txt
91af02a Add some comments and tweak assertions for cbc.c.
74d8bc2 Don't make SSL_MODE_*HELLO_TIME configurable.
7b5aff4 Have consumers supply OPENSSL_C11_ATOMIC.
ac63748 Revert "tool: we don't need -lrt."
444dce4 Do-nothing fns |OpenSSL_add_all_ciphers| and |OpenSSL_add_all_digests|.
ece089c Deprecate and no-op SSL_set_state.
be05c63 Remove compatibility s->version checks.
8ec8810 Remove SSL_in_before and SSL_ST_BEFORE.
cd90f3a Remove renegotiation deferral logic.
44d3eed Forbid caller-initiated renegotiations and all renego as a servers.
3d59e04 Fix test used for not-in-place CBC mode.
5f387e3 Remove s->renegotiate check in SSL_clear.
20f6e97 Switch three more renegotiate checks to initial_handshake_complete.
d23d5a5 Remove remnants of DTLS renegotiate.
9a41d1b Deprecate SSL_*_read_ahead and enforce DTLS packet boundaries.
76e48c5 Fix Windows mode.
3fa65f0 Fix some malloc test crashs.
0b635c5 Add malloc test support to unit tests.
3e3090d Pass a dtls1_use_epoch enum down to dtls1_seal_record.
31a0779 Factor SSL_AEAD_CTX into a dedicated type.
69d07d9 Get version-related functions from crypto.h rather than ssl.h.
b487df6 Pull version, option, and mode APIs into their own sections.
7270cfc Prune version constants.
7ef9fff Remove ssl_ok.
afc9ecd Unexport ssl_get_new_session and ssl_update_cache.
3b7456e Fix some documentation typos.
b480428 Also skip #elif lines.
6deacb3 Parse macros in getNameFromDecl.
4831c33 Document some core SSL_CTX and SSL methods.
4dab297 Don't use struct names in ssl.h.
760b1dd Tidy up state machine coverage tests.
3629c7b Add client peer-initiated renego to the state machine tests.
cff0b90 Add client-side tests for renegotiation_info enforcement.
6bff1ca Specify argc and argv arguments to refcount_test:main.
12a4768 Try to fix MSVC and __STDC_VERSION__ again.
cb56c2a Cast refcounts to _Atomic before use.
0d1d0d5 Try again to only test __STDC_VERSION__ when defined.
7b348dc Disable C11 atomics on OS X.
04edcc8 Tag the mutex functions with OPENSSL_EXPORT.
6e1f645 Don't test __STDC_VERSION__ unless it's defined.
552df47 Remove leftovers of the old-style locks.
6fb174e Remove last references to named locks.
4bdb6e4 Remove remaining calls to the old lock functions.
03163f3 Remove |CRYPTO_add|.
0b5e390 Convert reference counts in ssl/
0da323a Convert reference counts in crypto/
6f2e733 Add infrastructure for reference counts.
daaff93 Use C11 _Static_assert where available.
dc8c739 Implement |DES_ede2_cbc_encrypt|.
a7997f1 Set minimum DH group size to 1024 bits.
4a7b70d Add LICENSE file.
b3a262c Fix |SSLeay|.
f0320d3 Fix use after free in X509.
3dacff9 Always include x86_64-gcc.c in the standalone build.
9660032 Don't use x86_64-gcc.c with NO_ASM.
81091d5 Don't use uninitialized memory in RAND_bytes.
d72e284 Support arbitrary elliptic curve groups.
a07c0fc Fix SSL_get_current_cipher.
4b27d9f Never resume sessions on renegotiations.
785e07b Copy ecdsa_meth in EC_KEY_copy.
08dc68d Define no-op options consistently.
e6df054 Add s->s3->initial_handshake_complete.
897e5e0 Default renegotiations to off.
4690bb5 Port cipher_test to file_test.
771a138 Add missing #include for abort()
de12d6c Mind the end of the buffer in aligned case of generic RC4 implementation.
5694b3a Fix invalid assert in CRYPTO_ctr128_encrypt.
9b68e72 Define compatibility function |ERR_remove_state|.
2607383 Fix generate_build_files.py to account for crypto/test.
af3d5bd Add no-op |RAND_load_file| function for compatibility.
58e95fc Remove a spurious semicolon after |DECLARE_LHASH_OF|.
3c65171 Add buffer.h for compatibility.
c85373d Use EVP_AEAD_CTX in crypto/cipher/internal.h.

Change-Id: Ife3698f4520572e1fca48732c6a1cbd4254ec85c
diff --git a/BORINGSSL_REVISION b/BORINGSSL_REVISION
index 5c95a3d..d63fc86 100644
--- a/BORINGSSL_REVISION
+++ b/BORINGSSL_REVISION
@@ -1 +1 @@
-5aa8a8643851e309b48a1b5a5d91d2fd183eae52
+af0e32cb84f0c9cc65b9233a3414d2562642b342
diff --git a/android_compat_hacks.c b/android_compat_hacks.c
index 8eac801..cf4863d 100644
--- a/android_compat_hacks.c
+++ b/android_compat_hacks.c
@@ -53,11 +53,6 @@
   return BN_bin2bn(data, sizeof(data), NULL);
 }
 
-void ERR_remove_state(unsigned long pid) {
-  assert(pid == 0);
-  ERR_remove_thread_state(NULL);
-}
-
 int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len) {
   return 0;
 }
diff --git a/err_data.c b/err_data.c
index f09b1c2..5a79137 100644
--- a/err_data.c
+++ b/err_data.c
@@ -54,227 +54,229 @@
 OPENSSL_COMPILE_ASSERT(ERR_NUM_LIBS == 33, library_values_changed_num);
 
 const uint32_t kOpenSSLFunctionValues[] = {
-    0xc320540,
-    0xc32854b,
-    0xc330556,
-    0xc338563,
-    0xc34056d,
-    0xc348577,
-    0xc35057e,
-    0xc35858a,
-    0xc360591,
-    0xc3685a7,
-    0xc3705bc,
-    0xc3785cd,
-    0xc3805dd,
-    0xc3885f7,
-    0xc39060c,
-    0xc39861b,
-    0xc3a0634,
-    0xc3a8648,
-    0xc3b0654,
-    0xc3b865b,
-    0xc3c0663,
-    0xc3c8671,
-    0xc3d0679,
-    0xc3d8681,
-    0xc3e068c,
-    0x1032191e,
-    0x10329935,
-    0x1033194e,
-    0x10339964,
-    0x10341974,
-    0x10349987,
-    0x10351995,
-    0x103599a4,
-    0x103619c4,
-    0x103699e3,
-    0x10371a00,
-    0x10379a1d,
-    0x10381a32,
-    0x10389a54,
-    0x10391a73,
-    0x10399a92,
-    0x103a1aa9,
-    0x103a9ac0,
-    0x103b1ac9,
-    0x103b9ad4,
-    0x103c1aee,
-    0x103c9af6,
-    0x103d1afe,
-    0x103d9b05,
-    0x103e1b18,
-    0x103e9b2a,
-    0x103f1b3d,
-    0x103f9b46,
-    0x14320a2f,
-    0x14328a3d,
-    0x14330a49,
-    0x14338a56,
-    0x18361205,
-    0x18371233,
-    0x18379244,
-    0x1838125a,
-    0x1839127d,
-    0x18399292,
-    0x183a12a4,
-    0x183c12e8,
-    0x183c92f6,
-    0x183d1309,
-    0x183d9319,
-    0x183e933f,
-    0x183f1352,
-    0x183f9361,
-    0x1840938b,
-    0x184113f7,
-    0x18419408,
-    0x1842141b,
-    0x1842942d,
-    0x1843143f,
-    0x18439450,
-    0x18441461,
-    0x18449472,
-    0x18451483,
-    0x18459490,
-    0x184614b2,
-    0x184694c5,
-    0x184714d9,
-    0x184794e6,
-    0x184814f5,
-    0x18489504,
-    0x18491515,
-    0x18499531,
-    0x184a153f,
-    0x184a9550,
-    0x184b1561,
-    0x184b956f,
-    0x184c157f,
-    0x184c95a5,
-    0x184d15b4,
-    0x184d95c4,
-    0x184e15d4,
-    0x184e95e3,
-    0x184f1522,
-    0x184f9194,
-    0x18501137,
-    0x1850914f,
-    0x18511171,
-    0x18519183,
-    0x185211b5,
-    0x185291ce,
-    0x185311df,
-    0x185391f5,
-    0x1854121a,
-    0x1854926b,
-    0x185512b4,
-    0x185592c9,
-    0x185612d6,
-    0x1856932e,
-    0x18571371,
-    0x1857937e,
-    0x1858139a,
-    0x185893ab,
-    0x185913bb,
-    0x185993cb,
-    0x185a13da,
-    0x185a93e9,
-    0x185b149e,
-    0x1c320699,
-    0x1c3286a5,
-    0x1c3306b0,
-    0x1c3386bc,
-    0x203215f7,
-    0x20329602,
-    0x2033160a,
-    0x20339616,
-    0x24321622,
-    0x24329630,
-    0x24331642,
-    0x24339651,
-    0x24341664,
-    0x24349677,
-    0x2435168e,
-    0x243596a6,
-    0x243616b4,
-    0x243696cc,
-    0x243716d5,
-    0x243796e7,
-    0x243816fb,
-    0x24389708,
-    0x2439171e,
-    0x24399736,
-    0x243a174e,
-    0x243a9758,
-    0x243b176d,
-    0x243b977b,
-    0x243c1793,
-    0x243c97aa,
-    0x243d17b5,
-    0x243d97c3,
-    0x28320a8f,
-    0x28328a9e,
-    0x28330aa9,
-    0x28338aae,
-    0x28340ab9,
-    0x2c322aa0,
-    0x2c32aaac,
-    0x2c332abf,
-    0x2c33aad0,
-    0x2c342ae9,
-    0x2c34ab11,
-    0x2c352b28,
-    0x2c35ab45,
-    0x2c362b62,
-    0x2c36ab7f,
-    0x2c372b98,
-    0x2c37abb1,
-    0x2c382bc7,
-    0x2c38abd5,
-    0x2c392be7,
-    0x2c39ac04,
-    0x2c3a2c21,
-    0x2c3aac2f,
-    0x2c3b2c4d,
-    0x2c3bac6b,
-    0x2c3c2c86,
-    0x2c3cac9a,
-    0x2c3d2cac,
-    0x2c3dacbc,
-    0x2c3e2cca,
-    0x2c3eacda,
-    0x2c3f2cea,
-    0x2c3fad05,
-    0x2c402d16,
-    0x2c40ad31,
-    0x2c412d45,
-    0x2c41ad58,
-    0x2c422d77,
-    0x2c42ad8b,
-    0x2c432d9e,
-    0x2c43adad,
-    0x2c442dbc,
-    0x2c44add3,
-    0x2c452dee,
-    0x2c45ae06,
-    0x2c462e1a,
-    0x2c46ae2d,
-    0x2c472e3e,
-    0x2c47ae4f,
-    0x2c482e60,
-    0x2c48ae71,
-    0x2c492e80,
-    0x2c49ae8d,
-    0x2c4a2e9a,
-    0x2c4aaea7,
-    0x2c4b2eb0,
-    0x2c4baec4,
-    0x2c4c2ed3,
-    0x2c4caee1,
-    0x2c4d2f03,
-    0x2c4daf14,
-    0x2c4e2f25,
-    0x2c4eaef0,
-    0x2c4f2b02,
+    0xc32054b,
+    0xc328556,
+    0xc330561,
+    0xc33856e,
+    0xc340578,
+    0xc348582,
+    0xc350589,
+    0xc358595,
+    0xc36059c,
+    0xc3685b2,
+    0xc3705d1,
+    0xc3785e2,
+    0xc3805f2,
+    0xc38860c,
+    0xc390621,
+    0xc398630,
+    0xc3a0649,
+    0xc3a865d,
+    0xc3b0669,
+    0xc3b8670,
+    0xc3c0678,
+    0xc3c8690,
+    0xc3d0698,
+    0xc3d86a0,
+    0xc3e06ab,
+    0xc3e85c7,
+    0xc3f0686,
+    0x1032193d,
+    0x10329954,
+    0x1033196d,
+    0x10339983,
+    0x10341993,
+    0x103499a6,
+    0x103519b4,
+    0x103599c3,
+    0x103619e3,
+    0x10369a02,
+    0x10371a1f,
+    0x10379a3c,
+    0x10381a51,
+    0x10389a73,
+    0x10391a92,
+    0x10399ab1,
+    0x103a1ac8,
+    0x103a9adf,
+    0x103b1ae8,
+    0x103b9af3,
+    0x103c1b0d,
+    0x103c9b15,
+    0x103d1b1d,
+    0x103d9b24,
+    0x103e1b37,
+    0x103e9b49,
+    0x103f1b5c,
+    0x103f9b65,
+    0x14320a4e,
+    0x14328a5c,
+    0x14330a68,
+    0x14338a75,
+    0x18361224,
+    0x18371252,
+    0x18379263,
+    0x18381279,
+    0x1839129c,
+    0x183992b1,
+    0x183a12c3,
+    0x183c1307,
+    0x183c9315,
+    0x183d1328,
+    0x183d9338,
+    0x183e935e,
+    0x183f1371,
+    0x183f9380,
+    0x184093aa,
+    0x18411416,
+    0x18419427,
+    0x1842143a,
+    0x1842944c,
+    0x1843145e,
+    0x1843946f,
+    0x18441480,
+    0x18449491,
+    0x184514a2,
+    0x184594af,
+    0x184614d1,
+    0x184694e4,
+    0x184714f8,
+    0x18479505,
+    0x18481514,
+    0x18489523,
+    0x18491534,
+    0x18499550,
+    0x184a155e,
+    0x184a956f,
+    0x184b1580,
+    0x184b958e,
+    0x184c159e,
+    0x184c95c4,
+    0x184d15d3,
+    0x184d95e3,
+    0x184e15f3,
+    0x184e9602,
+    0x184f1541,
+    0x184f91b3,
+    0x18501156,
+    0x1850916e,
+    0x18511190,
+    0x185191a2,
+    0x185211d4,
+    0x185291ed,
+    0x185311fe,
+    0x18539214,
+    0x18541239,
+    0x1854928a,
+    0x185512d3,
+    0x185592e8,
+    0x185612f5,
+    0x1856934d,
+    0x18571390,
+    0x1857939d,
+    0x185813b9,
+    0x185893ca,
+    0x185913da,
+    0x185993ea,
+    0x185a13f9,
+    0x185a9408,
+    0x185b14bd,
+    0x1c3206b8,
+    0x1c3286c4,
+    0x1c3306cf,
+    0x1c3386db,
+    0x20321616,
+    0x20329621,
+    0x20331629,
+    0x20339635,
+    0x24321641,
+    0x2432964f,
+    0x24331661,
+    0x24339670,
+    0x24341683,
+    0x24349696,
+    0x243516ad,
+    0x243596c5,
+    0x243616d3,
+    0x243696eb,
+    0x243716f4,
+    0x24379706,
+    0x2438171a,
+    0x24389727,
+    0x2439173d,
+    0x24399755,
+    0x243a176d,
+    0x243a9777,
+    0x243b178c,
+    0x243b979a,
+    0x243c17b2,
+    0x243c97c9,
+    0x243d17d4,
+    0x243d97e2,
+    0x28320aae,
+    0x28328abd,
+    0x28330ac8,
+    0x28338acd,
+    0x28340ad8,
+    0x2c322b00,
+    0x2c32ab0c,
+    0x2c332b1f,
+    0x2c33ab30,
+    0x2c342b49,
+    0x2c34ab71,
+    0x2c352b88,
+    0x2c35aba5,
+    0x2c362bc2,
+    0x2c36abdf,
+    0x2c372bf8,
+    0x2c37ac11,
+    0x2c382c27,
+    0x2c38ac35,
+    0x2c392c47,
+    0x2c39ac64,
+    0x2c3a2c81,
+    0x2c3aac8f,
+    0x2c3b2cad,
+    0x2c3baccb,
+    0x2c3c2ce6,
+    0x2c3cacfa,
+    0x2c3d2d0c,
+    0x2c3dad1c,
+    0x2c3e2d2a,
+    0x2c3ead3a,
+    0x2c3f2d4a,
+    0x2c3fad65,
+    0x2c402d76,
+    0x2c40ad91,
+    0x2c412da5,
+    0x2c41adb8,
+    0x2c422dd7,
+    0x2c42adeb,
+    0x2c432dfe,
+    0x2c43ae0d,
+    0x2c442e1c,
+    0x2c44ae33,
+    0x2c452e4e,
+    0x2c45ae66,
+    0x2c462e7a,
+    0x2c46ae8d,
+    0x2c472e9e,
+    0x2c47aeaf,
+    0x2c482ec0,
+    0x2c48aed1,
+    0x2c492ee0,
+    0x2c49aeed,
+    0x2c4a2efa,
+    0x2c4aaf07,
+    0x2c4b2f10,
+    0x2c4baf24,
+    0x2c4c2f33,
+    0x2c4caf41,
+    0x2c4d2f63,
+    0x2c4daf74,
+    0x2c4e2f85,
+    0x2c4eaf50,
+    0x2c4f2b62,
     0x30320000,
     0x30328018,
     0x3033002c,
@@ -339,390 +341,395 @@
     0x30508404,
     0x30510413,
     0x3051841c,
-    0x343209b7,
-    0x343289c7,
-    0x343309d2,
-    0x343389df,
-    0x383209e8,
-    0x38328a00,
-    0x38330a13,
-    0x38338a1d,
-    0x3c320acc,
-    0x3c328ada,
-    0x3c330af1,
-    0x3c338b05,
-    0x3c340b37,
-    0x3c348b48,
-    0x3c350b54,
-    0x3c358b81,
-    0x3c360b93,
-    0x3c368bbc,
-    0x3c370bc9,
-    0x3c378bd6,
-    0x3c380be4,
-    0x3c388bf1,
-    0x3c390bfe,
-    0x3c398c22,
-    0x3c3a0c32,
-    0x3c3a8c4a,
-    0x3c3b0c5f,
-    0x3c3b8c74,
-    0x3c3c0c81,
-    0x3c3c8c94,
-    0x3c3d0ca7,
-    0x3c3d8ccb,
-    0x3c3e0cf3,
-    0x3c3e8d0c,
-    0x3c3f0d22,
-    0x3c3f8d2f,
-    0x3c400d42,
-    0x3c408d53,
-    0x3c410d64,
-    0x3c418d7d,
-    0x3c420d96,
-    0x3c428dac,
-    0x3c430dc9,
-    0x3c438ddf,
-    0x3c440e63,
-    0x3c448e8a,
-    0x3c450ea8,
-    0x3c458ec2,
-    0x3c460eda,
-    0x3c468ef2,
-    0x3c470f1d,
-    0x3c478f48,
-    0x3c480f69,
-    0x3c488f92,
-    0x3c490fad,
-    0x3c498fd6,
-    0x3c4a0fe3,
-    0x3c4a8ffa,
-    0x3c4b1011,
-    0x3c4b903a,
-    0x3c4c104a,
-    0x3c4c9056,
-    0x3c4d106e,
-    0x3c4d9081,
-    0x3c4e1092,
-    0x3c4e90a3,
-    0x3c4f10c9,
-    0x3c4f8ac0,
-    0x3c500dfb,
-    0x3c508e1b,
-    0x3c510e48,
-    0x3c518fc8,
-    0x3c5210b3,
-    0x3c528b68,
-    0x3c530b20,
-    0x40321b51,
-    0x40329b6b,
-    0x40331b93,
-    0x40339bab,
-    0x40341bc9,
-    0x40349c10,
-    0x40351c27,
-    0x40359c43,
-    0x40361c5f,
-    0x40369c79,
-    0x40371c98,
-    0x40379cb7,
-    0x40381ccf,
-    0x40389cec,
-    0x40391d0f,
-    0x40399d2c,
-    0x403a1d4a,
-    0x403a9d5a,
-    0x403b1d6f,
-    0x403b9d8b,
-    0x403c1da5,
-    0x403c9db0,
-    0x403d1dd3,
-    0x403d9df7,
-    0x403e1e0d,
-    0x403e9e17,
-    0x403f1e23,
-    0x403f9e34,
-    0x40401e4c,
-    0x40409e54,
-    0x40411e5d,
-    0x40419e66,
-    0x40421e8e,
-    0x40429ea2,
-    0x40431ead,
-    0x40439eb9,
-    0x40441f0d,
-    0x40449f19,
-    0x40451f26,
-    0x40459f39,
-    0x40461f51,
-    0x40469f69,
-    0x40471f7f,
-    0x40479f9a,
-    0x40481fb5,
-    0x40489fc9,
-    0x40491fe2,
-    0x40499ffb,
-    0x404a2015,
-    0x404aa01f,
-    0x404b202f,
-    0x404ba050,
-    0x404c206b,
-    0x404ca079,
-    0x404d2086,
-    0x404da09a,
-    0x404e20b2,
-    0x404ea0c0,
-    0x404f20ea,
-    0x404fa101,
-    0x40502113,
-    0x4050a144,
-    0x40512175,
-    0x4051a18a,
-    0x4052219b,
-    0x4052a1bb,
-    0x405321d6,
-    0x4053a1e6,
-    0x4054a1f2,
-    0x40552208,
-    0x4055a226,
-    0x40562233,
-    0x4056a23d,
-    0x4057224b,
-    0x4057a266,
-    0x40582281,
-    0x4058a2a0,
-    0x405922b5,
-    0x4059a2ca,
-    0x405a22e7,
-    0x405aa2fb,
-    0x405b2317,
-    0x405ba32d,
-    0x405c234a,
-    0x405ca35c,
-    0x405d2373,
-    0x405da384,
-    0x405e23a0,
-    0x405ea3b4,
-    0x405f23c4,
-    0x405fa3e0,
-    0x406023f5,
-    0x4060a40b,
-    0x40612428,
-    0x4061a441,
-    0x4062246b,
-    0x4062a474,
-    0x40632484,
-    0x4063a4bd,
-    0x406424d3,
-    0x4064a4f1,
-    0x40652506,
-    0x4065a523,
-    0x4066253a,
-    0x4066a558,
-    0x40672575,
-    0x4067a58c,
-    0x406825aa,
-    0x4068a5c1,
-    0x406925d9,
-    0x4069a5ea,
-    0x406a25fd,
-    0x406aa610,
-    0x406b2624,
-    0x406ba648,
-    0x406c2663,
-    0x406ca684,
-    0x406d26a8,
-    0x406da6c3,
-    0x406e26e4,
-    0x406ea6f9,
-    0x406f2712,
-    0x406fa71f,
-    0x4070272d,
-    0x4070a73a,
-    0x40712757,
-    0x4071a777,
-    0x40722792,
-    0x4072a7ab,
-    0x407327c2,
-    0x4073a7dc,
-    0x40742800,
-    0x4074a816,
-    0x4075282a,
-    0x4075a83f,
-    0x40762859,
-    0x4076a86b,
-    0x40772880,
-    0x4077a8a6,
-    0x407828c3,
-    0x4078a8e6,
-    0x4079290c,
-    0x4079a929,
-    0x407a294c,
-    0x407aa968,
-    0x407b2984,
-    0x407ba996,
-    0x407c29a3,
-    0x407e29b0,
-    0x407ea9c6,
-    0x407f29de,
-    0x407fa9f1,
-    0x40802a06,
-    0x4080aa1f,
-    0x40812a3d,
-    0x4081aa5d,
-    0x40822a66,
-    0x4082aa82,
-    0x40832a8b,
-    0x4083a0cf,
-    0x4084215e,
-    0x4084a12e,
-    0x408524ac,
-    0x4085a490,
-    0x40861be8,
-    0x40869bfb,
-    0x40871eed,
-    0x40879efc,
-    0x40881b77,
-    0x40889e76,
-    0x40891ed4,
-    0x4089a454,
+    0x343209d6,
+    0x343289e6,
+    0x343309f1,
+    0x343389fe,
+    0x38320a07,
+    0x38328a1f,
+    0x38330a32,
+    0x38338a3c,
+    0x3c320aeb,
+    0x3c328af9,
+    0x3c330b10,
+    0x3c338b24,
+    0x3c340b56,
+    0x3c348b67,
+    0x3c350b73,
+    0x3c358ba0,
+    0x3c360bb2,
+    0x3c368bdb,
+    0x3c370be8,
+    0x3c378bf5,
+    0x3c380c03,
+    0x3c388c10,
+    0x3c390c1d,
+    0x3c398c41,
+    0x3c3a0c51,
+    0x3c3a8c69,
+    0x3c3b0c7e,
+    0x3c3b8c93,
+    0x3c3c0ca0,
+    0x3c3c8cb3,
+    0x3c3d0cc6,
+    0x3c3d8cea,
+    0x3c3e0d12,
+    0x3c3e8d2b,
+    0x3c3f0d41,
+    0x3c3f8d4e,
+    0x3c400d61,
+    0x3c408d72,
+    0x3c410d83,
+    0x3c418d9c,
+    0x3c420db5,
+    0x3c428dcb,
+    0x3c430de8,
+    0x3c438dfe,
+    0x3c440e82,
+    0x3c448ea9,
+    0x3c450ec7,
+    0x3c458ee1,
+    0x3c460ef9,
+    0x3c468f11,
+    0x3c470f3c,
+    0x3c478f67,
+    0x3c480f88,
+    0x3c488fb1,
+    0x3c490fcc,
+    0x3c498ff5,
+    0x3c4a1002,
+    0x3c4a9019,
+    0x3c4b1030,
+    0x3c4b9059,
+    0x3c4c1069,
+    0x3c4c9075,
+    0x3c4d108d,
+    0x3c4d90a0,
+    0x3c4e10b1,
+    0x3c4e90c2,
+    0x3c4f10e8,
+    0x3c4f8adf,
+    0x3c500e1a,
+    0x3c508e3a,
+    0x3c510e67,
+    0x3c518fe7,
+    0x3c5210d2,
+    0x3c528b87,
+    0x3c530b3f,
+    0x40321ba5,
+    0x40329bbf,
+    0x40331be7,
+    0x40339bff,
+    0x40341c1d,
+    0x40349c64,
+    0x40351c7b,
+    0x40359c97,
+    0x40361cb3,
+    0x40369ccd,
+    0x40371cec,
+    0x40379d0b,
+    0x40381d23,
+    0x40389d40,
+    0x40391d63,
+    0x40399d80,
+    0x403a1d9e,
+    0x403a9dae,
+    0x403b1dc3,
+    0x403b9ddf,
+    0x403c1df9,
+    0x403c9e04,
+    0x403d1e27,
+    0x403d9e4b,
+    0x403e1e61,
+    0x403e9e6b,
+    0x403f1e77,
+    0x403f9e88,
+    0x40401ea0,
+    0x40409ea8,
+    0x40411eb1,
+    0x40419eba,
+    0x40421ee2,
+    0x40429ef6,
+    0x40431f01,
+    0x40439f0d,
+    0x40441f61,
+    0x40449f6d,
+    0x40451f7a,
+    0x40459f8d,
+    0x40461fa5,
+    0x40469fbd,
+    0x40471fd3,
+    0x40479fee,
+    0x40482009,
+    0x4048a01d,
+    0x40492036,
+    0x4049a04f,
+    0x404a2069,
+    0x404aa073,
+    0x404b2083,
+    0x404ba0a4,
+    0x404c20bf,
+    0x404ca0cd,
+    0x404d20da,
+    0x404da0ee,
+    0x404e2106,
+    0x404ea114,
+    0x404f213e,
+    0x404fa155,
+    0x40502167,
+    0x4050a198,
+    0x405121c9,
+    0x4051a1de,
+    0x40522201,
+    0x4052a221,
+    0x40532236,
+    0x4053a246,
+    0x4054a252,
+    0x40552268,
+    0x4055a286,
+    0x40562293,
+    0x4056a29d,
+    0x405722ab,
+    0x4057a2c6,
+    0x405822e1,
+    0x4058a300,
+    0x40592315,
+    0x4059a32a,
+    0x405a2347,
+    0x405aa35b,
+    0x405b2377,
+    0x405ba38d,
+    0x405c23aa,
+    0x405ca3bc,
+    0x405d23d3,
+    0x405da3e4,
+    0x405e2400,
+    0x405ea414,
+    0x405f2424,
+    0x405fa440,
+    0x40602455,
+    0x4060a46b,
+    0x40612488,
+    0x4061a4a1,
+    0x406224cb,
+    0x4062a4d4,
+    0x406324e4,
+    0x4063a51d,
+    0x40642533,
+    0x4064a551,
+    0x40652566,
+    0x4065a583,
+    0x4066259a,
+    0x4066a5b8,
+    0x406725d5,
+    0x4067a5ec,
+    0x4068260a,
+    0x4068a621,
+    0x40692639,
+    0x4069a64a,
+    0x406a265d,
+    0x406aa670,
+    0x406b2684,
+    0x406ba6a8,
+    0x406c26c3,
+    0x406ca6e4,
+    0x406d2708,
+    0x406da723,
+    0x406e2744,
+    0x406ea759,
+    0x406f2772,
+    0x406fa77f,
+    0x4070278d,
+    0x4070a79a,
+    0x407127b7,
+    0x4071a7d7,
+    0x407227f2,
+    0x4072a80b,
+    0x40732822,
+    0x4073a83c,
+    0x40742860,
+    0x4074a876,
+    0x4075288a,
+    0x4075a89f,
+    0x407628b9,
+    0x4076a8cb,
+    0x407728e0,
+    0x4077a906,
+    0x40782923,
+    0x4078a946,
+    0x4079296c,
+    0x4079a989,
+    0x407a29ac,
+    0x407aa9c8,
+    0x407b29e4,
+    0x407ba9f6,
+    0x407c2a03,
+    0x407e2a10,
+    0x407eaa26,
+    0x407f2a3e,
+    0x407faa51,
+    0x40802a66,
+    0x4080aa7f,
+    0x40812a9d,
+    0x4081aabd,
+    0x40822ac6,
+    0x4082aae2,
+    0x40832aeb,
+    0x4083a123,
+    0x408421b2,
+    0x4084a182,
+    0x4085250c,
+    0x4085a4f0,
+    0x40861c3c,
+    0x40869c4f,
+    0x40871f41,
+    0x40879f50,
+    0x40881bcb,
+    0x40889eca,
+    0x40891f28,
+    0x4089a4b4,
+    0x408a1b70,
+    0x408a9b81,
+    0x408b1b93,
+    0x408ba1ef,
     0x4432042a,
     0x4432843c,
     0x44330445,
     0x4433844d,
     0x4434045a,
-    0x4434846a,
-    0x44350485,
-    0x443584a5,
-    0x443604c1,
-    0x443684e2,
-    0x443704e9,
-    0x443784f7,
-    0x44380501,
-    0x4438850d,
-    0x44390517,
-    0x44398522,
-    0x443a052c,
-    0x443a8536,
-    0x4c3217cb,
-    0x4c3297da,
-    0x4c3317e9,
-    0x4c339802,
-    0x4c34181d,
-    0x4c349839,
-    0x4c35184b,
-    0x4c359859,
-    0x4c36186e,
-    0x4c36987f,
-    0x4c37188d,
-    0x4c37989b,
-    0x4c3818ad,
-    0x4c3898bd,
-    0x4c3918c7,
-    0x4c3998df,
-    0x4c3a18f7,
-    0x4c3a990a,
-    0x50322f36,
-    0x5032af4b,
-    0x50332f5c,
-    0x5033af6f,
-    0x50342f80,
-    0x5034af93,
-    0x50352fa2,
-    0x5035afb7,
-    0x50362fc7,
-    0x5036afd6,
-    0x50372fe7,
-    0x5037aff7,
-    0x50383008,
-    0x5038b01b,
-    0x5039302d,
-    0x5039b043,
-    0x503a3055,
-    0x503ab066,
-    0x503b3077,
-    0x503bb088,
-    0x503c3093,
-    0x503cb09f,
-    0x503d30aa,
-    0x503db0b5,
-    0x503e30c2,
-    0x503eb0d7,
-    0x503f30e5,
-    0x503fb0f9,
-    0x5040310c,
-    0x5040b11d,
-    0x50413137,
-    0x5041b146,
-    0x5042314f,
-    0x5042b15e,
-    0x50433170,
-    0x5043b17c,
-    0x50443184,
-    0x5044b197,
-    0x504531a8,
-    0x5045b1be,
-    0x504631ca,
-    0x5046b1de,
-    0x504731ec,
-    0x5047b200,
-    0x5048321a,
-    0x5048b22e,
-    0x50493244,
-    0x5049b25b,
-    0x504a326d,
-    0x504ab281,
-    0x504b3296,
-    0x504bb2ad,
-    0x504c32c1,
-    0x504cb2ca,
-    0x504d32d2,
-    0x504db2e1,
-    0x504e32f1,
-    0x683210ea,
-    0x683290fb,
-    0x6833110b,
-    0x68339119,
-    0x68341126,
-    0x6c3210d9,
-    0x74320a6a,
-    0x74328a7c,
-    0x783206c9,
-    0x783286fc,
-    0x7833070e,
-    0x78338720,
-    0x78340734,
-    0x78348748,
-    0x78350766,
-    0x78358778,
-    0x7836078c,
-    0x783687fa,
-    0x7837080c,
-    0x7837881e,
-    0x78380830,
-    0x78388847,
-    0x7839085e,
-    0x78398875,
-    0x783a0891,
-    0x783a88ad,
-    0x783b08c9,
-    0x783b88df,
-    0x783c08f5,
-    0x783c890b,
-    0x783d0928,
-    0x783d8937,
-    0x783e0946,
-    0x783e8955,
-    0x783f0971,
-    0x783f897f,
-    0x7840098d,
-    0x7840899b,
-    0x784109a8,
-    0x784186db,
-    0x784207a0,
-    0x784287be,
-    0x784307dc,
-    0x803215f2,
+    0x44348475,
+    0x44350490,
+    0x443584b0,
+    0x443604cc,
+    0x443684ed,
+    0x443704f4,
+    0x44378502,
+    0x4438050c,
+    0x44388518,
+    0x44390522,
+    0x4439852d,
+    0x443a0537,
+    0x443a8541,
+    0x443b046a,
+    0x4c3217ea,
+    0x4c3297f9,
+    0x4c331808,
+    0x4c339821,
+    0x4c34183c,
+    0x4c349858,
+    0x4c35186a,
+    0x4c359878,
+    0x4c36188d,
+    0x4c36989e,
+    0x4c3718ac,
+    0x4c3798ba,
+    0x4c3818cc,
+    0x4c3898dc,
+    0x4c3918e6,
+    0x4c3998fe,
+    0x4c3a1916,
+    0x4c3a9929,
+    0x50322f96,
+    0x5032afab,
+    0x50332fbc,
+    0x5033afcf,
+    0x50342fe0,
+    0x5034aff3,
+    0x50353002,
+    0x5035b017,
+    0x50363027,
+    0x5036b036,
+    0x50373047,
+    0x5037b057,
+    0x50383068,
+    0x5038b07b,
+    0x5039308d,
+    0x5039b0a3,
+    0x503a30b5,
+    0x503ab0c6,
+    0x503b30d7,
+    0x503bb0e8,
+    0x503c30f3,
+    0x503cb0ff,
+    0x503d310a,
+    0x503db115,
+    0x503e3122,
+    0x503eb137,
+    0x503f3145,
+    0x503fb159,
+    0x5040316c,
+    0x5040b17d,
+    0x50413197,
+    0x5041b1a6,
+    0x504231af,
+    0x5042b1be,
+    0x504331d0,
+    0x5043b1dc,
+    0x504431e4,
+    0x5044b1f7,
+    0x50453208,
+    0x5045b21e,
+    0x5046322a,
+    0x5046b23e,
+    0x5047324c,
+    0x5047b260,
+    0x5048327a,
+    0x5048b28e,
+    0x504932a4,
+    0x5049b2bb,
+    0x504a32cd,
+    0x504ab2e1,
+    0x504b32f6,
+    0x504bb30d,
+    0x504c3321,
+    0x504cb32a,
+    0x504d3332,
+    0x504db341,
+    0x504e3351,
+    0x68321109,
+    0x6832911a,
+    0x6833112a,
+    0x68339138,
+    0x68341145,
+    0x6c3210f8,
+    0x74320a89,
+    0x74328a9b,
+    0x783206e8,
+    0x7832871b,
+    0x7833072d,
+    0x7833873f,
+    0x78340753,
+    0x78348767,
+    0x78350785,
+    0x78358797,
+    0x783607ab,
+    0x78368819,
+    0x7837082b,
+    0x7837883d,
+    0x7838084f,
+    0x78388866,
+    0x7839087d,
+    0x78398894,
+    0x783a08b0,
+    0x783a88cc,
+    0x783b08e8,
+    0x783b88fe,
+    0x783c0914,
+    0x783c892a,
+    0x783d0947,
+    0x783d8956,
+    0x783e0965,
+    0x783e8974,
+    0x783f0990,
+    0x783f899e,
+    0x784009ac,
+    0x784089ba,
+    0x784109c7,
+    0x784186fa,
+    0x784207bf,
+    0x784287dd,
+    0x784307fb,
+    0x80321611,
 };
 
 const size_t kOpenSSLFunctionValuesLen = sizeof(kOpenSSLFunctionValues) / sizeof(kOpenSSLFunctionValues[0]);
@@ -797,6 +804,7 @@
     "BIO_new\0"
     "BIO_new_file\0"
     "BIO_new_mem_buf\0"
+    "BIO_printf\0"
     "BIO_zero_copy_get_read_buf\0"
     "BIO_zero_copy_get_read_buf_done\0"
     "BIO_zero_copy_get_write_buf\0"
@@ -820,6 +828,7 @@
     "BN_exp\0"
     "BN_generate_dsa_nonce\0"
     "BN_generate_prime_ex\0"
+    "BN_lshift\0"
     "BN_mod_exp2_mont\0"
     "BN_mod_exp_mont\0"
     "BN_mod_exp_mont_consttime\0"
@@ -831,6 +840,7 @@
     "BN_new\0"
     "BN_rand\0"
     "BN_rand_range\0"
+    "BN_rshift\0"
     "BN_sqrt\0"
     "BN_usub\0"
     "bn_wexpand\0"
@@ -1109,6 +1119,9 @@
     "rsa_setup_blinding\0"
     "sign_raw\0"
     "verify_raw\0"
+    "SSL_AEAD_CTX_new\0"
+    "SSL_AEAD_CTX_open\0"
+    "SSL_AEAD_CTX_seal\0"
     "SSL_CTX_check_private_key\0"
     "SSL_CTX_new\0"
     "SSL_CTX_set1_tls_channel_id\0"
@@ -1183,8 +1196,9 @@
     "dtls1_process_fragment\0"
     "dtls1_process_record\0"
     "dtls1_read_bytes\0"
+    "dtls1_seal_record\0"
     "dtls1_send_hello_verify_request\0"
-    "dtls1_write_app_data_bytes\0"
+    "dtls1_write_app_data\0"
     "i2d_SSL_SESSION\0"
     "ssl3_accept\0"
     "ssl3_cert_verify_hash\0"
@@ -1528,43 +1542,43 @@
     0x28328b8e,
     0x28330b5f,
     0x28338ba1,
-    0x2c322a47,
-    0x2c32aa55,
-    0x2c332a67,
-    0x2c33aa79,
-    0x2c342a8d,
-    0x2c34aa9f,
-    0x2c352aba,
-    0x2c35aacc,
-    0x2c362adf,
+    0x2c322ab3,
+    0x2c32aac1,
+    0x2c332ad3,
+    0x2c33aae5,
+    0x2c342af9,
+    0x2c34ab0b,
+    0x2c352b26,
+    0x2c35ab38,
+    0x2c362b4b,
     0x2c3682f3,
-    0x2c372aec,
-    0x2c37aafe,
-    0x2c382b11,
-    0x2c38ab1f,
-    0x2c392b2f,
-    0x2c39ab41,
-    0x2c3a2b55,
-    0x2c3aab66,
+    0x2c372b58,
+    0x2c37ab6a,
+    0x2c382b7d,
+    0x2c38ab8b,
+    0x2c392b9b,
+    0x2c39abad,
+    0x2c3a2bc1,
+    0x2c3aabd2,
     0x2c3b134c,
-    0x2c3bab77,
-    0x2c3c2b8b,
-    0x2c3caba1,
-    0x2c3d2bba,
-    0x2c3dabe8,
-    0x2c3e2bf6,
-    0x2c3eac0e,
-    0x2c3f2c26,
-    0x2c3fac33,
-    0x2c402c56,
-    0x2c40ac75,
+    0x2c3babe3,
+    0x2c3c2bf7,
+    0x2c3cac0d,
+    0x2c3d2c26,
+    0x2c3dac54,
+    0x2c3e2c62,
+    0x2c3eac7a,
+    0x2c3f2c92,
+    0x2c3fac9f,
+    0x2c402cc2,
+    0x2c40ace1,
     0x2c4111b6,
-    0x2c41ac86,
-    0x2c422c99,
+    0x2c41acf2,
+    0x2c422d05,
     0x2c429128,
-    0x2c432caa,
+    0x2c432d16,
     0x2c4386a2,
-    0x2c442bd7,
+    0x2c442c43,
     0x30320000,
     0x30328015,
     0x3033001f,
@@ -1736,161 +1750,165 @@
     0x40491b0e,
     0x40499b23,
     0x404a1b3c,
-    0x404a9b5f,
-    0x404b1b79,
-    0x404b9b97,
-    0x404c1bb2,
-    0x404c9bcc,
-    0x404d1be3,
-    0x404d9c0b,
-    0x404e1c22,
-    0x404e9c3e,
-    0x404f1c5a,
-    0x404f9c7b,
-    0x40501c9d,
-    0x40509cb9,
-    0x40511ccd,
-    0x40519cda,
-    0x40521cf1,
-    0x40529d01,
-    0x40531d11,
-    0x40539d25,
-    0x40541d40,
-    0x40549d50,
-    0x40551d67,
-    0x40559d76,
-    0x40561d91,
-    0x40569da9,
-    0x40571dc5,
-    0x40579dde,
-    0x40581df1,
-    0x40589e06,
-    0x40591e29,
-    0x40599e37,
-    0x405a1e44,
-    0x405a9e5d,
-    0x405b1e75,
-    0x405b9e88,
-    0x405c1e9d,
-    0x405c9eaf,
-    0x405d1ec4,
-    0x405d9ed4,
-    0x405e1eed,
-    0x405e9f01,
-    0x405f1f11,
-    0x405f9f29,
-    0x40601f3a,
-    0x40609f4d,
-    0x40611f5e,
-    0x40619f7c,
-    0x40621f8d,
-    0x40629f9a,
-    0x40631fb1,
-    0x40639ff2,
-    0x40642009,
-    0x4064a016,
-    0x40652024,
-    0x4065a046,
-    0x4066206e,
-    0x4066a083,
-    0x4067209a,
-    0x4067a0ab,
-    0x406820bc,
-    0x4068a0cd,
-    0x406920e2,
-    0x4069a0f9,
-    0x406a210a,
-    0x406aa123,
-    0x406b213e,
-    0x406ba155,
-    0x406c216d,
-    0x406ca18e,
-    0x406d21a1,
-    0x406da1c2,
-    0x406e21dd,
-    0x406ea1f8,
-    0x406f2219,
-    0x406fa23f,
-    0x4070225f,
-    0x4070a27b,
-    0x40712408,
-    0x4071a42b,
-    0x40722441,
-    0x4072a460,
-    0x40732478,
-    0x4073a498,
-    0x407426c2,
-    0x4074a6e7,
-    0x40752702,
-    0x4075a721,
-    0x40762750,
-    0x4076a778,
-    0x40772791,
-    0x4077a7b0,
-    0x407827d5,
-    0x4078a7ec,
-    0x407927ff,
-    0x4079a81c,
+    0x404a9b76,
+    0x404b1b90,
+    0x404b9bae,
+    0x404c1bc9,
+    0x404c9be3,
+    0x404d1bfa,
+    0x404d9c22,
+    0x404e1c39,
+    0x404e9c55,
+    0x404f1c71,
+    0x404f9c92,
+    0x40501cb4,
+    0x40509cd0,
+    0x40511ce4,
+    0x40519cf1,
+    0x40521d08,
+    0x40529d18,
+    0x40531d28,
+    0x40539d3c,
+    0x40541d57,
+    0x40549d67,
+    0x40551d7e,
+    0x40559d8d,
+    0x40561da8,
+    0x40569dc0,
+    0x40571ddc,
+    0x40579df5,
+    0x40581e08,
+    0x40589e1d,
+    0x40591e40,
+    0x40599e4e,
+    0x405a1e5b,
+    0x405a9e74,
+    0x405b1e8c,
+    0x405b9e9f,
+    0x405c1eb4,
+    0x405c9ec6,
+    0x405d1edb,
+    0x405d9eeb,
+    0x405e1f04,
+    0x405e9f18,
+    0x405f1f28,
+    0x405f9f40,
+    0x40601f51,
+    0x40609f64,
+    0x40611f75,
+    0x40619f93,
+    0x40621fa4,
+    0x40629fb1,
+    0x40631fc8,
+    0x4063a009,
+    0x40642020,
+    0x4064a02d,
+    0x4065203b,
+    0x4065a05d,
+    0x40662085,
+    0x4066a09a,
+    0x406720b1,
+    0x4067a0c2,
+    0x406820d3,
+    0x4068a0e4,
+    0x406920f9,
+    0x4069a110,
+    0x406a2121,
+    0x406aa13a,
+    0x406b2155,
+    0x406ba16c,
+    0x406c21d9,
+    0x406ca1fa,
+    0x406d220d,
+    0x406da22e,
+    0x406e2249,
+    0x406ea264,
+    0x406f2285,
+    0x406fa2ab,
+    0x407022cb,
+    0x4070a2e7,
+    0x40712474,
+    0x4071a497,
+    0x407224ad,
+    0x4072a4cc,
+    0x407324e4,
+    0x4073a504,
+    0x4074272e,
+    0x4074a753,
+    0x4075276e,
+    0x4075a78d,
+    0x407627bc,
+    0x4076a7e4,
+    0x407727fd,
+    0x4077a81c,
+    0x40782841,
+    0x4078a858,
+    0x4079286b,
+    0x4079a888,
     0x407a0782,
-    0x407aa82e,
-    0x407b2841,
-    0x407ba85a,
-    0x407c2872,
+    0x407aa89a,
+    0x407b28ad,
+    0x407ba8c6,
+    0x407c28de,
     0x407c90b0,
-    0x407d2886,
-    0x407da8a0,
-    0x407e28b1,
-    0x407ea8c5,
-    0x407f28d3,
-    0x407fa8ee,
+    0x407d28f2,
+    0x407da90c,
+    0x407e291d,
+    0x407ea931,
+    0x407f293f,
+    0x407fa95a,
     0x40801279,
-    0x4080a913,
-    0x40812935,
-    0x4081a950,
-    0x40822965,
-    0x4082a97d,
-    0x40832995,
-    0x4083a9ac,
-    0x408429c2,
-    0x4084a9ce,
-    0x408529e1,
-    0x4085a9f6,
-    0x40862a08,
-    0x4086aa1d,
-    0x40872a26,
-    0x40879bf9,
+    0x4080a97f,
+    0x408129a1,
+    0x4081a9bc,
+    0x408229d1,
+    0x4082a9e9,
+    0x40832a01,
+    0x4083aa18,
+    0x40842a2e,
+    0x4084aa3a,
+    0x40852a4d,
+    0x4085aa62,
+    0x40862a74,
+    0x4086aa89,
+    0x40872a92,
+    0x40879c10,
     0x40880083,
-    0x40889fd1,
-    0x41f42333,
-    0x41f923c5,
-    0x41fe22b8,
-    0x41fea4e9,
-    0x41ff25da,
-    0x4203234c,
-    0x4208236e,
-    0x4208a3aa,
-    0x4209229c,
-    0x4209a3e4,
-    0x420a22f3,
-    0x420aa2d3,
-    0x420b2313,
-    0x420ba38c,
-    0x420c25f6,
-    0x420ca4b6,
-    0x420d24d0,
-    0x420da507,
-    0x42122521,
-    0x421725bd,
-    0x4217a563,
-    0x421c2585,
-    0x421f2540,
-    0x4221260d,
-    0x422625a0,
-    0x422b26a6,
-    0x422ba66f,
-    0x422c268e,
-    0x422ca649,
-    0x422d2628,
+    0x40889fe8,
+    0x40890a0a,
+    0x4089a184,
+    0x408a1b5f,
+    0x408aa1ae,
+    0x41f4239f,
+    0x41f92431,
+    0x41fe2324,
+    0x41fea555,
+    0x41ff2646,
+    0x420323b8,
+    0x420823da,
+    0x4208a416,
+    0x42092308,
+    0x4209a450,
+    0x420a235f,
+    0x420aa33f,
+    0x420b237f,
+    0x420ba3f8,
+    0x420c2662,
+    0x420ca522,
+    0x420d253c,
+    0x420da573,
+    0x4212258d,
+    0x42172629,
+    0x4217a5cf,
+    0x421c25f1,
+    0x421f25ac,
+    0x42212679,
+    0x4226260c,
+    0x422b2712,
+    0x422ba6db,
+    0x422c26fa,
+    0x422ca6b5,
+    0x422d2694,
     0x443206ad,
     0x443286bc,
     0x443306c8,
@@ -1933,69 +1951,69 @@
     0x4c3d10b0,
     0x4c3d943c,
     0x4c3e1449,
-    0x50322cbc,
-    0x5032accb,
-    0x50332cd6,
-    0x5033ace6,
-    0x50342cff,
-    0x5034ad19,
-    0x50352d27,
-    0x5035ad3d,
-    0x50362d4f,
-    0x5036ad65,
-    0x50372d7e,
-    0x5037ad91,
-    0x50382da9,
-    0x5038adba,
-    0x50392dcf,
-    0x5039ade3,
-    0x503a2e03,
-    0x503aae19,
-    0x503b2e31,
-    0x503bae43,
-    0x503c2e5f,
-    0x503cae76,
-    0x503d2e8f,
-    0x503daea5,
-    0x503e2eb2,
-    0x503eaec8,
-    0x503f2eda,
+    0x50322d28,
+    0x5032ad37,
+    0x50332d42,
+    0x5033ad52,
+    0x50342d6b,
+    0x5034ad85,
+    0x50352d93,
+    0x5035ada9,
+    0x50362dbb,
+    0x5036add1,
+    0x50372dea,
+    0x5037adfd,
+    0x50382e15,
+    0x5038ae26,
+    0x50392e3b,
+    0x5039ae4f,
+    0x503a2e6f,
+    0x503aae85,
+    0x503b2e9d,
+    0x503baeaf,
+    0x503c2ecb,
+    0x503caee2,
+    0x503d2efb,
+    0x503daf11,
+    0x503e2f1e,
+    0x503eaf34,
+    0x503f2f46,
     0x503f8348,
-    0x50402eed,
-    0x5040aefd,
-    0x50412f17,
-    0x5041af26,
-    0x50422f40,
-    0x5042af5d,
-    0x50432f6d,
-    0x5043af7d,
-    0x50442f8c,
+    0x50402f59,
+    0x5040af69,
+    0x50412f83,
+    0x5041af92,
+    0x50422fac,
+    0x5042afc9,
+    0x50432fd9,
+    0x5043afe9,
+    0x50442ff8,
     0x50448414,
-    0x50452fa0,
-    0x5045afbe,
-    0x50462fd1,
-    0x5046afe7,
-    0x50472ff9,
-    0x5047b00e,
-    0x50483034,
-    0x5048b042,
-    0x50493055,
-    0x5049b06a,
-    0x504a3080,
-    0x504ab090,
-    0x504b30b0,
-    0x504bb0c3,
-    0x504c30e6,
-    0x504cb114,
-    0x504d3126,
-    0x504db143,
-    0x504e315e,
-    0x504eb17a,
-    0x504f318c,
-    0x504fb1a3,
-    0x505031b2,
+    0x5045300c,
+    0x5045b02a,
+    0x5046303d,
+    0x5046b053,
+    0x50473065,
+    0x5047b07a,
+    0x504830a0,
+    0x5048b0ae,
+    0x504930c1,
+    0x5049b0d6,
+    0x504a30ec,
+    0x504ab0fc,
+    0x504b311c,
+    0x504bb12f,
+    0x504c3152,
+    0x504cb180,
+    0x504d3192,
+    0x504db1af,
+    0x504e31ca,
+    0x504eb1e6,
+    0x504f31f8,
+    0x504fb20f,
+    0x5050321e,
     0x50508687,
-    0x505131c5,
+    0x50513231,
     0x58320e12,
     0x68320dd4,
     0x68328b8e,
@@ -2388,6 +2406,7 @@
     "DTLS_MESSAGE_TOO_BIG\0"
     "ECC_CERT_NOT_FOR_SIGNING\0"
     "EMPTY_SRTP_PROTECTION_PROFILE_LIST\0"
+    "EMS_STATE_INCONSISTENT\0"
     "ENCRYPTED_LENGTH_TOO_LONG\0"
     "ERROR_IN_RECEIVED_CIPHER_LIST\0"
     "EVP_DIGESTSIGNFINAL_FAILED\0"
@@ -2457,6 +2476,8 @@
     "RENEGOTIATION_ENCODING_ERR\0"
     "RENEGOTIATION_MISMATCH\0"
     "REQUIRED_CIPHER_MISSING\0"
+    "RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION\0"
+    "RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION\0"
     "SCSV_RECEIVED_WHEN_RENEGOTIATING\0"
     "SERVERHELLO_TLSEXT\0"
     "SESSION_ID_CONTEXT_UNINITIALIZED\0"
diff --git a/linux-arm/crypto/aes/bsaes-armv7.S b/linux-arm/crypto/aes/bsaes-armv7.S
index 0feeab0..204ee3e 100644
--- a/linux-arm/crypto/aes/bsaes-armv7.S
+++ b/linux-arm/crypto/aes/bsaes-armv7.S
@@ -1366,7 +1366,7 @@
 
 	vld1.8	{q0}, [r8]		@ load counter
 #ifdef	__APPLE__
-	mov	r8, #.LREVM0SR-.LM0
+	mov	r8, #:lower16:(.LREVM0SR-.LM0)
 	add	r8, r6, r8
 #else
 	add	r8, r6, #.LREVM0SR-.LM0	@ borrow r8
@@ -1428,7 +1428,7 @@
 	mov	r5, r10			@ pass rounds
 	vstmia	r9, {q10}			@ save next counter
 #ifdef	__APPLE__
-	mov	r6, #.LREVM0SR-.LSR
+	mov	r6, #:lower16:(.LREVM0SR-.LSR)
 	sub	r6, r8, r6
 #else
 	sub	r6, r8, #.LREVM0SR-.LSR	@ pass constants
diff --git a/linux-arm/crypto/sha/sha256-armv4.S b/linux-arm/crypto/sha/sha256-armv4.S
index ba37795..114aa43 100644
--- a/linux-arm/crypto/sha/sha256-armv4.S
+++ b/linux-arm/crypto/sha/sha256-armv4.S
@@ -1881,7 +1881,7 @@
 	stmdb	sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr}
 
 	sub	r11,sp,#16*4+16
-	adr	r14,K256
+	adrl	r14,K256
 	bic	r11,r11,#15		@ align for 128-bit stores
 	mov	r12,sp
 	mov	sp,r11			@ alloca
diff --git a/sources.mk b/sources.mk
index de6a956..cdb7abc 100644
--- a/sources.mk
+++ b/sources.mk
@@ -183,6 +183,8 @@
   src/crypto/rand/urandom.c\
   src/crypto/rand/windows.c\
   src/crypto/rc4/rc4.c\
+  src/crypto/refcount_c11.c\
+  src/crypto/refcount_lock.c\
   src/crypto/rsa/blinding.c\
   src/crypto/rsa/padding.c\
   src/crypto/rsa/rsa.c\
@@ -294,6 +296,7 @@
   src/ssl/s3_meth.c\
   src/ssl/s3_pkt.c\
   src/ssl/s3_srvr.c\
+  src/ssl/ssl_aead_ctx.c\
   src/ssl/ssl_algs.c\
   src/ssl/ssl_asn1.c\
   src/ssl/ssl_cert.c\
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6e41ee9..c1a6a37 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -76,6 +76,11 @@
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wshadow")
 endif()
 
+if((CMAKE_COMPILER_IS_GNUCXX AND CMAKE_C_COMPILER_VERSION VERSION_GREATER "4.8.99") OR
+   CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -D_XOPEN_SOURCE=700")
+endif()
+
 add_definitions(-DBORINGSSL_IMPLEMENTATION)
 
 if (BUILD_SHARED_LIBS)
@@ -104,6 +109,8 @@
   set(ARCH "x86")
 elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "arm")
   set(ARCH "arm")
+elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "armv6")
+  set(ARCH "arm")
 elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "armv7-a")
   set(ARCH "arm")
 elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64")
@@ -116,7 +123,7 @@
   # The Android-NDK CMake files somehow fail to set the -march flag for
   # assembly files. Without this flag, the compiler believes that it's
   # building for ARMv5.
-  set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -march=armv7-a")
+  set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -march=${CMAKE_SYSTEM_PROCESSOR}")
 endif()
 
 if (${ARCH} STREQUAL "x86" AND APPLE)
diff --git a/src/LICENSE b/src/LICENSE
new file mode 100644
index 0000000..8ae5e77
--- /dev/null
+++ b/src/LICENSE
@@ -0,0 +1,146 @@
+BoringSSL is a fork of OpenSSL. As such, large parts of it fall under OpenSSL
+licensing. Files that are completely new have a Google copyright and an ISC
+license. This license is reproduced at the bottom of this file.
+
+Contributors to BoringSSL are required to follow the CLA rules for Chromium:
+https://cla.developers.google.com/clas
+
+The OpenSSL toolkit stays under a dual license, i.e. both the conditions of the
+OpenSSL License and the original SSLeay license apply to the toolkit. See below
+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.
+
+  OpenSSL License
+  ---------------
+
+/* ====================================================================
+ * Copyright (c) 1998-2011 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+ Original SSLeay License
+ -----------------------
+
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+
+ISC license used for completely new code in BoringSSL:
+
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt
index 6433dc6..6858cbb 100644
--- a/src/crypto/CMakeLists.txt
+++ b/src/crypto/CMakeLists.txt
@@ -145,15 +145,17 @@
   crypto
 
   crypto.c
+  directory_posix.c
+  directory_win.c
+  ex_data.c
   mem.c
+  refcount_c11.c
+  refcount_lock.c
   thread.c
   thread_none.c
   thread_pthread.c
   thread_win.c
-  ex_data.c
   time_support.c
-  directory_posix.c
-  directory_win.c
 
   ${CRYPTO_ARCH_SOURCES}
 
@@ -205,6 +207,8 @@
   constant_time_test
 
   constant_time_test.c
+
+  $<TARGET_OBJECTS:test_support>
 )
 
 target_link_libraries(constant_time_test crypto)
@@ -213,9 +217,19 @@
   thread_test
 
   thread_test.c
+
+  $<TARGET_OBJECTS:test_support>
 )
 
 target_link_libraries(thread_test crypto)
 
+add_executable(
+  refcount_test
+
+  refcount_test.c
+)
+
+target_link_libraries(refcount_test crypto)
+
 perlasm(cpu-x86_64-asm.${ASM_EXT} cpu-x86_64-asm.pl)
 perlasm(cpu-x86-asm.${ASM_EXT} cpu-x86-asm.pl)
diff --git a/src/crypto/aes/asm/bsaes-armv7.pl b/src/crypto/aes/asm/bsaes-armv7.pl
index a5e4a98..273f0b9 100644
--- a/src/crypto/aes/asm/bsaes-armv7.pl
+++ b/src/crypto/aes/asm/bsaes-armv7.pl
@@ -1424,7 +1424,7 @@
 
 	vld1.8	{@XMM[0]}, [$ctr]		@ load counter
 #ifdef	__APPLE__
-	mov	$ctr, #.LREVM0SR-.LM0
+	mov	$ctr, #:lower16:(.LREVM0SR-.LM0)
 	add	$ctr, $const, $ctr
 #else
 	add	$ctr, $const, #.LREVM0SR-.LM0	@ borrow $ctr
@@ -1486,7 +1486,7 @@
 	mov		r5, $rounds			@ pass rounds
 	vstmia		$fp, {@XMM[10]}			@ save next counter
 #ifdef	__APPLE__
-	mov		$const, #.LREVM0SR-.LSR
+	mov		$const, #:lower16:(.LREVM0SR-.LSR)
 	sub		$const, $ctr, $const
 #else
 	sub		$const, $ctr, #.LREVM0SR-.LSR	@ pass constants
diff --git a/src/crypto/asn1/tasn_fre.c b/src/crypto/asn1/tasn_fre.c
index c344ed7..d1317ae 100644
--- a/src/crypto/asn1/tasn_fre.c
+++ b/src/crypto/asn1/tasn_fre.c
@@ -143,7 +143,7 @@
 
 		case ASN1_ITYPE_NDEF_SEQUENCE:
 		case ASN1_ITYPE_SEQUENCE:
-		if (asn1_do_lock(pval, -1, it) > 0)
+		if (!asn1_refcount_dec_and_test_zero(pval, it))
 			return;
 		if (asn1_cb)
 			{
diff --git a/src/crypto/asn1/tasn_new.c b/src/crypto/asn1/tasn_new.c
index 918aba7..6d69dcb 100644
--- a/src/crypto/asn1/tasn_new.c
+++ b/src/crypto/asn1/tasn_new.c
@@ -190,7 +190,7 @@
 			if (!*pval)
 				goto memerr;
 			memset(*pval, 0, it->size);
-			asn1_do_lock(pval, 0, it);
+			asn1_refcount_set_one(pval, it);
 			asn1_enc_init(pval, it);
 			}
 		for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
diff --git a/src/crypto/asn1/tasn_utl.c b/src/crypto/asn1/tasn_utl.c
index 1b9de94..ff3764e 100644
--- a/src/crypto/asn1/tasn_utl.c
+++ b/src/crypto/asn1/tasn_utl.c
@@ -64,6 +64,8 @@
 #include <openssl/err.h>
 #include <openssl/thread.h>
 
+#include "../internal.h"
+
 
 /* Utility functions for manipulating fields and offsets */
 
@@ -86,28 +88,32 @@
   return ret;
 }
 
-/* Do reference counting. The value 'op' decides what to do. if it is +1 then
- * the count is incremented. If op is 0 count is set to 1. If op is -1 count is
- * decremented and the return value is the current refrence count or 0 if no
- * reference count exists. */
-int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it) {
-  const ASN1_AUX *aux;
-  int *lck, ret;
+static CRYPTO_refcount_t *asn1_get_references(ASN1_VALUE **pval,
+                                              const ASN1_ITEM *it) {
   if (it->itype != ASN1_ITYPE_SEQUENCE &&
       it->itype != ASN1_ITYPE_NDEF_SEQUENCE) {
-    return 0;
+    return NULL;
   }
-  aux = it->funcs;
+  const ASN1_AUX *aux = it->funcs;
   if (!aux || !(aux->flags & ASN1_AFLG_REFCOUNT)) {
-    return 0;
+    return NULL;
   }
-  lck = offset2ptr(*pval, aux->ref_offset);
-  if (op == 0) {
-    *lck = 1;
-    return 1;
+  return offset2ptr(*pval, aux->ref_offset);
+}
+
+void asn1_refcount_set_one(ASN1_VALUE **pval, const ASN1_ITEM *it) {
+  CRYPTO_refcount_t *references = asn1_get_references(pval, it);
+  if (references != NULL) {
+    *references = 1;
   }
-  ret = CRYPTO_add(lck, op, aux->ref_lock);
-  return ret;
+}
+
+int asn1_refcount_dec_and_test_zero(ASN1_VALUE **pval, const ASN1_ITEM *it) {
+  CRYPTO_refcount_t *references = asn1_get_references(pval, it);
+  if (references != NULL) {
+    return CRYPTO_refcount_dec_and_test_zero(references);
+  }
+  return 1;
 }
 
 static ASN1_ENCODING *asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it) {
diff --git a/src/crypto/base64/CMakeLists.txt b/src/crypto/base64/CMakeLists.txt
index 8bc531a..42037a5 100644
--- a/src/crypto/base64/CMakeLists.txt
+++ b/src/crypto/base64/CMakeLists.txt
@@ -12,6 +12,8 @@
   base64_test
 
   base64_test.cc
+
+  $<TARGET_OBJECTS:test_support>
 )
 
 target_link_libraries(base64_test crypto)
diff --git a/src/crypto/bio/CMakeLists.txt b/src/crypto/bio/CMakeLists.txt
index f4122c4..dbf5951 100644
--- a/src/crypto/bio/CMakeLists.txt
+++ b/src/crypto/bio/CMakeLists.txt
@@ -22,6 +22,8 @@
   bio_test
 
   bio_test.cc
+
+  $<TARGET_OBJECTS:test_support>
 )
 
 target_link_libraries(bio_test crypto)
diff --git a/src/crypto/bio/bio.c b/src/crypto/bio/bio.c
index 694a11c..5ac5911 100644
--- a/src/crypto/bio/bio.c
+++ b/src/crypto/bio/bio.c
@@ -65,6 +65,8 @@
 #include <openssl/mem.h>
 #include <openssl/thread.h>
 
+#include "../internal.h"
+
 
 /* BIO_set initialises a BIO structure to have the given type and sets the
  * reference count to one. It returns one on success or zero on error. */
@@ -104,8 +106,7 @@
   BIO *next_bio;
 
   for (; bio != NULL; bio = next_bio) {
-    int refs = CRYPTO_add(&bio->references, -1, CRYPTO_LOCK_BIO);
-    if (refs > 0) {
+    if (!CRYPTO_refcount_dec_and_test_zero(&bio->references)) {
       return 0;
     }
 
@@ -128,7 +129,7 @@
 }
 
 BIO *BIO_up_ref(BIO *bio) {
-  CRYPTO_add(&bio->references, 1, CRYPTO_LOCK_BIO);
+  CRYPTO_refcount_inc(&bio->references);
   return bio;
 }
 
@@ -507,7 +508,7 @@
     done += n;
     if (len < max_len && len - done < kChunkSize / 2) {
       len += kChunkSize;
-      if (len > max_len) {
+      if (len < kChunkSize || len > max_len) {
         len = max_len;
       }
       uint8_t *new_buf = OPENSSL_realloc(*out, len);
diff --git a/src/crypto/bio/bio_test.cc b/src/crypto/bio/bio_test.cc
index e0193f8..4d7dfe2 100644
--- a/src/crypto/bio/bio_test.cc
+++ b/src/crypto/bio/bio_test.cc
@@ -371,6 +371,9 @@
                                          kLargePayloadLen & 0xff};
   ScopedOpenSSLBytes large(reinterpret_cast<uint8_t *>(
       OPENSSL_malloc(sizeof(kLargePrefix) + kLargePayloadLen)));
+  if (!large) {
+    return false;
+  }
   memset(large.get() + sizeof(kLargePrefix), 0, kLargePayloadLen);
   memcpy(large.get(), kLargePrefix, sizeof(kLargePrefix));
 
diff --git a/src/crypto/bio/printf.c b/src/crypto/bio/printf.c
index 3638915..f51b396 100644
--- a/src/crypto/bio/printf.c
+++ b/src/crypto/bio/printf.c
@@ -64,6 +64,7 @@
 #include <stdarg.h>
 #include <stdio.h>
 
+#include <openssl/err.h>
 #include <openssl/mem.h>
 
 int BIO_printf(BIO *bio, const char *format, ...) {
@@ -94,9 +95,8 @@
     out = OPENSSL_malloc(requested_len + 1);
     out_malloced = 1;
     if (out == NULL) {
-      /* Unclear what can be done in this situation. OpenSSL has historically
-       * crashed and that seems better than producing the wrong output. */
-      abort();
+      OPENSSL_PUT_ERROR(BIO, BIO_printf, ERR_R_MALLOC_FAILURE);
+      return -1;
     }
     va_start(args, format);
     out_len = vsnprintf(out, requested_len + 1, format, args);
diff --git a/src/crypto/bio/socket_helper.c b/src/crypto/bio/socket_helper.c
index 197c737..b1cdd1a 100644
--- a/src/crypto/bio/socket_helper.c
+++ b/src/crypto/bio/socket_helper.c
@@ -51,7 +51,7 @@
   ret = getaddrinfo(hostname, port_str, &hint, &result);
   if (ret != 0) {
     OPENSSL_PUT_ERROR(SYS, getaddrinfo, 0);
-    ERR_add_error_data(2, gai_strerror(ret));
+    ERR_add_error_data(1, gai_strerror(ret));
     return 0;
   }
 
diff --git a/src/crypto/bn/CMakeLists.txt b/src/crypto/bn/CMakeLists.txt
index 25663af..2e0cb45 100644
--- a/src/crypto/bn/CMakeLists.txt
+++ b/src/crypto/bn/CMakeLists.txt
@@ -4,7 +4,6 @@
   set(
     BN_ARCH_SOURCES
 
-    asm/x86_64-gcc.c
     x86_64-mont.${ASM_EXT}
     x86_64-mont5.${ASM_EXT}
     rsaz-x86_64.${ASM_EXT}
@@ -38,6 +37,7 @@
   OBJECT
 
   add.c
+  asm/x86_64-gcc.c
   bn.c
   cmp.c
   convert.c
@@ -70,6 +70,8 @@
   bn_test
 
   bn_test.cc
+
+  $<TARGET_OBJECTS:test_support>
 )
 
 target_link_libraries(bn_test crypto)
diff --git a/src/crypto/bn/bn_test.cc b/src/crypto/bn/bn_test.cc
index 9aa2bf5..6a7d48c 100644
--- a/src/crypto/bn/bn_test.cc
+++ b/src/crypto/bn/bn_test.cc
@@ -72,6 +72,7 @@
 #define __STDC_FORMAT_MACROS
 #endif
 
+#include <errno.h>
 #include <stdio.h>
 #include <string.h>
 
@@ -83,6 +84,12 @@
 #include "../crypto/test/scoped_types.h"
 
 
+// This program tests the BIGNUM implementation. It takes an optional -bc
+// argument to write a transcript compatible with the UNIX bc utility.
+//
+// TODO(davidben): Rather than generate random inputs and depend on bc to check
+// the results, most of these tests should use known answers.
+
 static const int num0 = 100; // number of tests
 static const int num1 = 50;  // additional tests for some functions
 static const int num2 = 5;   // number of tests for slow functions
@@ -114,10 +121,7 @@
 static bool test_dec2bn(FILE *fp, BN_CTX *ctx);
 static bool test_hex2bn(FILE *fp, BN_CTX *ctx);
 static bool test_asc2bn(FILE *fp, BN_CTX *ctx);
-
-// g_results can be set to true to cause the result of each computation to be
-// printed.
-static bool g_results = false;
+static bool test_rand();
 
 static const uint8_t kSample[] =
     "\xC6\x4F\x43\x04\x2A\xEA\xCA\x6E\x58\x36\x80\x5B\xE8\xC9"
@@ -126,7 +130,15 @@
 // A wrapper around puts that takes its arguments in the same order as our *_fp
 // functions.
 static void puts_fp(FILE *out, const char *m) {
-  fputs(m, out);
+  if (out != nullptr) {
+    fputs(m, out);
+  }
+}
+
+static void flush_fp(FILE *out) {
+  if (out != nullptr) {
+    fflush(out);
+  }
 }
 
 static void message(FILE *out, const char *m) {
@@ -138,11 +150,24 @@
 int main(int argc, char *argv[]) {
   CRYPTO_library_init();
 
+  ScopedFILE bc_file;
   argc--;
   argv++;
   while (argc >= 1) {
-    if (strcmp(*argv, "-results") == 0) {
-      g_results = true;
+    if (strcmp(*argv, "-bc") == 0) {
+      if (argc < 2) {
+        fprintf(stderr, "Missing parameter to -bc\n");
+        return 1;
+      }
+      bc_file.reset(fopen(argv[1], "w+"));
+      if (!bc_file) {
+        fprintf(stderr, "Failed to open %s: %s\n", argv[1], strerror(errno));
+      }
+      argc--;
+      argv++;
+    } else {
+      fprintf(stderr, "Unknown option: %s\n", argv[0]);
+      return 1;
     }
     argc--;
     argv++;
@@ -154,159 +179,167 @@
     return 1;
   }
 
-  if (!g_results) {
-    puts_fp(stdout, "obase=16\nibase=16\n");
-  }
+  puts_fp(bc_file.get(), "/* This script, when run through the UNIX bc utility, "
+                         "should produce a sequence of zeros. */\n");
+  puts_fp(bc_file.get(), "/* tr a-f A-F < bn_test.out | sed s/BAsE/base/ | bc "
+                         "| grep -v 0 */\n");
+  puts_fp(bc_file.get(), "obase=16\nibase=16\n");
 
-  message(stdout, "BN_add");
-  if (!test_add(stdout)) {
+  message(bc_file.get(), "BN_add");
+  if (!test_add(bc_file.get())) {
     return 1;
   }
-  fflush(stdout);
+  flush_fp(bc_file.get());
 
-  message(stdout, "BN_sub");
-  if (!test_sub(stdout)) {
+  message(bc_file.get(), "BN_sub");
+  if (!test_sub(bc_file.get())) {
     return 1;
   }
-  fflush(stdout);
+  flush_fp(bc_file.get());
 
-  message(stdout, "BN_lshift1");
-  if (!test_lshift1(stdout)) {
+  message(bc_file.get(), "BN_lshift1");
+  if (!test_lshift1(bc_file.get())) {
     return 1;
   }
-  fflush(stdout);
+  flush_fp(bc_file.get());
 
-  message(stdout, "BN_lshift (fixed)");
+  message(bc_file.get(), "BN_lshift (fixed)");
   ScopedBIGNUM sample(BN_bin2bn(kSample, sizeof(kSample) - 1, NULL));
   if (!sample) {
     return 1;
   }
-  if (!test_lshift(stdout, ctx.get(), bssl::move(sample))) {
+  if (!test_lshift(bc_file.get(), ctx.get(), bssl::move(sample))) {
     return 1;
   }
-  fflush(stdout);
+  flush_fp(bc_file.get());
 
-  message(stdout, "BN_lshift");
-  if (!test_lshift(stdout, ctx.get(), nullptr)) {
+  message(bc_file.get(), "BN_lshift");
+  if (!test_lshift(bc_file.get(), ctx.get(), nullptr)) {
     return 1;
   }
-  fflush(stdout);
+  flush_fp(bc_file.get());
 
-  message(stdout, "BN_rshift1");
-  if (!test_rshift1(stdout)) {
+  message(bc_file.get(), "BN_rshift1");
+  if (!test_rshift1(bc_file.get())) {
     return 1;
   }
-  fflush(stdout);
+  flush_fp(bc_file.get());
 
-  message(stdout, "BN_rshift");
-  if (!test_rshift(stdout, ctx.get())) {
+  message(bc_file.get(), "BN_rshift");
+  if (!test_rshift(bc_file.get(), ctx.get())) {
     return 1;
   }
-  fflush(stdout);
+  flush_fp(bc_file.get());
 
-  message(stdout, "BN_sqr");
-  if (!test_sqr(stdout, ctx.get())) {
+  message(bc_file.get(), "BN_sqr");
+  if (!test_sqr(bc_file.get(), ctx.get())) {
     return 1;
   }
-  fflush(stdout);
+  flush_fp(bc_file.get());
 
-  message(stdout, "BN_mul");
-  if (!test_mul(stdout)) {
+  message(bc_file.get(), "BN_mul");
+  if (!test_mul(bc_file.get())) {
     return 1;
   }
-  fflush(stdout);
+  flush_fp(bc_file.get());
 
-  message(stdout, "BN_div");
-  if (!test_div(stdout, ctx.get())) {
+  message(bc_file.get(), "BN_div");
+  if (!test_div(bc_file.get(), ctx.get())) {
     return 1;
   }
-  fflush(stdout);
+  flush_fp(bc_file.get());
 
-  message(stdout, "BN_div_word");
-  if (!test_div_word(stdout)) {
+  message(bc_file.get(), "BN_div_word");
+  if (!test_div_word(bc_file.get())) {
     return 1;
   }
-  fflush(stdout);
+  flush_fp(bc_file.get());
 
-  message(stdout, "BN_mod");
-  if (!test_mod(stdout, ctx.get())) {
+  message(bc_file.get(), "BN_mod");
+  if (!test_mod(bc_file.get(), ctx.get())) {
     return 1;
   }
-  fflush(stdout);
+  flush_fp(bc_file.get());
 
-  message(stdout, "BN_mod_mul");
-  if (!test_mod_mul(stdout, ctx.get())) {
+  message(bc_file.get(), "BN_mod_mul");
+  if (!test_mod_mul(bc_file.get(), ctx.get())) {
     return 1;
   }
-  fflush(stdout);
+  flush_fp(bc_file.get());
 
-  message(stdout, "BN_mont");
-  if (!test_mont(stdout, ctx.get())) {
+  message(bc_file.get(), "BN_mont");
+  if (!test_mont(bc_file.get(), ctx.get())) {
     return 1;
   }
-  fflush(stdout);
+  flush_fp(bc_file.get());
 
-  message(stdout, "BN_mod_exp");
-  if (!test_mod_exp(stdout, ctx.get())) {
+  message(bc_file.get(), "BN_mod_exp");
+  if (!test_mod_exp(bc_file.get(), ctx.get())) {
     return 1;
   }
-  fflush(stdout);
+  flush_fp(bc_file.get());
 
-  message(stdout, "BN_mod_exp_mont_consttime");
-  if (!test_mod_exp_mont_consttime(stdout, ctx.get()) ||
-      !test_mod_exp_mont5(stdout, ctx.get())) {
+  message(bc_file.get(), "BN_mod_exp_mont_consttime");
+  if (!test_mod_exp_mont_consttime(bc_file.get(), ctx.get()) ||
+      !test_mod_exp_mont5(bc_file.get(), ctx.get())) {
     return 1;
   }
-  fflush(stdout);
+  flush_fp(bc_file.get());
 
-  message(stdout, "BN_exp");
-  if (!test_exp(stdout, ctx.get()) ||
+  message(bc_file.get(), "BN_exp");
+  if (!test_exp(bc_file.get(), ctx.get()) ||
       !test_exp_mod_zero()) {
     return 1;
   }
-  fflush(stdout);
+  flush_fp(bc_file.get());
 
-  message(stdout, "BN_mod_sqrt");
-  if (!test_mod_sqrt(stdout, ctx.get())) {
+  message(bc_file.get(), "BN_mod_sqrt");
+  if (!test_mod_sqrt(bc_file.get(), ctx.get())) {
     return 1;
   }
-  fflush(stdout);
+  flush_fp(bc_file.get());
 
-  message(stdout, "Small prime generation");
-  if (!test_small_prime(stdout, ctx.get())) {
+  message(bc_file.get(), "Small prime generation");
+  if (!test_small_prime(bc_file.get(), ctx.get())) {
     return 1;
   }
-  fflush(stdout);
+  flush_fp(bc_file.get());
 
-  message(stdout, "BN_sqrt");
-  if (!test_sqrt(stdout, ctx.get())) {
+  message(bc_file.get(), "BN_sqrt");
+  if (!test_sqrt(bc_file.get(), ctx.get())) {
     return 1;
   }
-  fflush(stdout);
+  flush_fp(bc_file.get());
 
-  message(stdout, "BN_bn2bin_padded");
-  if (!test_bn2bin_padded(stdout, ctx.get())) {
+  message(bc_file.get(), "BN_bn2bin_padded");
+  if (!test_bn2bin_padded(bc_file.get(), ctx.get())) {
     return 1;
   }
-  fflush(stdout);
+  flush_fp(bc_file.get());
 
-  message(stdout, "BN_dec2bn");
-  if (!test_dec2bn(stdout, ctx.get())) {
+  message(bc_file.get(), "BN_dec2bn");
+  if (!test_dec2bn(bc_file.get(), ctx.get())) {
     return 1;
   }
-  fflush(stdout);
+  flush_fp(bc_file.get());
 
-  message(stdout, "BN_hex2bn");
-  if (!test_hex2bn(stdout, ctx.get())) {
+  message(bc_file.get(), "BN_hex2bn");
+  if (!test_hex2bn(bc_file.get(), ctx.get())) {
     return 1;
   }
-  fflush(stdout);
+  flush_fp(bc_file.get());
 
-  message(stdout, "BN_asc2bn");
-  if (!test_asc2bn(stdout, ctx.get())) {
+  message(bc_file.get(), "BN_asc2bn");
+  if (!test_asc2bn(bc_file.get(), ctx.get())) {
     return 1;
   }
-  fflush(stdout);
+  flush_fp(bc_file.get());
+
+  message(bc_file.get(), "BN_rand");
+  if (!test_rand()) {
+    return 1;
+  }
+  flush_fp(bc_file.get());
 
   printf("PASS\n");
   return 0;
@@ -330,12 +363,10 @@
       return false;
     }
     if (fp != NULL) {
-      if (!g_results) {
-        BN_print_fp(fp, a.get());
-        puts_fp(fp, " + ");
-        BN_print_fp(fp, b.get());
-        puts_fp(fp, " - ");
-      }
+      BN_print_fp(fp, a.get());
+      puts_fp(fp, " + ");
+      BN_print_fp(fp, b.get());
+      puts_fp(fp, " - ");
       BN_print_fp(fp, c.get());
       puts_fp(fp, "\n");
     }
@@ -380,12 +411,10 @@
       return false;
     }
     if (fp != NULL) {
-      if (!g_results) {
-        BN_print_fp(fp, a.get());
-        puts_fp(fp, " - ");
-        BN_print_fp(fp, b.get());
-        puts_fp(fp, " - ");
-      }
+      BN_print_fp(fp, a.get());
+      puts_fp(fp, " - ");
+      BN_print_fp(fp, b.get());
+      puts_fp(fp, " - ");
       BN_print_fp(fp, c.get());
       puts_fp(fp, "\n");
     }
@@ -428,21 +457,17 @@
       return false;
     }
     if (fp != NULL) {
-      if (!g_results) {
-        BN_print_fp(fp, a.get());
-        puts_fp(fp, " / ");
-        BN_print_fp(fp, b.get());
-        puts_fp(fp, " - ");
-      }
+      BN_print_fp(fp, a.get());
+      puts_fp(fp, " / ");
+      BN_print_fp(fp, b.get());
+      puts_fp(fp, " - ");
       BN_print_fp(fp, d.get());
       puts_fp(fp, "\n");
 
-      if (!g_results) {
-        BN_print_fp(fp, a.get());
-        puts_fp(fp, " % ");
-        BN_print_fp(fp, b.get());
-        puts_fp(fp, " - ");
-      }
+      BN_print_fp(fp, a.get());
+      puts_fp(fp, " % ");
+      BN_print_fp(fp, b.get());
+      puts_fp(fp, " - ");
       BN_print_fp(fp, c.get());
       puts_fp(fp, "\n");
     }
@@ -499,11 +524,9 @@
       return false;
     }
     if (fp != NULL) {
-      if (!g_results) {
-        BN_print_fp(fp, a.get());
-        puts_fp(fp, " * 2");
-        puts_fp(fp, " - ");
-      }
+      BN_print_fp(fp, a.get());
+      puts_fp(fp, " * 2");
+      puts_fp(fp, " - ");
       BN_print_fp(fp, b.get());
       puts_fp(fp, "\n");
     }
@@ -540,12 +563,10 @@
       return false;
     }
     if (fp != NULL) {
-      if (!g_results) {
-        BN_print_fp(fp, a.get());
-        puts_fp(fp, " / ");
-        BN_print_fp(fp, c.get());
-        puts_fp(fp, " - ");
-      }
+      BN_print_fp(fp, a.get());
+      puts_fp(fp, " / ");
+      BN_print_fp(fp, c.get());
+      puts_fp(fp, " - ");
       BN_print_fp(fp, b.get());
       puts_fp(fp, "\n");
     }
@@ -575,11 +596,9 @@
       return false;
     }
     if (fp != NULL) {
-      if (!g_results) {
-        BN_print_fp(fp, a.get());
-        puts_fp(fp, " / 2");
-        puts_fp(fp, " - ");
-      }
+      BN_print_fp(fp, a.get());
+      puts_fp(fp, " / 2");
+      puts_fp(fp, " - ");
       BN_print_fp(fp, b.get());
       puts_fp(fp, "\n");
     }
@@ -620,12 +639,10 @@
       return false;
     }
     if (fp != NULL) {
-      if (!g_results) {
-        BN_print_fp(fp, a.get());
-        puts_fp(fp, " * ");
-        BN_print_fp(fp, c.get());
-        puts_fp(fp, " - ");
-      }
+      BN_print_fp(fp, a.get());
+      puts_fp(fp, " * ");
+      BN_print_fp(fp, c.get());
+      puts_fp(fp, " - ");
       BN_print_fp(fp, b.get());
       puts_fp(fp, "\n");
     }
@@ -676,12 +693,10 @@
       return false;
     }
     if (fp != NULL) {
-      if (!g_results) {
-        BN_print_fp(fp, a.get());
-        puts_fp(fp, " * ");
-        BN_print_fp(fp, b.get());
-        puts_fp(fp, " - ");
-      }
+      BN_print_fp(fp, a.get());
+      puts_fp(fp, " * ");
+      BN_print_fp(fp, b.get());
+      puts_fp(fp, " - ");
       BN_print_fp(fp, c.get());
       puts_fp(fp, "\n");
     }
@@ -730,12 +745,10 @@
       return false;
     }
     if (fp != NULL) {
-      if (!g_results) {
-        BN_print_fp(fp, a.get());
-        puts_fp(fp, " * ");
-        BN_print_fp(fp, a.get());
-        puts_fp(fp, " - ");
-      }
+      BN_print_fp(fp, a.get());
+      puts_fp(fp, " * ");
+      BN_print_fp(fp, a.get());
+      puts_fp(fp, " - ");
       BN_print_fp(fp, c.get());
       puts_fp(fp, "\n");
     }
@@ -758,12 +771,10 @@
     return false;
   }
   if (fp != NULL) {
-    if (!g_results) {
-      BN_print_fp(fp, a.get());
-      puts_fp(fp, " * ");
-      BN_print_fp(fp, a.get());
-      puts_fp(fp, " - ");
-    }
+    BN_print_fp(fp, a.get());
+    puts_fp(fp, " * ");
+    BN_print_fp(fp, a.get());
+    puts_fp(fp, " - ");
     BN_print_fp(fp, c.get());
     puts_fp(fp, "\n");
   }
@@ -786,12 +797,10 @@
     return false;
   }
   if (fp != NULL) {
-    if (!g_results) {
-      BN_print_fp(fp, a.get());
-      puts_fp(fp, " * ");
-      BN_print_fp(fp, a.get());
-      puts_fp(fp, " - ");
-    }
+    BN_print_fp(fp, a.get());
+    puts_fp(fp, " * ");
+    BN_print_fp(fp, a.get());
+    puts_fp(fp, " - ");
     BN_print_fp(fp, c.get());
     puts_fp(fp, "\n");
   }
@@ -846,21 +855,17 @@
     }
 
     if (fp != NULL) {
-      if (!g_results) {
-        BN_print_fp(fp, a.get());
-        puts_fp(fp, " / ");
-        print_word(fp, s);
-        puts_fp(fp, " - ");
-      }
+      BN_print_fp(fp, a.get());
+      puts_fp(fp, " / ");
+      print_word(fp, s);
+      puts_fp(fp, " - ");
       BN_print_fp(fp, b.get());
       puts_fp(fp, "\n");
 
-      if (!g_results) {
-        BN_print_fp(fp, a.get());
-        puts_fp(fp, " % ");
-        print_word(fp, s);
-        puts_fp(fp, " - ");
-      }
+      BN_print_fp(fp, a.get());
+      puts_fp(fp, " % ");
+      print_word(fp, s);
+      puts_fp(fp, " - ");
       print_word(fp, r);
       puts_fp(fp, "\n");
     }
@@ -909,14 +914,12 @@
       return false;
     }
     if (fp != NULL) {
-      if (!g_results) {
-        BN_print_fp(fp, a.get());
-        puts_fp(fp, " * ");
-        BN_print_fp(fp, b.get());
-        puts_fp(fp, " % ");
-        BN_print_fp(fp, &mont->N);
-        puts_fp(fp, " - ");
-      }
+      BN_print_fp(fp, a.get());
+      puts_fp(fp, " * ");
+      BN_print_fp(fp, b.get());
+      puts_fp(fp, " % ");
+      BN_print_fp(fp, &mont->N);
+      puts_fp(fp, " - ");
       BN_print_fp(fp, A.get());
       puts_fp(fp, "\n");
     }
@@ -953,12 +956,10 @@
       return false;
     }
     if (fp != NULL) {
-      if (!g_results) {
-        BN_print_fp(fp, a.get());
-        puts_fp(fp, " % ");
-        BN_print_fp(fp, b.get());
-        puts_fp(fp, " - ");
-      }
+      BN_print_fp(fp, a.get());
+      puts_fp(fp, " % ");
+      BN_print_fp(fp, b.get());
+      puts_fp(fp, " - ");
       BN_print_fp(fp, c.get());
       puts_fp(fp, "\n");
     }
@@ -1000,22 +1001,20 @@
         return false;
       }
       if (fp != NULL) {
-        if (!g_results) {
-          BN_print_fp(fp, a.get());
-          puts_fp(fp, " * ");
-          BN_print_fp(fp, b.get());
-          puts_fp(fp, " % ");
+        BN_print_fp(fp, a.get());
+        puts_fp(fp, " * ");
+        BN_print_fp(fp, b.get());
+        puts_fp(fp, " % ");
+        BN_print_fp(fp, c.get());
+        if (a->neg != b->neg && !BN_is_zero(e.get())) {
+          // If  (a*b) % c  is negative,  c  must be added
+          // in order to obtain the normalized remainder
+          // (new with OpenSSL 0.9.7, previous versions of
+          // BN_mod_mul could generate negative results)
+          puts_fp(fp, " + ");
           BN_print_fp(fp, c.get());
-          if (a->neg != b->neg && !BN_is_zero(e.get())) {
-            // If  (a*b) % c  is negative,  c  must be added
-            // in order to obtain the normalized remainder
-            // (new with OpenSSL 0.9.7, previous versions of
-            // BN_mod_mul could generate negative results)
-            puts_fp(fp, " + ");
-            BN_print_fp(fp, c.get());
-          }
-          puts_fp(fp, " - ");
         }
+        puts_fp(fp, " - ");
         BN_print_fp(fp, e.get());
         puts_fp(fp, "\n");
       }
@@ -1052,14 +1051,12 @@
     }
 
     if (fp != NULL) {
-      if (!g_results) {
-        BN_print_fp(fp, a.get());
-        puts_fp(fp, " ^ ");
-        BN_print_fp(fp, b.get());
-        puts_fp(fp, " % ");
-        BN_print_fp(fp, c.get());
-        puts_fp(fp, " - ");
-      }
+      BN_print_fp(fp, a.get());
+      puts_fp(fp, " ^ ");
+      BN_print_fp(fp, b.get());
+      puts_fp(fp, " % ");
+      BN_print_fp(fp, c.get());
+      puts_fp(fp, " - ");
       BN_print_fp(fp, d.get());
       puts_fp(fp, "\n");
     }
@@ -1095,14 +1092,12 @@
     }
 
     if (fp != NULL) {
-      if (!g_results) {
-        BN_print_fp(fp, a.get());
-        puts_fp(fp, " ^ ");
-        BN_print_fp(fp, b.get());
-        puts_fp(fp, " % ");
-        BN_print_fp(fp, c.get());
-        puts_fp(fp, " - ");
-      }
+      BN_print_fp(fp, a.get());
+      puts_fp(fp, " ^ ");
+      BN_print_fp(fp, b.get());
+      puts_fp(fp, " % ");
+      BN_print_fp(fp, c.get());
+      puts_fp(fp, " - ");
       BN_print_fp(fp, d.get());
       puts_fp(fp, "\n");
     }
@@ -1203,12 +1198,10 @@
     }
 
     if (fp != NULL) {
-      if (!g_results) {
-        BN_print_fp(fp, a.get());
-        puts_fp(fp, " ^ ");
-        BN_print_fp(fp, b.get());
-        puts_fp(fp, " - ");
-      }
+      BN_print_fp(fp, a.get());
+      puts_fp(fp, " ^ ");
+      BN_print_fp(fp, b.get());
+      puts_fp(fp, " - ");
       BN_print_fp(fp, d.get());
       puts_fp(fp, "\n");
     }
@@ -1247,32 +1240,15 @@
   }
 
   if (!BN_is_zero(r.get())) {
-    printf("1**0 mod 1 = ");
-    BN_print_fp(stdout, r.get());
-    printf(", should be 0\n");
+    fprintf(stderr, "1**0 mod 1 = ");
+    BN_print_fp(stderr, r.get());
+    fprintf(stderr, ", should be 0\n");
     return false;
   }
 
   return true;
 }
 
-static int genprime_cb(int p, int n, BN_GENCB *arg) {
-  char c = '*';
-
-  if (p == 0) {
-    c = '.';
-  } else if (p == 1) {
-    c = '+';
-  } else if (p == 2) {
-    c = '*';
-  } else if (p == 3) {
-    c = '\n';
-  }
-  putc(c, stdout);
-  fflush(stdout);
-  return 1;
-}
-
 static bool test_mod_sqrt(FILE *fp, BN_CTX *ctx) {
   ScopedBIGNUM a(BN_new());
   ScopedBIGNUM p(BN_new());
@@ -1281,9 +1257,6 @@
     return false;
   }
 
-  BN_GENCB cb;
-  BN_GENCB_set(&cb, genprime_cb, NULL);
-
   for (int i = 0; i < 16; i++) {
     if (i < 8) {
       const unsigned kPrimes[8] = {2, 3, 5, 7, 11, 13, 17, 19};
@@ -1293,10 +1266,9 @@
     } else {
       if (!BN_set_word(a.get(), 32) ||
           !BN_set_word(r.get(), 2 * i + 1) ||
-          !BN_generate_prime_ex(p.get(), 256, 0, a.get(), r.get(), &cb)) {
+          !BN_generate_prime_ex(p.get(), 256, 0, a.get(), r.get(), nullptr)) {
         return false;
       }
-      putc('\n', stdout);
     }
     p->neg = rand_neg();
 
@@ -1332,26 +1304,21 @@
         fprintf(stderr, "\n");
         return false;
       }
-
-      putc('.', stdout);
-      fflush(stdout);
     }
-
-    putc('\n', stdout);
-    fflush(stderr);
   }
   return true;
 }
 
 static bool test_small_prime(FILE *fp, BN_CTX *ctx) {
-  static const int kBits = 10;
+  static const unsigned kBits = 10;
 
   ScopedBIGNUM r(BN_new());
-  if (!r || !BN_generate_prime_ex(r.get(), kBits, 0, NULL, NULL, NULL)) {
+  if (!r || !BN_generate_prime_ex(r.get(), static_cast<int>(kBits), 0, NULL,
+                                  NULL, NULL)) {
     return false;
   }
   if (BN_num_bits(r.get()) != kBits) {
-    fprintf(fp, "Expected %d bit prime, got %d bit number\n", kBits,
+    fprintf(fp, "Expected %u bit prime, got %u bit number\n", kBits,
             BN_num_bits(r.get()));
     return false;
   }
@@ -1617,3 +1584,47 @@
 
   return true;
 }
+
+static bool test_rand() {
+  ScopedBIGNUM bn(BN_new());
+  if (!bn) {
+    return false;
+  }
+
+  // Test BN_rand accounts for degenerate cases with |top| and |bottom|
+  // parameters.
+  if (!BN_rand(bn.get(), 0, 0 /* top */, 0 /* bottom */) ||
+      !BN_is_zero(bn.get())) {
+    fprintf(stderr, "BN_rand gave a bad result.\n");
+    return false;
+  }
+  if (!BN_rand(bn.get(), 0, 1 /* top */, 1 /* bottom */) ||
+      !BN_is_zero(bn.get())) {
+    fprintf(stderr, "BN_rand gave a bad result.\n");
+    return false;
+  }
+
+  if (!BN_rand(bn.get(), 1, 0 /* top */, 0 /* bottom */) ||
+      !BN_is_word(bn.get(), 1)) {
+    fprintf(stderr, "BN_rand gave a bad result.\n");
+    return false;
+  }
+  if (!BN_rand(bn.get(), 1, 1 /* top */, 0 /* bottom */) ||
+      !BN_is_word(bn.get(), 1)) {
+    fprintf(stderr, "BN_rand gave a bad result.\n");
+    return false;
+  }
+  if (!BN_rand(bn.get(), 1, -1 /* top */, 1 /* bottom */) ||
+      !BN_is_word(bn.get(), 1)) {
+    fprintf(stderr, "BN_rand gave a bad result.\n");
+    return false;
+  }
+
+  if (!BN_rand(bn.get(), 2, 1 /* top */, 0 /* bottom */) ||
+      !BN_is_word(bn.get(), 3)) {
+    fprintf(stderr, "BN_rand gave a bad result.\n");
+    return false;
+  }
+
+  return true;
+}
diff --git a/src/crypto/bn/random.c b/src/crypto/bn/random.c
index 3be7510..549ac48 100644
--- a/src/crypto/bn/random.c
+++ b/src/crypto/bn/random.c
@@ -144,7 +144,7 @@
   }
 
   if (top != -1) {
-    if (top) {
+    if (top && bits > 1) {
       if (bit == 0) {
         buf[0] = 1;
         buf[1] |= 0x80;
diff --git a/src/crypto/bn/shift.c b/src/crypto/bn/shift.c
index 1e3b7c3..f143996 100644
--- a/src/crypto/bn/shift.c
+++ b/src/crypto/bn/shift.c
@@ -58,6 +58,8 @@
 
 #include <string.h>
 
+#include <openssl/err.h>
+
 #include "internal.h"
 
 
@@ -66,6 +68,11 @@
   BN_ULONG *t, *f;
   BN_ULONG l;
 
+  if (n < 0) {
+    OPENSSL_PUT_ERROR(BN, BN_lshift, BN_R_NEGATIVE_NUMBER);
+    return 0;
+  }
+
   r->neg = a->neg;
   nw = n / BN_BITS2;
   if (bn_wexpand(r, a->top + nw + 1) == NULL) {
@@ -130,6 +137,11 @@
   BN_ULONG *t, *f;
   BN_ULONG l, tmp;
 
+  if (n < 0) {
+    OPENSSL_PUT_ERROR(BN, BN_rshift, BN_R_NEGATIVE_NUMBER);
+    return 0;
+  }
+
   nw = n / BN_BITS2;
   rb = n % BN_BITS2;
   lb = BN_BITS2 - rb;
diff --git a/src/crypto/bytestring/CMakeLists.txt b/src/crypto/bytestring/CMakeLists.txt
index d1f0441..cbbacf2 100644
--- a/src/crypto/bytestring/CMakeLists.txt
+++ b/src/crypto/bytestring/CMakeLists.txt
@@ -14,6 +14,8 @@
   bytestring_test
 
   bytestring_test.cc
+
+  $<TARGET_OBJECTS:test_support>
 )
 
 target_link_libraries(bytestring_test crypto)
diff --git a/src/crypto/bytestring/ber.c b/src/crypto/bytestring/ber.c
index 2729fa1..e3b150c 100644
--- a/src/crypto/bytestring/ber.c
+++ b/src/crypto/bytestring/ber.c
@@ -43,7 +43,7 @@
     unsigned tag;
     size_t header_len;
 
-    if (!CBS_get_any_asn1_element(&in, &contents, &tag, &header_len)) {
+    if (!CBS_get_any_ber_asn1_element(&in, &contents, &tag, &header_len)) {
       return 0;
     }
     if (CBS_len(&contents) == header_len &&
@@ -74,7 +74,7 @@
 }
 
 /* is_eoc returns true if |header_len| and |contents|, as returned by
- * |CBS_get_any_asn1_element|, indicate an "end of contents" (EOC) value. */
+ * |CBS_get_any_ber_asn1_element|, indicate an "end of contents" (EOC) value. */
 static char is_eoc(size_t header_len, CBS *contents) {
   return header_len == 2 && CBS_len(contents) == 2 &&
          memcmp(CBS_data(contents), "\x00\x00", 2) == 0;
@@ -98,7 +98,7 @@
     size_t header_len;
     CBB *out_contents, out_contents_storage;
 
-    if (!CBS_get_any_asn1_element(in, &contents, &tag, &header_len)) {
+    if (!CBS_get_any_ber_asn1_element(in, &contents, &tag, &header_len)) {
       return 0;
     }
     out_contents = out;
@@ -129,8 +129,8 @@
           size_t inner_header_len;
 
           CBS_init(&in_copy, CBS_data(in), CBS_len(in));
-          if (!CBS_get_any_asn1_element(&in_copy, &inner_contents, &inner_tag,
-                                        &inner_header_len)) {
+          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 &&
@@ -209,7 +209,9 @@
     return 1;
   }
 
-  CBB_init(&cbb, CBS_len(in));
+  if (!CBB_init(&cbb, CBS_len(in))) {
+    return 0;
+  }
   if (!cbs_convert_ber(in, &cbb, 0, 0, 0)) {
     CBB_cleanup(&cbb);
     return 0;
diff --git a/src/crypto/bytestring/cbs.c b/src/crypto/bytestring/cbs.c
index 10f1a99..b8caedd 100644
--- a/src/crypto/bytestring/cbs.c
+++ b/src/crypto/bytestring/cbs.c
@@ -157,8 +157,8 @@
   return cbs_get_length_prefixed(cbs, out, 3);
 }
 
-int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
-                             size_t *out_header_len) {
+static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
+                                    size_t *out_header_len, int ber_ok) {
   uint8_t tag, length_byte;
   CBS header = *cbs;
   CBS throwaway;
@@ -193,9 +193,11 @@
     const size_t num_bytes = length_byte & 0x7f;
     uint32_t len32;
 
-    if ((tag & CBS_ASN1_CONSTRUCTED) != 0 && num_bytes == 0) {
+    if (ber_ok && (tag & CBS_ASN1_CONSTRUCTED) != 0 && num_bytes == 0) {
       /* indefinite length */
-      *out_header_len = 2;
+      if (out_header_len != NULL) {
+        *out_header_len = 2;
+      }
       return CBS_get_bytes(cbs, out, 2);
     }
 
@@ -227,6 +229,18 @@
   return CBS_get_bytes(cbs, out, len);
 }
 
+int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
+                                    size_t *out_header_len) {
+  return cbs_get_any_asn1_element(cbs, out, out_tag, out_header_len,
+                                  0 /* DER only */);
+}
+
+int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
+                                 size_t *out_header_len) {
+  return cbs_get_any_asn1_element(cbs, out, out_tag, out_header_len,
+                                  1 /* BER allowed */);
+}
+
 static int cbs_get_asn1(CBS *cbs, CBS *out, unsigned tag_value,
                         int skip_header) {
   size_t header_len;
@@ -238,12 +252,7 @@
   }
 
   if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) ||
-      tag != tag_value ||
-      (header_len > 0 &&
-       /* This ensures that the tag is either zero length or
-        * indefinite-length. */
-       CBS_len(out) == header_len &&
-       CBS_data(out)[header_len - 1] == 0x80)) {
+      tag != tag_value) {
     return 0;
   }
 
diff --git a/src/crypto/bytestring/internal.h b/src/crypto/bytestring/internal.h
index b4ea7e5..391ad19 100644
--- a/src/crypto/bytestring/internal.h
+++ b/src/crypto/bytestring/internal.h
@@ -38,6 +38,14 @@
  * It returns one on success and zero otherwise. */
 OPENSSL_EXPORT int CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len);
 
+/* CBS_get_any_ber_asn1_element acts the same as |CBS_get_any_asn1_element| but
+ * also allows indefinite-length elements to be returned. In that case,
+ * |*out_header_len| and |CBS_len(out)| will both be two as only the header is
+ * returned. */
+OPENSSL_EXPORT int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out,
+                                                unsigned *out_tag,
+                                                size_t *out_header_len);
+
 
 #if defined(__cplusplus)
 }  /* extern C */
diff --git a/src/crypto/cipher/CMakeLists.txt b/src/crypto/cipher/CMakeLists.txt
index f428e25..2775698 100644
--- a/src/crypto/cipher/CMakeLists.txt
+++ b/src/crypto/cipher/CMakeLists.txt
@@ -24,7 +24,8 @@
 add_executable(
   cipher_test
 
-  cipher_test.c
+  cipher_test.cc
+  $<TARGET_OBJECTS:test_support>
 )
 
 add_executable(
diff --git a/src/crypto/cipher/cipher.c b/src/crypto/cipher/cipher.c
index 1dcfd06..400c3f5 100644
--- a/src/crypto/cipher/cipher.c
+++ b/src/crypto/cipher/cipher.c
@@ -94,14 +94,13 @@
 }
 
 int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c) {
-  if (c->cipher != NULL && c->cipher->cleanup) {
-    c->cipher->cleanup(c);
-  }
-
-  if (c->cipher_data) {
+  if (c->cipher != NULL) {
+    if (c->cipher->cleanup) {
+      c->cipher->cleanup(c);
+    }
     OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size);
-    OPENSSL_free(c->cipher_data);
   }
+  OPENSSL_free(c->cipher_data);
 
   memset(c, 0, sizeof(EVP_CIPHER_CTX));
   return 1;
@@ -165,6 +164,7 @@
     if (ctx->cipher->ctx_size) {
       ctx->cipher_data = OPENSSL_malloc(ctx->cipher->ctx_size);
       if (!ctx->cipher_data) {
+        ctx->cipher = NULL;
         OPENSSL_PUT_ERROR(CIPHER, EVP_CipherInit_ex, ERR_R_MALLOC_FAILURE);
         return 0;
       }
@@ -177,6 +177,7 @@
 
     if (ctx->cipher->flags & EVP_CIPH_CTRL_INIT) {
       if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) {
+        ctx->cipher = NULL;
         OPENSSL_PUT_ERROR(CIPHER, EVP_CipherInit_ex, CIPHER_R_INITIALIZATION_ERROR);
         return 0;
       }
diff --git a/src/crypto/cipher/cipher_test.c b/src/crypto/cipher/cipher_test.c
deleted file mode 100644
index 390262f..0000000
--- a/src/crypto/cipher/cipher_test.c
+++ /dev/null
@@ -1,423 +0,0 @@
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.] */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <openssl/cipher.h>
-#include <openssl/crypto.h>
-#include <openssl/err.h>
-
-
-static void hexdump(FILE *f, const char *title, const uint8_t *s, int l) {
-  int n = 0;
-
-  fprintf(f, "%s", title);
-  for (; n < l; ++n) {
-    if ((n % 16) == 0) {
-      fprintf(f, "\n%04x", n);
-    }
-    fprintf(f, " %02x", s[n]);
-  }
-  fprintf(f, "\n");
-}
-
-static int convert(uint8_t *s) {
-  uint8_t *d;
-
-  for (d = s; *s; s += 2, ++d) {
-    unsigned int n;
-
-    if (!s[1]) {
-      fprintf(stderr, "Odd number of hex digits!");
-      exit(4);
-    }
-    sscanf((char *)s, "%2x", &n);
-    *d = (uint8_t)n;
-  }
-  return s - d;
-}
-
-static char *sstrsep(char **string, const char *delim) {
-  char isdelim[256];
-  char *token = *string;
-
-  if (**string == 0) {
-    return NULL;
-  }
-
-  memset(isdelim, 0, 256);
-  isdelim[0] = 1;
-
-  while (*delim) {
-    isdelim[(uint8_t)(*delim)] = 1;
-    delim++;
-  }
-
-  while (!isdelim[(uint8_t)(**string)]) {
-    (*string)++;
-  }
-
-  if (**string) {
-    **string = 0;
-    (*string)++;
-  }
-
-  return token;
-}
-
-static uint8_t *ustrsep(char **p, const char *sep) {
-  return (uint8_t *)sstrsep(p, sep);
-}
-
-static void test1(const char* cipher_name, const EVP_CIPHER *c,
-                  const uint8_t *key, int kn, const uint8_t *iv, int in,
-                  const uint8_t *plaintext, int pn, const uint8_t *ciphertext,
-                  int cn, const uint8_t *aad, int an, const uint8_t *tag,
-                  int tn, int encdec) {
-  EVP_CIPHER_CTX ctx;
-  uint8_t out[4096];
-  int outl, outl2, mode;
-
-  printf("Testing cipher %s%s\n", cipher_name,
-         (encdec == 1 ? "(encrypt)"
-                      : (encdec == 0 ? "(decrypt)" : "(encrypt/decrypt)")));
-  hexdump(stdout, "Key", key, kn);
-  if (in) {
-    hexdump(stdout, "IV", iv, in);
-  }
-  hexdump(stdout, "Plaintext", plaintext, pn);
-  hexdump(stdout, "Ciphertext", ciphertext, cn);
-  if (an) {
-    hexdump(stdout, "AAD", aad, an);
-  }
-  if (tn) {
-    hexdump(stdout, "Tag", tag, tn);
-  }
-  mode = EVP_CIPHER_mode(c);
-  if (kn != EVP_CIPHER_key_length(c)) {
-    fprintf(stderr, "Key length doesn't match, got %d expected %lu\n", kn,
-            (unsigned long)EVP_CIPHER_key_length(c));
-    exit(5);
-  }
-  EVP_CIPHER_CTX_init(&ctx);
-  if (encdec != 0) {
-    if (mode == EVP_CIPH_GCM_MODE) {
-      if (!EVP_EncryptInit_ex(&ctx, c, NULL, NULL, NULL)) {
-        fprintf(stderr, "EncryptInit failed\n");
-        ERR_print_errors_fp(stderr);
-        exit(10);
-      }
-      if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, in, NULL)) {
-        fprintf(stderr, "IV length set failed\n");
-        ERR_print_errors_fp(stderr);
-        exit(11);
-      }
-      if (!EVP_EncryptInit_ex(&ctx, NULL, NULL, key, iv)) {
-        fprintf(stderr, "Key/IV set failed\n");
-        ERR_print_errors_fp(stderr);
-        exit(12);
-      }
-      if (an && !EVP_EncryptUpdate(&ctx, NULL, &outl, aad, an)) {
-        fprintf(stderr, "AAD set failed\n");
-        ERR_print_errors_fp(stderr);
-        exit(13);
-      }
-    } else if (!EVP_EncryptInit_ex(&ctx, c, NULL, key, iv)) {
-      fprintf(stderr, "EncryptInit failed\n");
-      ERR_print_errors_fp(stderr);
-      exit(10);
-    }
-    EVP_CIPHER_CTX_set_padding(&ctx, 0);
-
-    if (!EVP_EncryptUpdate(&ctx, out, &outl, plaintext, pn)) {
-      fprintf(stderr, "Encrypt failed\n");
-      ERR_print_errors_fp(stderr);
-      exit(6);
-    }
-    if (!EVP_EncryptFinal_ex(&ctx, out + outl, &outl2)) {
-      fprintf(stderr, "EncryptFinal failed\n");
-      ERR_print_errors_fp(stderr);
-      exit(7);
-    }
-
-    if (outl + outl2 != cn) {
-      fprintf(stderr, "Ciphertext length mismatch got %d expected %d\n",
-              outl + outl2, cn);
-      exit(8);
-    }
-
-    if (memcmp(out, ciphertext, cn)) {
-      fprintf(stderr, "Ciphertext mismatch\n");
-      hexdump(stderr, "Got", out, cn);
-      hexdump(stderr, "Expected", ciphertext, cn);
-      exit(9);
-    }
-    if (mode == EVP_CIPH_GCM_MODE) {
-      uint8_t rtag[16];
-      /* Note: EVP_CTRL_CCM_GET_TAG has same value as
-       * EVP_CTRL_GCM_GET_TAG
-       */
-      if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, tn, rtag)) {
-        fprintf(stderr, "Get tag failed\n");
-        ERR_print_errors_fp(stderr);
-        exit(14);
-      }
-      if (memcmp(rtag, tag, tn)) {
-        fprintf(stderr, "Tag mismatch\n");
-        hexdump(stderr, "Got", rtag, tn);
-        hexdump(stderr, "Expected", tag, tn);
-        exit(9);
-      }
-    }
-  }
-
-  if (encdec <= 0) {
-    if (mode == EVP_CIPH_GCM_MODE) {
-      if (!EVP_DecryptInit_ex(&ctx, c, NULL, NULL, NULL)) {
-        fprintf(stderr, "EncryptInit failed\n");
-        ERR_print_errors_fp(stderr);
-        exit(10);
-      }
-      if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, in, NULL)) {
-        fprintf(stderr, "IV length set failed\n");
-        ERR_print_errors_fp(stderr);
-        exit(11);
-      }
-      if (!EVP_DecryptInit_ex(&ctx, NULL, NULL, key, iv)) {
-        fprintf(stderr, "Key/IV set failed\n");
-        ERR_print_errors_fp(stderr);
-        exit(12);
-      }
-      if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, tn, (void *)tag)) {
-        fprintf(stderr, "Set tag failed\n");
-        ERR_print_errors_fp(stderr);
-        exit(14);
-      }
-      if (an && !EVP_DecryptUpdate(&ctx, NULL, &outl, aad, an)) {
-        fprintf(stderr, "AAD set failed\n");
-        ERR_print_errors_fp(stderr);
-        exit(13);
-      }
-    } else if (!EVP_DecryptInit_ex(&ctx, c, NULL, key, iv)) {
-      fprintf(stderr, "DecryptInit failed\n");
-      ERR_print_errors_fp(stderr);
-      exit(11);
-    }
-    EVP_CIPHER_CTX_set_padding(&ctx, 0);
-
-    if (!EVP_DecryptUpdate(&ctx, out, &outl, ciphertext, cn)) {
-      fprintf(stderr, "Decrypt failed\n");
-      ERR_print_errors_fp(stderr);
-      exit(6);
-    }
-    outl2 = 0;
-    if (!EVP_DecryptFinal_ex(&ctx, out + outl, &outl2)) {
-      fprintf(stderr, "DecryptFinal failed\n");
-      ERR_print_errors_fp(stderr);
-      exit(7);
-    }
-
-    if (outl + outl2 != pn) {
-      fprintf(stderr, "Plaintext length mismatch got %d expected %d\n",
-              outl + outl2, pn);
-      exit(8);
-    }
-
-    if (memcmp(out, plaintext, pn)) {
-      fprintf(stderr, "Plaintext mismatch\n");
-      hexdump(stderr, "Got", out, pn);
-      hexdump(stderr, "Expected", plaintext, pn);
-      exit(9);
-    }
-  }
-
-  EVP_CIPHER_CTX_cleanup(&ctx);
-
-  printf("\n");
-}
-
-static int test_cipher(const char *cipher, const uint8_t *key, int kn,
-                       const uint8_t *iv, int in, const uint8_t *plaintext,
-                       int pn, const uint8_t *ciphertext, int cn,
-                       const uint8_t *aad, int an, const uint8_t *tag, int tn,
-                       int encdec) {
-  const EVP_CIPHER *c;
-
-  if (strcmp(cipher, "DES-CBC") == 0) {
-    c = EVP_des_cbc();
-  } else if (strcmp(cipher, "DES-EDE3-CBC") == 0) {
-    c = EVP_des_ede3_cbc();
-  } else if (strcmp(cipher, "RC4") == 0) {
-    c = EVP_rc4();
-  } else if (strcmp(cipher, "AES-128-ECB") == 0) {
-    c = EVP_aes_128_ecb();
-  } else if (strcmp(cipher, "AES-256-ECB") == 0) {
-    c = EVP_aes_256_ecb();
-  } else if (strcmp(cipher, "AES-128-CBC") == 0) {
-    c = EVP_aes_128_cbc();
-  } else if (strcmp(cipher, "AES-128-GCM") == 0) {
-    c = EVP_aes_128_gcm();
-  } else if (strcmp(cipher, "AES-128-OFB") == 0) {
-    c = EVP_aes_128_ofb();
-  } else if (strcmp(cipher, "AES-192-CBC") == 0) {
-    c = EVP_aes_192_cbc();
-  } else if (strcmp(cipher, "AES-192-ECB") == 0) {
-    c = EVP_aes_192_ecb();
-  } else if (strcmp(cipher, "AES-256-CBC") == 0) {
-    c = EVP_aes_256_cbc();
-  } else if (strcmp(cipher, "AES-128-CTR") == 0) {
-    c = EVP_aes_128_ctr();
-  } else if (strcmp(cipher, "AES-256-CTR") == 0) {
-    c = EVP_aes_256_ctr();
-  } else if (strcmp(cipher, "AES-256-GCM") == 0) {
-    c = EVP_aes_256_gcm();
-  } else if (strcmp(cipher, "AES-256-OFB") == 0) {
-    c = EVP_aes_256_ofb();
-  } else {
-    fprintf(stderr, "Unknown cipher type %s\n", cipher);
-    return 0;
-  }
-
-  test1(cipher, c, key, kn, iv, in, plaintext, pn, ciphertext, cn, aad, an,
-        tag, tn, encdec);
-
-  return 1;
-}
-
-int main(int argc, char **argv) {
-  const char *input_file;
-  FILE *f;
-
-  CRYPTO_library_init();
-
-  if (argc != 2) {
-    fprintf(stderr, "%s <test file>\n", argv[0]);
-    return 1;
-  }
-
-  input_file = argv[1];
-
-  f = fopen(input_file, "r");
-  if (!f) {
-    perror(input_file);
-    return 2;
-  }
-
-  ERR_load_crypto_strings();
-
-  for (;;) {
-    char line[4096];
-    char *p;
-    char *cipher;
-    uint8_t *iv, *key, *plaintext, *ciphertext, *aad, *tag;
-    int encdec;
-    int kn, in, pn, cn;
-    int an = 0;
-    int tn = 0;
-
-    if (!fgets((char *)line, sizeof line, f)) {
-      break;
-    }
-    if (line[0] == '#' || line[0] == '\n') {
-      continue;
-    }
-    p = line;
-    cipher = sstrsep(&p, ":");
-    key = ustrsep(&p, ":");
-    iv = ustrsep(&p, ":");
-    plaintext = ustrsep(&p, ":");
-    ciphertext = ustrsep(&p, ":");
-    if (p[-1] == '\n') {
-      encdec = -1;
-      p[-1] = '\0';
-      tag = aad = NULL;
-      an = tn = 0;
-    } else {
-      aad = ustrsep(&p, ":");
-      tag = ustrsep(&p, ":");
-      if (tag == NULL) {
-        p = (char *)aad;
-        tag = aad = NULL;
-        an = tn = 0;
-      }
-      if (p[-1] == '\n') {
-        encdec = -1;
-        p[-1] = '\0';
-      } else {
-        encdec = atoi(sstrsep(&p, "\n"));
-      }
-    }
-
-    kn = convert(key);
-    in = convert(iv);
-    pn = convert(plaintext);
-    cn = convert(ciphertext);
-    if (aad) {
-      an = convert(aad);
-      tn = convert(tag);
-    }
-
-    if (!test_cipher(cipher, key, kn, iv, in, plaintext, pn, ciphertext, cn,
-                     aad, an, tag, tn, encdec)) {
-      return 3;
-    }
-  }
-  fclose(f);
-
-  printf("PASS\n");
-  return 0;
-}
diff --git a/src/crypto/cipher/cipher_test.cc b/src/crypto/cipher/cipher_test.cc
new file mode 100644
index 0000000..97a84e0
--- /dev/null
+++ b/src/crypto/cipher/cipher_test.cc
@@ -0,0 +1,262 @@
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2015 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <string>
+#include <vector>
+
+#include <openssl/cipher.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+
+#include "../test/file_test.h"
+#include "../test/scoped_types.h"
+#include "../test/stl_compat.h"
+
+
+static const EVP_CIPHER *GetCipher(const std::string &name) {
+  if (name == "DES-CBC") {
+    return EVP_des_cbc();
+  } else if (name == "DES-EDE3-CBC") {
+    return EVP_des_ede3_cbc();
+  } else if (name == "RC4") {
+    return EVP_rc4();
+  } else if (name == "AES-128-ECB") {
+    return EVP_aes_128_ecb();
+  } else if (name == "AES-256-ECB") {
+    return EVP_aes_256_ecb();
+  } else if (name == "AES-128-CBC") {
+    return EVP_aes_128_cbc();
+  } else if (name == "AES-128-GCM") {
+    return EVP_aes_128_gcm();
+  } else if (name == "AES-128-OFB") {
+    return EVP_aes_128_ofb();
+  } else if (name == "AES-192-CBC") {
+    return EVP_aes_192_cbc();
+  } else if (name == "AES-192-ECB") {
+    return EVP_aes_192_ecb();
+  } else if (name == "AES-256-CBC") {
+    return EVP_aes_256_cbc();
+  } else if (name == "AES-128-CTR") {
+    return EVP_aes_128_ctr();
+  } else if (name == "AES-256-CTR") {
+    return EVP_aes_256_ctr();
+  } else if (name == "AES-256-GCM") {
+    return EVP_aes_256_gcm();
+  } else if (name == "AES-256-OFB") {
+    return EVP_aes_256_ofb();
+  }
+  return nullptr;
+}
+
+static bool TestOperation(FileTest *t,
+                          const EVP_CIPHER *cipher,
+                          bool encrypt,
+                          const std::vector<uint8_t> &key,
+                          const std::vector<uint8_t> &iv,
+                          const std::vector<uint8_t> &plaintext,
+                          const std::vector<uint8_t> &ciphertext,
+                          const std::vector<uint8_t> &aad,
+                          const std::vector<uint8_t> &tag) {
+  const std::vector<uint8_t> *in, *out;
+  if (encrypt) {
+    in = &plaintext;
+    out = &ciphertext;
+  } else {
+    in = &ciphertext;
+    out = &plaintext;
+  }
+
+  bool is_aead = EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE;
+
+  ScopedEVP_CIPHER_CTX ctx;
+  if (!EVP_CipherInit_ex(ctx.get(), cipher, nullptr, nullptr, nullptr,
+                         encrypt ? 1 : 0)) {
+    return false;
+  }
+  if (t->HasAttribute("IV")) {
+    if (is_aead) {
+      if (!EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_IVLEN,
+                               iv.size(), 0)) {
+        return false;
+      }
+    } else if (iv.size() != (size_t)EVP_CIPHER_CTX_iv_length(ctx.get())) {
+      t->PrintLine("Bad IV length.");
+      return false;
+    }
+  }
+  if (is_aead && !encrypt &&
+      !EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_TAG, tag.size(),
+                           const_cast<uint8_t*>(bssl::vector_data(&tag)))) {
+    return false;
+  }
+  // The ciphers are run with no padding. For each of the ciphers we test, the
+  // output size matches the input size.
+  std::vector<uint8_t> result(in->size());
+  if (in->size() != out->size()) {
+    t->PrintLine("Input/output size mismatch (%u vs %u).", (unsigned)in->size(),
+                 (unsigned)out->size());
+    return false;
+  }
+  // Note: the deprecated |EVP_CIPHER|-based AES-GCM API is sensitive to whether
+  // parameters are NULL, so it is important to skip the |in| and |aad|
+  // |EVP_CipherUpdate| calls when empty.
+  int unused, result_len1 = 0, result_len2;
+  if (!EVP_CIPHER_CTX_set_key_length(ctx.get(), key.size()) ||
+      !EVP_CipherInit_ex(ctx.get(), nullptr, nullptr, bssl::vector_data(&key),
+                         bssl::vector_data(&iv), -1) ||
+      (!aad.empty() &&
+       !EVP_CipherUpdate(ctx.get(), nullptr, &unused, bssl::vector_data(&aad),
+                         aad.size())) ||
+      !EVP_CIPHER_CTX_set_padding(ctx.get(), 0) ||
+      (!in->empty() &&
+       !EVP_CipherUpdate(ctx.get(), bssl::vector_data(&result), &result_len1,
+                         bssl::vector_data(in), in->size())) ||
+      !EVP_CipherFinal_ex(ctx.get(), bssl::vector_data(&result) + result_len1,
+                          &result_len2)) {
+    t->PrintLine("Operation failed.");
+    return false;
+  }
+  result.resize(result_len1 + result_len2);
+  if (!t->ExpectBytesEqual(bssl::vector_data(out), out->size(),
+                           bssl::vector_data(&result), result.size())) {
+    return false;
+  }
+  if (encrypt && is_aead) {
+    uint8_t rtag[16];
+    if (tag.size() > sizeof(rtag)) {
+      t->PrintLine("Bad tag length.");
+      return false;
+    }
+    if (!EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_GET_TAG, tag.size(),
+                             rtag) ||
+        !t->ExpectBytesEqual(bssl::vector_data(&tag), tag.size(), rtag,
+                             tag.size())) {
+      return false;
+    }
+  }
+  return true;
+}
+
+static bool TestCipher(FileTest *t, void *arg) {
+  std::string cipher_str;
+  if (!t->GetAttribute(&cipher_str, "Cipher")) {
+    return false;
+  }
+  const EVP_CIPHER *cipher = GetCipher(cipher_str);
+  if (cipher == nullptr) {
+    t->PrintLine("Unknown cipher: '%s'.", cipher_str.c_str());
+    return false;
+  }
+
+  std::vector<uint8_t> key, iv, plaintext, ciphertext, aad, tag;
+  if (!t->GetBytes(&key, "Key") ||
+      !t->GetBytes(&plaintext, "Plaintext") ||
+      !t->GetBytes(&ciphertext, "Ciphertext")) {
+    return false;
+  }
+  if (EVP_CIPHER_iv_length(cipher) > 0 &&
+      !t->GetBytes(&iv, "IV")) {
+    return false;
+  }
+  if (EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE) {
+    if (!t->GetBytes(&aad, "AAD") ||
+        !t->GetBytes(&tag, "Tag")) {
+      return false;
+    }
+  }
+
+  enum {
+    kEncrypt,
+    kDecrypt,
+    kBoth,
+  } operation = kBoth;
+  if (t->HasAttribute("Operation")) {
+    const std::string &str = t->GetAttributeOrDie("Operation");
+    if (str == "ENCRYPT") {
+      operation = kEncrypt;
+    } else if (str == "DECRYPT") {
+      operation = kDecrypt;
+    } else {
+      t->PrintLine("Unknown operation: '%s'.", str.c_str());
+      return false;
+    }
+  }
+
+  // By default, both directions are run, unless overridden by the operation.
+  if (operation != kDecrypt &&
+      !TestOperation(t, cipher, true /* encrypt */, key, iv, plaintext,
+                     ciphertext, aad, tag)) {
+    return false;
+  }
+  if (operation != kEncrypt &&
+      !TestOperation(t, cipher, false /* decrypt */, key, iv, plaintext,
+                     ciphertext, aad, tag)) {
+    return false;
+  }
+
+  return true;
+}
+
+int main(int argc, char **argv) {
+  CRYPTO_library_init();
+
+  if (argc != 2) {
+    fprintf(stderr, "%s <test file>\n", argv[0]);
+    return 1;
+  }
+
+  return FileTestMain(TestCipher, nullptr, argv[1]);
+}
diff --git a/src/crypto/cipher/e_aes.c b/src/crypto/cipher/e_aes.c
index eacbd10..41d0aec 100644
--- a/src/crypto/cipher/e_aes.c
+++ b/src/crypto/cipher/e_aes.c
@@ -115,7 +115,7 @@
     (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))
 #include "../arm_arch.h"
 
-#if defined(OPENSSL_ARM) && __ARM_ARCH__ >= 7
+#if defined(OPENSSL_ARM) && __ARM_MAX_ARCH__ >= 7
 #define BSAES
 static char bsaes_capable(void) {
   return CRYPTO_is_NEON_capable();
diff --git a/src/crypto/cipher/internal.h b/src/crypto/cipher/internal.h
index 605b8cb..b2a94f4 100644
--- a/src/crypto/cipher/internal.h
+++ b/src/crypto/cipher/internal.h
@@ -70,8 +70,6 @@
 #define EVP_CIPH_MODE_MASK 0x3f
 
 
-struct evp_aead_ctx_st;
-
 /* EVP_AEAD represents a specific AEAD algorithm. */
 struct evp_aead_st {
   uint8_t key_len;
@@ -79,27 +77,25 @@
   uint8_t overhead;
   uint8_t max_tag_len;
 
-  /* init initialises an |evp_aead_ctx_st|. If this call returns zero then
+  /* init initialises an |EVP_AEAD_CTX|. If this call returns zero then
    * |cleanup| will not be called for that context. */
-  int (*init)(struct evp_aead_ctx_st *, const uint8_t *key,
-              size_t key_len, size_t tag_len);
-  int (*init_with_direction)(struct evp_aead_ctx_st *, const uint8_t *key,
-                             size_t key_len, size_t tag_len,
-                             enum evp_aead_direction_t dir);
-  void (*cleanup)(struct evp_aead_ctx_st *);
+  int (*init)(EVP_AEAD_CTX *, const uint8_t *key, size_t key_len,
+              size_t tag_len);
+  int (*init_with_direction)(EVP_AEAD_CTX *, const uint8_t *key, size_t key_len,
+                             size_t tag_len, enum evp_aead_direction_t dir);
+  void (*cleanup)(EVP_AEAD_CTX *);
 
-  int (*seal)(const struct evp_aead_ctx_st *ctx, uint8_t *out,
-              size_t *out_len, size_t max_out_len, const uint8_t *nonce,
-              size_t nonce_len, const uint8_t *in, size_t in_len,
-              const uint8_t *ad, size_t ad_len);
+  int (*seal)(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
+              size_t max_out_len, const uint8_t *nonce, size_t nonce_len,
+              const uint8_t *in, size_t in_len, const uint8_t *ad,
+              size_t ad_len);
 
-  int (*open)(const struct evp_aead_ctx_st *ctx, uint8_t *out,
-              size_t *out_len, size_t max_out_len, const uint8_t *nonce,
-              size_t nonce_len, const uint8_t *in, size_t in_len,
-              const uint8_t *ad, size_t ad_len);
+  int (*open)(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
+              size_t max_out_len, const uint8_t *nonce, size_t nonce_len,
+              const uint8_t *in, size_t in_len, const uint8_t *ad,
+              size_t ad_len);
 
-  int (*get_rc4_state)(const struct evp_aead_ctx_st *ctx,
-                       const RC4_KEY **out_key);
+  int (*get_rc4_state)(const EVP_AEAD_CTX *ctx, const RC4_KEY **out_key);
 };
 
 
diff --git a/src/crypto/cipher/test/cipher_test.txt b/src/crypto/cipher/test/cipher_test.txt
index f3c6d35..93cb8f3 100644
--- a/src/crypto/cipher/test/cipher_test.txt
+++ b/src/crypto/cipher/test/cipher_test.txt
@@ -1,118 +1,537 @@
 # RC4 tests (from rc4test)
-RC4:0123456789abcdef0123456789abcdef::0123456789abcdef:75b7878099e0c596
-RC4:0123456789abcdef0123456789abcdef::0000000000000000:7494c2e7104b0879
-RC4:00000000000000000000000000000000::0000000000000000:de188941a3375d3a
-RC4:ef012345ef012345ef012345ef012345::0000000000000000000000000000000000000000:d6a141a7ec3c38dfbd615a1162e1c7ba36b67858
-RC4:0123456789abcdef0123456789abcdef::123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345678:66a0949f8af7d6891f7f832ba833c00c892ebe30143ce28740011ecf
-RC4:ef012345ef012345ef012345ef012345::00000000000000000000:d6a141a7ec3c38dfbd61
+Cipher = RC4
+Key = 0123456789abcdef0123456789abcdef
+Plaintext = 0123456789abcdef
+Ciphertext = 75b7878099e0c596
+
+Cipher = RC4
+Key = 0123456789abcdef0123456789abcdef
+Plaintext = 0000000000000000
+Ciphertext = 7494c2e7104b0879
+
+Cipher = RC4
+Key = 00000000000000000000000000000000
+Plaintext = 0000000000000000
+Ciphertext = de188941a3375d3a
+
+Cipher = RC4
+Key = ef012345ef012345ef012345ef012345
+Plaintext = 0000000000000000000000000000000000000000
+Ciphertext = d6a141a7ec3c38dfbd615a1162e1c7ba36b67858
+
+Cipher = RC4
+Key = 0123456789abcdef0123456789abcdef
+Plaintext = 123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345678
+Ciphertext = 66a0949f8af7d6891f7f832ba833c00c892ebe30143ce28740011ecf
+
+Cipher = RC4
+Key = ef012345ef012345ef012345ef012345
+Plaintext = 00000000000000000000
+Ciphertext = d6a141a7ec3c38dfbd61
+
 
 # DES EDE3 CBC tests (from destest)
-DES-EDE3-CBC:0123456789abcdeff1e0d3c2b5a49786fedcba9876543210:fedcba9876543210:37363534333231204E6F77206973207468652074696D6520666F722000000000:3FE301C962AC01D02213763C1CBD4CDC799657C064ECF5D41C673812CFDE9675
+Cipher = DES-EDE3-CBC
+Key = 0123456789abcdeff1e0d3c2b5a49786fedcba9876543210
+IV = fedcba9876543210
+Plaintext = 37363534333231204E6F77206973207468652074696D6520666F722000000000
+Ciphertext = 3FE301C962AC01D02213763C1CBD4CDC799657C064ECF5D41C673812CFDE9675
+
 
 # AES 128 ECB tests (from FIPS-197 test vectors, encrypt)
-AES-128-ECB:000102030405060708090A0B0C0D0E0F::00112233445566778899AABBCCDDEEFF:69C4E0D86A7B0430D8CDB78070B4C55A:1
+Cipher = AES-128-ECB
+Key = 000102030405060708090A0B0C0D0E0F
+Operation = ENCRYPT
+Plaintext = 00112233445566778899AABBCCDDEEFF
+Ciphertext = 69C4E0D86A7B0430D8CDB78070B4C55A
+
 
 # AES 256 ECB tests (from FIPS-197 test vectors, encrypt)
-AES-256-ECB:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF:8EA2B7CA516745BFEAFC49904B496089:1
+Cipher = AES-256-ECB
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Operation = ENCRYPT
+Plaintext = 00112233445566778899AABBCCDDEEFF
+Ciphertext = 8EA2B7CA516745BFEAFC49904B496089
 
-# AES 128 CBC tests (from NIST test vectors, decrypt)
 
 # AES tests from NIST document SP800-38A
 # For all ECB encrypts and decrypts, the transformed sequence is
 #   AES-bits-ECB:key::plaintext:ciphertext:encdec
 # ECB-AES128.Encrypt and ECB-AES128.Decrypt
-AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::6BC1BEE22E409F96E93D7E117393172A:3AD77BB40D7A3660A89ECAF32466EF97
-AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::AE2D8A571E03AC9C9EB76FAC45AF8E51:F5D3D58503B9699DE785895A96FDBAAF
-AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::30C81C46A35CE411E5FBC1191A0A52EF:43B1CD7F598ECE23881B00E3ED030688
-AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::F69F2445DF4F9B17AD2B417BE66C3710:7B0C785E27E8AD3F8223207104725DD4
+Cipher = AES-128-ECB
+Key = 2B7E151628AED2A6ABF7158809CF4F3C
+Plaintext = 6BC1BEE22E409F96E93D7E117393172A
+Ciphertext = 3AD77BB40D7A3660A89ECAF32466EF97
+
+Cipher = AES-128-ECB
+Key = 2B7E151628AED2A6ABF7158809CF4F3C
+Plaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51
+Ciphertext = F5D3D58503B9699DE785895A96FDBAAF
+
+Cipher = AES-128-ECB
+Key = 2B7E151628AED2A6ABF7158809CF4F3C
+Plaintext = 30C81C46A35CE411E5FBC1191A0A52EF
+Ciphertext = 43B1CD7F598ECE23881B00E3ED030688
+
+Cipher = AES-128-ECB
+Key = 2B7E151628AED2A6ABF7158809CF4F3C
+Plaintext = F69F2445DF4F9B17AD2B417BE66C3710
+Ciphertext = 7B0C785E27E8AD3F8223207104725DD4
+
+
 # ECB-AES256.Encrypt and ECB-AES256.Decrypt
-AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::6BC1BEE22E409F96E93D7E117393172A:F3EED1BDB5D2A03C064B5A7E3DB181F8
-AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::AE2D8A571E03AC9C9EB76FAC45AF8E51:591CCB10D410ED26DC5BA74A31362870
-AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::30C81C46A35CE411E5FBC1191A0A52EF:B6ED21B99CA6F4F9F153E7B1BEAFED1D
-AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::F69F2445DF4F9B17AD2B417BE66C3710:23304B7A39F9F3FF067D8D8F9E24ECC7
+Cipher = AES-256-ECB
+Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4
+Plaintext = 6BC1BEE22E409F96E93D7E117393172A
+Ciphertext = F3EED1BDB5D2A03C064B5A7E3DB181F8
+
+Cipher = AES-256-ECB
+Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4
+Plaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51
+Ciphertext = 591CCB10D410ED26DC5BA74A31362870
+
+Cipher = AES-256-ECB
+Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4
+Plaintext = 30C81C46A35CE411E5FBC1191A0A52EF
+Ciphertext = B6ED21B99CA6F4F9F153E7B1BEAFED1D
+
+Cipher = AES-256-ECB
+Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4
+Plaintext = F69F2445DF4F9B17AD2B417BE66C3710
+Ciphertext = 23304B7A39F9F3FF067D8D8F9E24ECC7
+
+
 # For all CBC encrypts and decrypts, the transformed sequence is
 #   AES-bits-CBC:key:IV/ciphertext':plaintext:ciphertext:encdec
 # CBC-AES128.Encrypt and CBC-AES128.Decrypt
-AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:7649ABAC8119B246CEE98E9B12E9197D
-AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:7649ABAC8119B246CEE98E9B12E9197D:AE2D8A571E03AC9C9EB76FAC45AF8E51:5086CB9B507219EE95DB113A917678B2
-AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:5086CB9B507219EE95DB113A917678B2:30C81C46A35CE411E5FBC1191A0A52EF:73BED6B8E3C1743B7116E69E22229516
-AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:73BED6B8E3C1743B7116E69E22229516:F69F2445DF4F9B17AD2B417BE66C3710:3FF1CAA1681FAC09120ECA307586E1A7
+Cipher = AES-128-CBC
+Key = 2B7E151628AED2A6ABF7158809CF4F3C
+IV = 000102030405060708090A0B0C0D0E0F
+Plaintext = 6BC1BEE22E409F96E93D7E117393172A
+Ciphertext = 7649ABAC8119B246CEE98E9B12E9197D
+
+Cipher = AES-128-CBC
+Key = 2B7E151628AED2A6ABF7158809CF4F3C
+IV = 7649ABAC8119B246CEE98E9B12E9197D
+Plaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51
+Ciphertext = 5086CB9B507219EE95DB113A917678B2
+
+Cipher = AES-128-CBC
+Key = 2B7E151628AED2A6ABF7158809CF4F3C
+IV = 5086CB9B507219EE95DB113A917678B2
+Plaintext = 30C81C46A35CE411E5FBC1191A0A52EF
+Ciphertext = 73BED6B8E3C1743B7116E69E22229516
+
+Cipher = AES-128-CBC
+Key = 2B7E151628AED2A6ABF7158809CF4F3C
+IV = 73BED6B8E3C1743B7116E69E22229516
+Plaintext = F69F2445DF4F9B17AD2B417BE66C3710
+Ciphertext = 3FF1CAA1681FAC09120ECA307586E1A7
+
+
 # CBC-AES256.Encrypt and CBC-AES256.Decrypt
-AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:F58C4C04D6E5F1BA779EABFB5F7BFBD6
-AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:F58C4C04D6E5F1BA779EABFB5F7BFBD6:AE2D8A571E03AC9C9EB76FAC45AF8E51:9CFC4E967EDB808D679F777BC6702C7D
-AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:9CFC4E967EDB808D679F777BC6702C7D:30C81C46A35CE411E5FBC1191A0A52EF:39F23369A9D9BACFA530E26304231461
-AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39F23369A9D9BACFA530E26304231461:F69F2445DF4F9B17AD2B417BE66C3710:B2EB05E2C39BE9FCDA6C19078C6A9D1B
+Cipher = AES-256-CBC
+Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4
+IV = 000102030405060708090A0B0C0D0E0F
+Plaintext = 6BC1BEE22E409F96E93D7E117393172A
+Ciphertext = F58C4C04D6E5F1BA779EABFB5F7BFBD6
+
+Cipher = AES-256-CBC
+Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4
+IV = F58C4C04D6E5F1BA779EABFB5F7BFBD6
+Plaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51
+Ciphertext = 9CFC4E967EDB808D679F777BC6702C7D
+
+Cipher = AES-256-CBC
+Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4
+IV = 9CFC4E967EDB808D679F777BC6702C7D
+Plaintext = 30C81C46A35CE411E5FBC1191A0A52EF
+Ciphertext = 39F23369A9D9BACFA530E26304231461
+
+Cipher = AES-256-CBC
+Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4
+IV = 39F23369A9D9BACFA530E26304231461
+Plaintext = F69F2445DF4F9B17AD2B417BE66C3710
+Ciphertext = B2EB05E2C39BE9FCDA6C19078C6A9D1B
+
 
 # AES Counter test vectors from RFC3686
-AES-128-CTR:AE6852F8121067CC4BF7A5765577F39E:00000030000000000000000000000001:53696E676C6520626C6F636B206D7367:E4095D4FB7A7B3792D6175A3261311B8:1
-AES-128-CTR:7E24067817FAE0D743D6CE1F32539163:006CB6DBC0543B59DA48D90B00000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:5104A106168A72D9790D41EE8EDAD388EB2E1EFC46DA57C8FCE630DF9141BE28:1
-AES-128-CTR:7691BE035E5020A8AC6E618529F9A0DC:00E0017B27777F3F4A1786F000000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:C1CF48A89F2FFDD9CF4652E9EFDB72D74540A42BDE6D7836D59A5CEAAEF3105325B2072F:1
+Cipher = AES-128-CTR
+Key = AE6852F8121067CC4BF7A5765577F39E
+IV = 00000030000000000000000000000001
+Operation = ENCRYPT
+Plaintext = 53696E676C6520626C6F636B206D7367
+Ciphertext = E4095D4FB7A7B3792D6175A3261311B8
 
-AES-256-CTR:776BEFF2851DB06F4C8A0542C8696F6C6A81AF1EEC96B4D37FC1D689E6C1C104:00000060DB5672C97AA8F0B200000001:53696E676C6520626C6F636B206D7367:145AD01DBF824EC7560863DC71E3E0C0:1
-AES-256-CTR:F6D66D6BD52D59BB0796365879EFF886C66DD51A5B6A99744B50590C87A23884:00FAAC24C1585EF15A43D87500000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:F05E231B3894612C49EE000B804EB2A9B8306B508F839D6A5530831D9344AF1C:1
-AES-256-CTR:FF7A617CE69148E4F1726E2F43581DE2AA62D9F805532EDFF1EED687FB54153D:001CC5B751A51D70A1C1114800000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:EB6C52821D0BBBF7CE7594462ACA4FAAB407DF866569FD07F48CC0B583D6071F1EC0E6B8:1
+Cipher = AES-128-CTR
+Key = 7E24067817FAE0D743D6CE1F32539163
+IV = 006CB6DBC0543B59DA48D90B00000001
+Operation = ENCRYPT
+Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Ciphertext = 5104A106168A72D9790D41EE8EDAD388EB2E1EFC46DA57C8FCE630DF9141BE28
+
+Cipher = AES-128-CTR
+Key = 7691BE035E5020A8AC6E618529F9A0DC
+IV = 00E0017B27777F3F4A1786F000000001
+Operation = ENCRYPT
+Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223
+Ciphertext = C1CF48A89F2FFDD9CF4652E9EFDB72D74540A42BDE6D7836D59A5CEAAEF3105325B2072F
+
+Cipher = AES-256-CTR
+Key = 776BEFF2851DB06F4C8A0542C8696F6C6A81AF1EEC96B4D37FC1D689E6C1C104
+IV = 00000060DB5672C97AA8F0B200000001
+Operation = ENCRYPT
+Plaintext = 53696E676C6520626C6F636B206D7367
+Ciphertext = 145AD01DBF824EC7560863DC71E3E0C0
+
+Cipher = AES-256-CTR
+Key = F6D66D6BD52D59BB0796365879EFF886C66DD51A5B6A99744B50590C87A23884
+IV = 00FAAC24C1585EF15A43D87500000001
+Operation = ENCRYPT
+Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Ciphertext = F05E231B3894612C49EE000B804EB2A9B8306B508F839D6A5530831D9344AF1C
+
+Cipher = AES-256-CTR
+Key = FF7A617CE69148E4F1726E2F43581DE2AA62D9F805532EDFF1EED687FB54153D
+IV = 001CC5B751A51D70A1C1114800000001
+Operation = ENCRYPT
+Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223
+Ciphertext = EB6C52821D0BBBF7CE7594462ACA4FAAB407DF866569FD07F48CC0B583D6071F1EC0E6B8
+
 
 # AES GCM test vectors from http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf
-AES-128-GCM:00000000000000000000000000000000:000000000000000000000000::::58e2fccefa7e3061367f1d57a4e7455a
-AES-128-GCM:00000000000000000000000000000000:000000000000000000000000:00000000000000000000000000000000:0388dace60b6a392f328c2b971b2fe78::ab6e47d42cec13bdf53a67b21257bddf
-AES-128-GCM:feffe9928665731c6d6a8f9467308308:cafebabefacedbaddecaf888:d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255:42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f5985::4d5c2af327cd64a62cf35abd2ba6fab4
-AES-128-GCM:feffe9928665731c6d6a8f9467308308:cafebabefacedbaddecaf888:d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39:42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091:feedfacedeadbeeffeedfacedeadbeefabaddad2:5bc94fbc3221a5db94fae95ae7121a47
-AES-128-GCM:feffe9928665731c6d6a8f9467308308:cafebabefacedbad:d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39:61353b4c2806934a777ff51fa22a4755699b2a714fcdc6f83766e5f97b6c742373806900e49f24b22b097544d4896b424989b5e1ebac0f07c23f4598:feedfacedeadbeeffeedfacedeadbeefabaddad2:3612d2e79e3b0785561be14aaca2fccb
-AES-128-GCM:feffe9928665731c6d6a8f9467308308:9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b:d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39:8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5:feedfacedeadbeeffeedfacedeadbeefabaddad2:619cc5aefffe0bfa462af43c1699d050
-AES-256-GCM:0000000000000000000000000000000000000000000000000000000000000000:000000000000000000000000::::530f8afbc74536b9a963b4f1c4cb738b
-AES-256-GCM:0000000000000000000000000000000000000000000000000000000000000000:000000000000000000000000:00000000000000000000000000000000:cea7403d4d606b6e074ec5d3baf39d18::d0d1c8a799996bf0265b98b5d48ab919
-AES-256-GCM:feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308:cafebabefacedbaddecaf888:d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255:522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad::b094dac5d93471bdec1a502270e3cc6c
-AES-256-GCM:feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308:cafebabefacedbaddecaf888:d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39:522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662:feedfacedeadbeeffeedfacedeadbeefabaddad2:76fc6ece0f4e1768cddf8853bb2d551b
-AES-256-GCM:feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308:cafebabefacedbad:d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39:c3762df1ca787d32ae47c13bf19844cbaf1ae14d0b976afac52ff7d79bba9de0feb582d33934a4f0954cc2363bc73f7862ac430e64abe499f47c9b1f:feedfacedeadbeeffeedfacedeadbeefabaddad2:3a337dbf46a792c45e454913fe2ea8f2
-AES-256-GCM:feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308:9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b:d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39:5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf40fc0c3b780f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3f:feedfacedeadbeeffeedfacedeadbeefabaddad2:a44a8266ee1c8eb0c8b5d4cf5ae9f19a
+Cipher = AES-128-GCM
+Key = 00000000000000000000000000000000
+IV = 000000000000000000000000
+Plaintext =
+Ciphertext =
+AAD =
+Tag = 58e2fccefa7e3061367f1d57a4e7455a
+
+Cipher = AES-128-GCM
+Key = 00000000000000000000000000000000
+IV = 000000000000000000000000
+Plaintext = 00000000000000000000000000000000
+Ciphertext = 0388dace60b6a392f328c2b971b2fe78
+AAD =
+Tag = ab6e47d42cec13bdf53a67b21257bddf
+
+Cipher = AES-128-GCM
+Key = feffe9928665731c6d6a8f9467308308
+IV = cafebabefacedbaddecaf888
+Plaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255
+Ciphertext = 42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f5985
+AAD =
+Tag = 4d5c2af327cd64a62cf35abd2ba6fab4
+
+Cipher = AES-128-GCM
+Key = feffe9928665731c6d6a8f9467308308
+IV = cafebabefacedbaddecaf888
+Plaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+Ciphertext = 42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091
+AAD = feedfacedeadbeeffeedfacedeadbeefabaddad2
+Tag = 5bc94fbc3221a5db94fae95ae7121a47
+
+Cipher = AES-128-GCM
+Key = feffe9928665731c6d6a8f9467308308
+IV = cafebabefacedbad
+Plaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+Ciphertext = 61353b4c2806934a777ff51fa22a4755699b2a714fcdc6f83766e5f97b6c742373806900e49f24b22b097544d4896b424989b5e1ebac0f07c23f4598
+AAD = feedfacedeadbeeffeedfacedeadbeefabaddad2
+Tag = 3612d2e79e3b0785561be14aaca2fccb
+
+Cipher = AES-128-GCM
+Key = feffe9928665731c6d6a8f9467308308
+IV = 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b
+Plaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+Ciphertext = 8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5
+AAD = feedfacedeadbeeffeedfacedeadbeefabaddad2
+Tag = 619cc5aefffe0bfa462af43c1699d050
+
+Cipher = AES-256-GCM
+Key = 0000000000000000000000000000000000000000000000000000000000000000
+IV = 000000000000000000000000
+Plaintext =
+Ciphertext =
+AAD =
+Tag = 530f8afbc74536b9a963b4f1c4cb738b
+
+Cipher = AES-256-GCM
+Key = 0000000000000000000000000000000000000000000000000000000000000000
+IV = 000000000000000000000000
+Plaintext = 00000000000000000000000000000000
+Ciphertext = cea7403d4d606b6e074ec5d3baf39d18
+AAD =
+Tag = d0d1c8a799996bf0265b98b5d48ab919
+
+Cipher = AES-256-GCM
+Key = feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308
+IV = cafebabefacedbaddecaf888
+Plaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255
+Ciphertext = 522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad
+AAD =
+Tag = b094dac5d93471bdec1a502270e3cc6c
+
+Cipher = AES-256-GCM
+Key = feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308
+IV = cafebabefacedbaddecaf888
+Plaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+Ciphertext = 522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662
+AAD = feedfacedeadbeeffeedfacedeadbeefabaddad2
+Tag = 76fc6ece0f4e1768cddf8853bb2d551b
+
+Cipher = AES-256-GCM
+Key = feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308
+IV = cafebabefacedbad
+Plaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+Ciphertext = c3762df1ca787d32ae47c13bf19844cbaf1ae14d0b976afac52ff7d79bba9de0feb582d33934a4f0954cc2363bc73f7862ac430e64abe499f47c9b1f
+AAD = feedfacedeadbeeffeedfacedeadbeefabaddad2
+Tag = 3a337dbf46a792c45e454913fe2ea8f2
+
+Cipher = AES-256-GCM
+Key = feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308
+IV = 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b
+Plaintext = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+Ciphertext = 5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf40fc0c3b780f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3f
+AAD = feedfacedeadbeeffeedfacedeadbeefabaddad2
+Tag = a44a8266ee1c8eb0c8b5d4cf5ae9f19a
+
 # local add-ons, primarily streaming ghash tests
 # 128 bytes aad
-AES-128-GCM:00000000000000000000000000000000:000000000000000000000000:::d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad:5fea793a2d6f974d37e68e0cb8ff9492
+Cipher = AES-128-GCM
+Key = 00000000000000000000000000000000
+IV = 000000000000000000000000
+Plaintext =
+Ciphertext =
+AAD = d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad
+Tag = 5fea793a2d6f974d37e68e0cb8ff9492
+
 # 48 bytes plaintext
-AES-128-GCM:00000000000000000000000000000000:000000000000000000000000:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0::9dd0a376b08e40eb00c35f29f9ea61a4
+Cipher = AES-128-GCM
+Key = 00000000000000000000000000000000
+IV = 000000000000000000000000
+Plaintext = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Ciphertext = 0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0
+AAD =
+Tag = 9dd0a376b08e40eb00c35f29f9ea61a4
+
 # 80 bytes plaintext
-AES-128-GCM:00000000000000000000000000000000:000000000000000000000000:0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0c94da219118e297d7b7ebcbcc9c388f28ade7d85a8ee35616f7124a9d5270291::98885a3a22bd4742fe7b72172193b163
+Cipher = AES-128-GCM
+Key = 00000000000000000000000000000000
+IV = 000000000000000000000000
+Plaintext = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Ciphertext = 0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0c94da219118e297d7b7ebcbcc9c388f28ade7d85a8ee35616f7124a9d5270291
+AAD =
+Tag = 98885a3a22bd4742fe7b72172193b163
+
 # 128 bytes plaintext
-AES-128-GCM:00000000000000000000000000000000:000000000000000000000000:0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0c94da219118e297d7b7ebcbcc9c388f28ade7d85a8ee35616f7124a9d527029195b84d1b96c690ff2f2de30bf2ec89e00253786e126504f0dab90c48a30321de3345e6b0461e7c9e6c6b7afedde83f40::cac45f60e31efd3b5a43b98a22ce1aa1
+Cipher = AES-128-GCM
+Key = 00000000000000000000000000000000
+IV = 000000000000000000000000
+Plaintext = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Ciphertext = 0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0c94da219118e297d7b7ebcbcc9c388f28ade7d85a8ee35616f7124a9d527029195b84d1b96c690ff2f2de30bf2ec89e00253786e126504f0dab90c48a30321de3345e6b0461e7c9e6c6b7afedde83f40
+AAD =
+Tag = cac45f60e31efd3b5a43b98a22ce1aa1
+
 # 192 bytes plaintext, iv is chosen so that initial counter LSB is 0xFF
-AES-128-GCM:00000000000000000000000000000000:ffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:56b3373ca9ef6e4a2b64fe1e9a17b61425f10d47a75a5fce13efc6bc784af24f4141bdd48cf7c770887afd573cca5418a9aeffcd7c5ceddfc6a78397b9a85b499da558257267caab2ad0b23ca476a53cb17fb41c4b8b475cb4f3f7165094c229c9e8c4dc0a2a5ff1903e501511221376a1cdb8364c5061a20cae74bc4acd76ceb0abc9fd3217ef9f8c90be402ddf6d8697f4f880dff15bfb7a6b28241ec8fe183c2d59e3f9dfff653c7126f0acb9e64211f42bae12af462b1070bef1ab5e3606::566f8ef683078bfdeeffa869d751a017
+Cipher = AES-128-GCM
+Key = 00000000000000000000000000000000
+IV = ffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Plaintext = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Ciphertext = 56b3373ca9ef6e4a2b64fe1e9a17b61425f10d47a75a5fce13efc6bc784af24f4141bdd48cf7c770887afd573cca5418a9aeffcd7c5ceddfc6a78397b9a85b499da558257267caab2ad0b23ca476a53cb17fb41c4b8b475cb4f3f7165094c229c9e8c4dc0a2a5ff1903e501511221376a1cdb8364c5061a20cae74bc4acd76ceb0abc9fd3217ef9f8c90be402ddf6d8697f4f880dff15bfb7a6b28241ec8fe183c2d59e3f9dfff653c7126f0acb9e64211f42bae12af462b1070bef1ab5e3606
+AAD =
+Tag = 566f8ef683078bfdeeffa869d751a017
+
 # 288 bytes plaintext, iv is chosen so that initial counter LSB is 0xFF
-AES-128-GCM:00000000000000000000000000000000:ffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:56b3373ca9ef6e4a2b64fe1e9a17b61425f10d47a75a5fce13efc6bc784af24f4141bdd48cf7c770887afd573cca5418a9aeffcd7c5ceddfc6a78397b9a85b499da558257267caab2ad0b23ca476a53cb17fb41c4b8b475cb4f3f7165094c229c9e8c4dc0a2a5ff1903e501511221376a1cdb8364c5061a20cae74bc4acd76ceb0abc9fd3217ef9f8c90be402ddf6d8697f4f880dff15bfb7a6b28241ec8fe183c2d59e3f9dfff653c7126f0acb9e64211f42bae12af462b1070bef1ab5e3606872ca10dee15b3249b1a1b958f23134c4bccb7d03200bce420a2f8eb66dcf3644d1423c1b5699003c13ecef4bf38a3b60eedc34033bac1902783dc6d89e2e774188a439c7ebcc0672dbda4ddcfb2794613b0be41315ef778708a70ee7d75165c::8b307f6b33286d0ab026a9ed3fe1e85f
+Cipher = AES-128-GCM
+Key = 00000000000000000000000000000000
+IV = ffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Plaintext = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Ciphertext = 56b3373ca9ef6e4a2b64fe1e9a17b61425f10d47a75a5fce13efc6bc784af24f4141bdd48cf7c770887afd573cca5418a9aeffcd7c5ceddfc6a78397b9a85b499da558257267caab2ad0b23ca476a53cb17fb41c4b8b475cb4f3f7165094c229c9e8c4dc0a2a5ff1903e501511221376a1cdb8364c5061a20cae74bc4acd76ceb0abc9fd3217ef9f8c90be402ddf6d8697f4f880dff15bfb7a6b28241ec8fe183c2d59e3f9dfff653c7126f0acb9e64211f42bae12af462b1070bef1ab5e3606872ca10dee15b3249b1a1b958f23134c4bccb7d03200bce420a2f8eb66dcf3644d1423c1b5699003c13ecef4bf38a3b60eedc34033bac1902783dc6d89e2e774188a439c7ebcc0672dbda4ddcfb2794613b0be41315ef778708a70ee7d75165c
+AAD =
+Tag = 8b307f6b33286d0ab026a9ed3fe1e85f
+
 # 80 bytes plaintext, submitted by Intel
-AES-128-GCM:843ffcf5d2b72694d19ed01d01249412:dbcca32ebf9b804617c3aa9e:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f:6268c6fa2a80b2d137467f092f657ac04d89be2beaa623d61b5a868c8f03ff95d3dcee23ad2f1ab3a6c80eaf4b140eb05de3457f0fbc111a6b43d0763aa422a3013cf1dc37fe417d1fbfc449b75d4cc5:00000000000000000000000000000000101112131415161718191a1b1c1d1e1f:3b629ccfbc1119b7319e1dce2cd6fd6d
+Cipher = AES-128-GCM
+Key = 843ffcf5d2b72694d19ed01d01249412
+IV = dbcca32ebf9b804617c3aa9e
+Plaintext = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f
+Ciphertext = 6268c6fa2a80b2d137467f092f657ac04d89be2beaa623d61b5a868c8f03ff95d3dcee23ad2f1ab3a6c80eaf4b140eb05de3457f0fbc111a6b43d0763aa422a3013cf1dc37fe417d1fbfc449b75d4cc5
+AAD = 00000000000000000000000000000000101112131415161718191a1b1c1d1e1f
+Tag = 3b629ccfbc1119b7319e1dce2cd6fd6d
+
 
 # OFB tests from OpenSSL upstream.
-AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:1
-AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:7789508D16918F03F53C52DAC54ED825:1
-AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:9740051E9C5FECF64344F7A82260EDCC:1
-AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:304C6528F659C77866A510D9C1D6AE5E:1
+
+# OFB-AES128.Encrypt
+Cipher = AES-128-OFB
+Key = 2B7E151628AED2A6ABF7158809CF4F3C
+IV = 000102030405060708090A0B0C0D0E0F
+Operation = ENCRYPT
+Plaintext = 6BC1BEE22E409F96E93D7E117393172A
+Ciphertext = 3B3FD92EB72DAD20333449F8E83CFB4A
+
+Cipher = AES-128-OFB
+Key = 2B7E151628AED2A6ABF7158809CF4F3C
+IV = 50FE67CC996D32B6DA0937E99BAFEC60
+Operation = ENCRYPT
+Plaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51
+Ciphertext = 7789508D16918F03F53C52DAC54ED825
+
+Cipher = AES-128-OFB
+Key = 2B7E151628AED2A6ABF7158809CF4F3C
+IV = D9A4DADA0892239F6B8B3D7680E15674
+Operation = ENCRYPT
+Plaintext = 30C81C46A35CE411E5FBC1191A0A52EF
+Ciphertext = 9740051E9C5FECF64344F7A82260EDCC
+
+Cipher = AES-128-OFB
+Key = 2B7E151628AED2A6ABF7158809CF4F3C
+IV = A78819583F0308E7A6BF36B1386ABF23
+Operation = ENCRYPT
+Plaintext = F69F2445DF4F9B17AD2B417BE66C3710
+Ciphertext = 304C6528F659C77866A510D9C1D6AE5E
+
 # OFB-AES128.Decrypt
-AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:0
-AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:7789508D16918F03F53C52DAC54ED825:0
-AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:9740051E9C5FECF64344F7A82260EDCC:0
-AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:304C6528F659C77866A510D9C1D6AE5E:0
+Cipher = AES-128-OFB
+Key = 2B7E151628AED2A6ABF7158809CF4F3C
+IV = 000102030405060708090A0B0C0D0E0F
+Operation = DECRYPT
+Plaintext = 6BC1BEE22E409F96E93D7E117393172A
+Ciphertext = 3B3FD92EB72DAD20333449F8E83CFB4A
+
+Cipher = AES-128-OFB
+Key = 2B7E151628AED2A6ABF7158809CF4F3C
+IV = 50FE67CC996D32B6DA0937E99BAFEC60
+Operation = DECRYPT
+Plaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51
+Ciphertext = 7789508D16918F03F53C52DAC54ED825
+
+Cipher = AES-128-OFB
+Key = 2B7E151628AED2A6ABF7158809CF4F3C
+IV = D9A4DADA0892239F6B8B3D7680E15674
+Operation = DECRYPT
+Plaintext = 30C81C46A35CE411E5FBC1191A0A52EF
+Ciphertext = 9740051E9C5FECF64344F7A82260EDCC
+
+Cipher = AES-128-OFB
+Key = 2B7E151628AED2A6ABF7158809CF4F3C
+IV = A78819583F0308E7A6BF36B1386ABF23
+Operation = DECRYPT
+Plaintext = F69F2445DF4F9B17AD2B417BE66C3710
+Ciphertext = 304C6528F659C77866A510D9C1D6AE5E
+
 # OFB-AES256.Encrypt
-AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:1
-AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:4FEBDC6740D20B3AC88F6AD82A4FB08D:1
-AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:71AB47A086E86EEDF39D1C5BBA97C408:1
-AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0126141D67F37BE8538F5A8BE740E484:1
+Cipher = AES-256-OFB
+Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4
+IV = 000102030405060708090A0B0C0D0E0F
+Operation = ENCRYPT
+Plaintext = 6BC1BEE22E409F96E93D7E117393172A
+Ciphertext = DC7E84BFDA79164B7ECD8486985D3860
+
+Cipher = AES-256-OFB
+Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4
+IV = B7BF3A5DF43989DD97F0FA97EBCE2F4A
+Operation = ENCRYPT
+Plaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51
+Ciphertext = 4FEBDC6740D20B3AC88F6AD82A4FB08D
+
+Cipher = AES-256-OFB
+Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4
+IV = E1C656305ED1A7A6563805746FE03EDC
+Operation = ENCRYPT
+Plaintext = 30C81C46A35CE411E5FBC1191A0A52EF
+Ciphertext = 71AB47A086E86EEDF39D1C5BBA97C408
+
+Cipher = AES-256-OFB
+Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4
+IV = 41635BE625B48AFC1666DD42A09D96E7
+Operation = ENCRYPT
+Plaintext = F69F2445DF4F9B17AD2B417BE66C3710
+Ciphertext = 0126141D67F37BE8538F5A8BE740E484
+
+
 # OFB-AES256.Decrypt
-AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:0
-AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:4FEBDC6740D20B3AC88F6AD82A4FB08D:0
-AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:71AB47A086E86EEDF39D1C5BBA97C408:0
-AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0126141D67F37BE8538F5A8BE740E484:0
+Cipher = AES-256-OFB
+Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4
+IV = 000102030405060708090A0B0C0D0E0F
+Operation = DECRYPT
+Plaintext = 6BC1BEE22E409F96E93D7E117393172A
+Ciphertext = DC7E84BFDA79164B7ECD8486985D3860
+
+Cipher = AES-256-OFB
+Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4
+IV = B7BF3A5DF43989DD97F0FA97EBCE2F4A
+Operation = DECRYPT
+Plaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51
+Ciphertext = 4FEBDC6740D20B3AC88F6AD82A4FB08D
+
+Cipher = AES-256-OFB
+Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4
+IV = E1C656305ED1A7A6563805746FE03EDC
+Operation = DECRYPT
+Plaintext = 30C81C46A35CE411E5FBC1191A0A52EF
+Ciphertext = 71AB47A086E86EEDF39D1C5BBA97C408
+
+Cipher = AES-256-OFB
+Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4
+IV = 41635BE625B48AFC1666DD42A09D96E7
+Operation = DECRYPT
+Plaintext = F69F2445DF4F9B17AD2B417BE66C3710
+Ciphertext = 0126141D67F37BE8538F5A8BE740E484
+
 
 # AES-192 CBC-mode test from upstream OpenSSL.
-AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:4F021DB243BC633D7178183A9FA071E8
-AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:4F021DB243BC633D7178183A9FA071E8:AE2D8A571E03AC9C9EB76FAC45AF8E51:B4D9ADA9AD7DEDF4E5E738763F69145A
-AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:B4D9ADA9AD7DEDF4E5E738763F69145A:30C81C46A35CE411E5FBC1191A0A52EF:571B242012FB7AE07FA9BAAC3DF102E0
-AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:571B242012FB7AE07FA9BAAC3DF102E0:F69F2445DF4F9B17AD2B417BE66C3710:08B0E27988598881D920A9E64F5615CD
+Cipher = AES-192-CBC
+Key = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B
+IV = 000102030405060708090A0B0C0D0E0F
+Plaintext = 6BC1BEE22E409F96E93D7E117393172A
+Ciphertext = 4F021DB243BC633D7178183A9FA071E8
+
+Cipher = AES-192-CBC
+Key = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B
+IV = 4F021DB243BC633D7178183A9FA071E8
+Plaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51
+Ciphertext = B4D9ADA9AD7DEDF4E5E738763F69145A
+
+Cipher = AES-192-CBC
+Key = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B
+IV = B4D9ADA9AD7DEDF4E5E738763F69145A
+Plaintext = 30C81C46A35CE411E5FBC1191A0A52EF
+Ciphertext = 571B242012FB7AE07FA9BAAC3DF102E0
+
+Cipher = AES-192-CBC
+Key = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B
+IV = 571B242012FB7AE07FA9BAAC3DF102E0
+Plaintext = F69F2445DF4F9B17AD2B417BE66C3710
+Ciphertext = 08B0E27988598881D920A9E64F5615CD
+
 
 # AES-192-ECB tests from FIPS-197
-AES-192-ECB:000102030405060708090A0B0C0D0E0F1011121314151617::00112233445566778899AABBCCDDEEFF:DDA97CA4864CDFE06EAF70A0EC0D7191:1
+Cipher = AES-192-ECB
+Key = 000102030405060708090A0B0C0D0E0F1011121314151617
+Operation = ENCRYPT
+Plaintext = 00112233445566778899AABBCCDDEEFF
+Ciphertext = DDA97CA4864CDFE06EAF70A0EC0D7191
+
 
 # AES-192-ECB tests from NIST document SP800-38A
-AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::6BC1BEE22E409F96E93D7E117393172A:BD334F1D6E45F25FF712A214571FA5CC:1
-AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::AE2D8A571E03AC9C9EB76FAC45AF8E51:974104846D0AD3AD7734ECB3ECEE4EEF:1
-AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::30C81C46A35CE411E5FBC1191A0A52EF:EF7AFD2270E2E60ADCE0BA2FACE6444E:1
-AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::F69F2445DF4F9B17AD2B417BE66C3710:9A4B41BA738D6C72FB16691603C18E0E:1
+Cipher = AES-192-ECB
+Key = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B
+Plaintext = 6BC1BEE22E409F96E93D7E117393172A
+Ciphertext = BD334F1D6E45F25FF712A214571FA5CC
+
+Cipher = AES-192-ECB
+Key = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B
+Plaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51
+Ciphertext = 974104846D0AD3AD7734ECB3ECEE4EEF
+
+Cipher = AES-192-ECB
+Key = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B
+Plaintext = 30C81C46A35CE411E5FBC1191A0A52EF
+Ciphertext = EF7AFD2270E2E60ADCE0BA2FACE6444E
+
+Cipher = AES-192-ECB
+Key = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B
+Plaintext = F69F2445DF4F9B17AD2B417BE66C3710
+Ciphertext = 9A4B41BA738D6C72FB16691603C18E0E
diff --git a/src/crypto/des/des.c b/src/crypto/des/des.c
index 56a2996..9cd75f5 100644
--- a/src/crypto/des/des.c
+++ b/src/crypto/des/des.c
@@ -762,3 +762,11 @@
 
   tin[0] = tin[1] = 0;
 }
+
+void DES_ede2_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len,
+                          const DES_key_schedule *ks1,
+                          const DES_key_schedule *ks2,
+                          DES_cblock *ivec,
+                          int enc) {
+  DES_ede3_cbc_encrypt(in, out, len, ks1, ks2, ks1, ivec, enc);
+}
diff --git a/src/crypto/dh/CMakeLists.txt b/src/crypto/dh/CMakeLists.txt
index 9e487d5..d0c1da7 100644
--- a/src/crypto/dh/CMakeLists.txt
+++ b/src/crypto/dh/CMakeLists.txt
@@ -16,6 +16,8 @@
   dh_test
 
   dh_test.cc
+
+  $<TARGET_OBJECTS:test_support>
 )
 
 target_link_libraries(dh_test crypto)
diff --git a/src/crypto/dh/dh.c b/src/crypto/dh/dh.c
index ab7ed8b..96b85f3 100644
--- a/src/crypto/dh/dh.c
+++ b/src/crypto/dh/dh.c
@@ -116,7 +116,7 @@
     return;
   }
 
-  if (CRYPTO_add(&dh->references, -1, CRYPTO_LOCK_DH) > 0) {
+  if (!CRYPTO_refcount_dec_and_test_zero(&dh->references)) {
     return;
   }
 
@@ -164,8 +164,10 @@
 
 int DH_size(const DH *dh) { return BN_num_bytes(dh->p); }
 
-int DH_up_ref(DH *r) {
-  CRYPTO_add(&r->references, 1, CRYPTO_LOCK_DH);
+unsigned DH_num_bits(const DH *dh) { return BN_num_bits(dh->p); }
+
+int DH_up_ref(DH *dh) {
+  CRYPTO_refcount_inc(&dh->references);
   return 1;
 }
 
diff --git a/src/crypto/digest/CMakeLists.txt b/src/crypto/digest/CMakeLists.txt
index 8cab46a..816d116 100644
--- a/src/crypto/digest/CMakeLists.txt
+++ b/src/crypto/digest/CMakeLists.txt
@@ -13,6 +13,8 @@
   digest_test
 
   digest_test.cc
+
+  $<TARGET_OBJECTS:test_support>
 )
 
 target_link_libraries(digest_test crypto)
diff --git a/src/crypto/digest/digest.c b/src/crypto/digest/digest.c
index e32eafd..f09948b 100644
--- a/src/crypto/digest/digest.c
+++ b/src/crypto/digest/digest.c
@@ -189,7 +189,8 @@
     return 1;
   }
 
-  return ctx->digest->init(ctx);
+  ctx->digest->init(ctx);
+  return 1;
 }
 
 int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) {
@@ -198,26 +199,24 @@
 }
 
 int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) {
-  return ctx->update(ctx, data, len);
+  ctx->update(ctx, data, len);
+  return 1;
 }
 
 int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, uint8_t *md_out, unsigned int *size) {
-  int ret;
-
   assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
-  ret = ctx->digest->final(ctx, md_out);
+  ctx->digest->final(ctx, md_out);
   if (size != NULL) {
     *size = ctx->digest->md_size;
   }
   OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size);
-
-  return ret;
+  return 1;
 }
 
 int EVP_DigestFinal(EVP_MD_CTX *ctx, uint8_t *md, unsigned int *size) {
-  int ret = EVP_DigestFinal_ex(ctx, md, size);
+  EVP_DigestFinal_ex(ctx, md, size);
   EVP_MD_CTX_cleanup(ctx);
-  return ret;
+  return 1;
 }
 
 int EVP_Digest(const void *data, size_t count, uint8_t *out_md,
@@ -258,14 +257,6 @@
   ctx->flags |= flags;
 }
 
-void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, uint32_t flags) {
-  ctx->flags &= ~flags;
-}
-
-uint32_t EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, uint32_t flags) {
-  return ctx->flags & flags;
-}
-
 int EVP_add_digest(const EVP_MD *digest) {
   return 1;
 }
diff --git a/src/crypto/digest/digest_test.cc b/src/crypto/digest/digest_test.cc
index dcb569c..6a6113d 100644
--- a/src/crypto/digest/digest_test.cc
+++ b/src/crypto/digest/digest_test.cc
@@ -233,6 +233,16 @@
   return true;
 }
 
+static int TestGetters() {
+  if (EVP_get_digestbyname("RSA-SHA512") == NULL ||
+      EVP_get_digestbyname("sha512WithRSAEncryption") == NULL ||
+      EVP_get_digestbyname("nonsense") != NULL) {
+    return false;
+  }
+
+  return true;
+}
+
 int main(void) {
   CRYPTO_library_init();
   ERR_load_crypto_strings();
@@ -244,6 +254,10 @@
     }
   }
 
+  if (!TestGetters()) {
+    return 1;
+  }
+
   printf("PASS\n");
   return 0;
 }
diff --git a/src/crypto/digest/digests.c b/src/crypto/digest/digests.c
index ac00ed3..f5eda36 100644
--- a/src/crypto/digest/digests.c
+++ b/src/crypto/digest/digests.c
@@ -56,6 +56,9 @@
 
 #include <openssl/digest.h>
 
+#include <assert.h>
+#include <string.h>
+
 #include <openssl/md4.h>
 #include <openssl/md5.h>
 #include <openssl/obj.h>
@@ -63,15 +66,23 @@
 
 #include "internal.h"
 
+#if defined(NDEBUG)
+#define CHECK(x) x
+#else
+#define CHECK(x) assert(x)
+#endif
 
-static int md4_init(EVP_MD_CTX *ctx) { return MD4_Init(ctx->md_data); }
 
-static int md4_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
-  return MD4_Update(ctx->md_data, data, count);
+static void md4_init(EVP_MD_CTX *ctx) {
+  CHECK(MD4_Init(ctx->md_data));
 }
 
-static int md4_final(EVP_MD_CTX *ctx, unsigned char *out) {
-  return MD4_Final(out, ctx->md_data);
+static void md4_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
+  CHECK(MD4_Update(ctx->md_data, data, count));
+}
+
+static void md4_final(EVP_MD_CTX *ctx, uint8_t *out) {
+  CHECK(MD4_Final(out, ctx->md_data));
 }
 
 static const EVP_MD md4_md = {
@@ -82,14 +93,16 @@
 const EVP_MD *EVP_md4(void) { return &md4_md; }
 
 
-static int md5_init(EVP_MD_CTX *ctx) { return MD5_Init(ctx->md_data); }
-
-static int md5_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
-  return MD5_Update(ctx->md_data, data, count);
+static void md5_init(EVP_MD_CTX *ctx) {
+  CHECK(MD5_Init(ctx->md_data));
 }
 
-static int md5_final(EVP_MD_CTX *ctx, unsigned char *out) {
-  return MD5_Final(out, ctx->md_data);
+static void md5_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
+  CHECK(MD5_Update(ctx->md_data, data, count));
+}
+
+static void md5_final(EVP_MD_CTX *ctx, uint8_t *out) {
+  CHECK(MD5_Final(out, ctx->md_data));
 }
 
 static const EVP_MD md5_md = {
@@ -100,14 +113,16 @@
 const EVP_MD *EVP_md5(void) { return &md5_md; }
 
 
-static int sha1_init(EVP_MD_CTX *ctx) { return SHA1_Init(ctx->md_data); }
-
-static int sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
-  return SHA1_Update(ctx->md_data, data, count);
+static void sha1_init(EVP_MD_CTX *ctx) {
+  CHECK(SHA1_Init(ctx->md_data));
 }
 
-static int sha1_final(EVP_MD_CTX *ctx, unsigned char *md) {
-  return SHA1_Final(md, ctx->md_data);
+static void sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
+  CHECK(SHA1_Update(ctx->md_data, data, count));
+}
+
+static void sha1_final(EVP_MD_CTX *ctx, uint8_t *md) {
+  CHECK(SHA1_Final(md, ctx->md_data));
 }
 
 static const EVP_MD sha1_md = {
@@ -118,14 +133,16 @@
 const EVP_MD *EVP_sha1(void) { return &sha1_md; }
 
 
-static int sha224_init(EVP_MD_CTX *ctx) { return SHA224_Init(ctx->md_data); }
-
-static int sha224_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
-  return SHA224_Update(ctx->md_data, data, count);
+static void sha224_init(EVP_MD_CTX *ctx) {
+  CHECK(SHA224_Init(ctx->md_data));
 }
 
-static int sha224_final(EVP_MD_CTX *ctx, unsigned char *md) {
-  return SHA224_Final(md, ctx->md_data);
+static void sha224_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
+  CHECK(SHA224_Update(ctx->md_data, data, count));
+}
+
+static void sha224_final(EVP_MD_CTX *ctx, uint8_t *md) {
+  CHECK(SHA224_Final(md, ctx->md_data));
 }
 
 static const EVP_MD sha224_md = {
@@ -137,14 +154,16 @@
 const EVP_MD *EVP_sha224(void) { return &sha224_md; }
 
 
-static int sha256_init(EVP_MD_CTX *ctx) { return SHA256_Init(ctx->md_data); }
-
-static int sha256_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
-  return SHA256_Update(ctx->md_data, data, count);
+static void sha256_init(EVP_MD_CTX *ctx) {
+  CHECK(SHA256_Init(ctx->md_data));
 }
 
-static int sha256_final(EVP_MD_CTX *ctx, unsigned char *md) {
-  return SHA256_Final(md, ctx->md_data);
+static void sha256_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
+  CHECK(SHA256_Update(ctx->md_data, data, count));
+}
+
+static void sha256_final(EVP_MD_CTX *ctx, uint8_t *md) {
+  CHECK(SHA256_Final(md, ctx->md_data));
 }
 
 static const EVP_MD sha256_md = {
@@ -156,14 +175,16 @@
 const EVP_MD *EVP_sha256(void) { return &sha256_md; }
 
 
-static int sha384_init(EVP_MD_CTX *ctx) { return SHA384_Init(ctx->md_data); }
-
-static int sha384_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
-  return SHA384_Update(ctx->md_data, data, count);
+static void sha384_init(EVP_MD_CTX *ctx) {
+  CHECK(SHA384_Init(ctx->md_data));
 }
 
-static int sha384_final(EVP_MD_CTX *ctx, unsigned char *md) {
-  return SHA384_Final(md, ctx->md_data);
+static void sha384_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
+  CHECK(SHA384_Update(ctx->md_data, data, count));
+}
+
+static void sha384_final(EVP_MD_CTX *ctx, uint8_t *md) {
+  CHECK(SHA384_Final(md, ctx->md_data));
 }
 
 static const EVP_MD sha384_md = {
@@ -175,14 +196,16 @@
 const EVP_MD *EVP_sha384(void) { return &sha384_md; }
 
 
-static int sha512_init(EVP_MD_CTX *ctx) { return SHA512_Init(ctx->md_data); }
-
-static int sha512_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
-  return SHA512_Update(ctx->md_data, data, count);
+static void sha512_init(EVP_MD_CTX *ctx) {
+  CHECK(SHA512_Init(ctx->md_data));
 }
 
-static int sha512_final(EVP_MD_CTX *ctx, unsigned char *md) {
-  return SHA512_Final(md, ctx->md_data);
+static void sha512_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
+  CHECK(SHA512_Update(ctx->md_data, data, count));
+}
+
+static void sha512_final(EVP_MD_CTX *ctx, uint8_t *md) {
+  CHECK(SHA512_Final(md, ctx->md_data));
 }
 
 static const EVP_MD sha512_md = {
@@ -199,23 +222,22 @@
   SHA_CTX sha1;
 } MD5_SHA1_CTX;
 
-static int md5_sha1_init(EVP_MD_CTX *md_ctx) {
+static void md5_sha1_init(EVP_MD_CTX *md_ctx) {
   MD5_SHA1_CTX *ctx = md_ctx->md_data;
-  return MD5_Init(&ctx->md5) && SHA1_Init(&ctx->sha1);
+  CHECK(MD5_Init(&ctx->md5) && SHA1_Init(&ctx->sha1));
 }
 
-static int md5_sha1_update(EVP_MD_CTX *md_ctx, const void *data, size_t count) {
+static void md5_sha1_update(EVP_MD_CTX *md_ctx, const void *data,
+                            size_t count) {
   MD5_SHA1_CTX *ctx = md_ctx->md_data;
-  return MD5_Update(&ctx->md5, data, count) && SHA1_Update(&ctx->sha1, data, count);
+  CHECK(MD5_Update(&ctx->md5, data, count) &&
+        SHA1_Update(&ctx->sha1, data, count));
 }
 
-static int md5_sha1_final(EVP_MD_CTX *md_ctx, unsigned char *out) {
+static void md5_sha1_final(EVP_MD_CTX *md_ctx, uint8_t *out) {
   MD5_SHA1_CTX *ctx = md_ctx->md_data;
-  if (!MD5_Final(out, &ctx->md5) ||
-      !SHA1_Final(out + MD5_DIGEST_LENGTH, &ctx->sha1)) {
-    return 0;
-  }
-  return 1;
+  CHECK(MD5_Final(out, &ctx->md5) &&
+        SHA1_Final(out + MD5_DIGEST_LENGTH, &ctx->sha1));
 }
 
 static const EVP_MD md5_sha1_md = {
@@ -235,25 +257,33 @@
 struct nid_to_digest {
   int nid;
   const EVP_MD* (*md_func)(void);
+  const char *short_name;
+  const char *long_name;
 };
 
 static const struct nid_to_digest nid_to_digest_mapping[] = {
-  { NID_md5, EVP_md5 },
-  { NID_sha1, EVP_sha1 },
-  { NID_sha224, EVP_sha224 },
-  { NID_sha256, EVP_sha256 },
-  { NID_sha384, EVP_sha384 },
-  { NID_sha512, EVP_sha512 },
-  { NID_md5_sha1, EVP_md5_sha1 },
-  { NID_dsaWithSHA, EVP_sha1 },
-  { NID_dsaWithSHA1, EVP_sha1 },
-  { NID_ecdsa_with_SHA1, EVP_sha1 },
-  { NID_md5WithRSAEncryption, EVP_md5 },
-  { NID_sha1WithRSAEncryption, EVP_sha1 },
-  { NID_sha224WithRSAEncryption, EVP_sha224 },
-  { NID_sha256WithRSAEncryption, EVP_sha256 },
-  { NID_sha384WithRSAEncryption, EVP_sha384 },
-  { NID_sha512WithRSAEncryption, EVP_sha512 },
+  { NID_md5, EVP_md5, SN_md5, LN_md5 },
+  { NID_sha1, EVP_sha1, SN_sha1, LN_sha1 },
+  { NID_sha224, EVP_sha224, SN_sha224, LN_sha224 },
+  { NID_sha256, EVP_sha256, SN_sha256, LN_sha256 },
+  { NID_sha384, EVP_sha384, SN_sha384, LN_sha384 },
+  { NID_sha512, EVP_sha512, SN_sha512, LN_sha512 },
+  { NID_md5_sha1, EVP_md5_sha1, SN_md5_sha1, LN_md5_sha1 },
+  { NID_dsaWithSHA, EVP_sha1, SN_dsaWithSHA, LN_dsaWithSHA },
+  { NID_dsaWithSHA1, EVP_sha1, SN_dsaWithSHA1, LN_dsaWithSHA1 },
+  { NID_ecdsa_with_SHA1, EVP_sha1, SN_ecdsa_with_SHA1, NULL },
+  { NID_md5WithRSAEncryption, EVP_md5, SN_md5WithRSAEncryption,
+    LN_md5WithRSAEncryption },
+  { NID_sha1WithRSAEncryption, EVP_sha1, SN_sha1WithRSAEncryption,
+    LN_sha1WithRSAEncryption },
+  { NID_sha224WithRSAEncryption, EVP_sha224, SN_sha224WithRSAEncryption,
+    LN_sha224WithRSAEncryption },
+  { NID_sha256WithRSAEncryption, EVP_sha256, SN_sha256WithRSAEncryption,
+    LN_sha256WithRSAEncryption },
+  { NID_sha384WithRSAEncryption, EVP_sha384, SN_sha384WithRSAEncryption,
+    LN_sha384WithRSAEncryption },
+  { NID_sha512WithRSAEncryption, EVP_sha512, SN_sha512WithRSAEncryption,
+    LN_sha512WithRSAEncryption },
 };
 
 const EVP_MD* EVP_get_digestbynid(int nid) {
@@ -272,3 +302,19 @@
 const EVP_MD* EVP_get_digestbyobj(const ASN1_OBJECT *obj) {
   return EVP_get_digestbynid(OBJ_obj2nid(obj));
 }
+
+const EVP_MD *EVP_get_digestbyname(const char *name) {
+  unsigned i;
+
+  for (i = 0; i < sizeof(nid_to_digest_mapping) / sizeof(struct nid_to_digest);
+       i++) {
+    const char *short_name = nid_to_digest_mapping[i].short_name;
+    const char *long_name = nid_to_digest_mapping[i].long_name;
+    if ((short_name && strcmp(short_name, name) == 0) ||
+        (long_name && strcmp(long_name, name) == 0)) {
+      return nid_to_digest_mapping[i].md_func();
+    }
+  }
+
+  return NULL;
+}
diff --git a/src/crypto/digest/internal.h b/src/crypto/digest/internal.h
index 94dbfaa..1572fa8 100644
--- a/src/crypto/digest/internal.h
+++ b/src/crypto/digest/internal.h
@@ -75,15 +75,14 @@
   /* flags contains the OR of |EVP_MD_FLAG_*| values. */
   uint32_t flags;
 
-  /* init initialises the state in |ctx->md_data|. It returns one on success
-   * and zero otherwise. */
-  int (*init)(EVP_MD_CTX *ctx);
+  /* init initialises the state in |ctx->md_data|. */
+  void (*init)(EVP_MD_CTX *ctx);
 
   /* update hashes |len| bytes of |data| into the state in |ctx->md_data|. */
-  int (*update)(EVP_MD_CTX *ctx, const void *data, size_t count);
+  void (*update)(EVP_MD_CTX *ctx, const void *data, size_t count);
 
   /* final completes the hash and writes |md_size| bytes of digest to |out|. */
-  int (*final)(EVP_MD_CTX *ctx, uint8_t *out);
+  void (*final)(EVP_MD_CTX *ctx, uint8_t *out);
 
   /* block_size contains the hash's native block size. */
   unsigned block_size;
@@ -109,6 +108,17 @@
   int (*begin_digest) (EVP_MD_CTX *ctx);
 };
 
+/* EVP_MD_CTX_set_flags ORs |flags| into the flags member of |ctx|. */
+OPENSSL_EXPORT void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, uint32_t flags);
+
+/* EVP_MD_CTX_FLAG_NO_INIT causes the |EVP_MD|'s |init| function not to be
+ * called, the |update| member not to be copied from the |EVP_MD| in
+ * |EVP_DigestInit_ex| and for |md_data| not to be initialised.
+ *
+ * TODO(davidben): This is an implementation detail of |EVP_PKEY_HMAC| and can
+ * be removed when it is gone. */
+#define EVP_MD_CTX_FLAG_NO_INIT 1
+
 
 #if defined(__cplusplus)
 }  /* extern C */
diff --git a/src/crypto/digest/md32_common.h b/src/crypto/digest/md32_common.h
index d7caba2..14607fb 100644
--- a/src/crypto/digest/md32_common.h
+++ b/src/crypto/digest/md32_common.h
@@ -147,11 +147,11 @@
    * 					<appro@fy.chalmers.se>
    */
 #  if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
-#   define ROTATE(a,n)	({ register unsigned int ret;	\
+#   define ROTATE(a,n)	({ register uint32_t ret;	\
 				asm (			\
 				"roll %1,%0"		\
 				: "=r"(ret)		\
-				: "I"(n), "0"((unsigned int)(a))	\
+				: "I"(n), "0"((uint32_t)(a))	\
 				: "cc");		\
 			   ret;				\
 			})
@@ -173,28 +173,28 @@
      * this trick on x86* platforms only, because these CPUs can fetch
      * unaligned data without raising an exception.
      */
-#   define HOST_c2l(c,l)	({ unsigned int r=*((const unsigned int *)(c));	\
+#   define HOST_c2l(c,l)	({ uint32_t r=*((const uint32_t *)(c));	\
 				   asm ("bswapl %0":"=r"(r):"0"(r));	\
 				   (c)+=4; (l)=r;			})
-#   define HOST_l2c(l,c)	({ unsigned int r=(l);			\
+#   define HOST_l2c(l,c)	({ uint32_t r=(l);			\
 				   asm ("bswapl %0":"=r"(r):"0"(r));	\
-				   *((unsigned int *)(c))=r; (c)+=4; r;	})
+				   *((uint32_t *)(c))=r; (c)+=4; r;	})
 #  elif defined(__aarch64__)
 #   if defined(__BYTE_ORDER__)
 #    if defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__
-#     define HOST_c2l(c,l)	({ unsigned int r;		\
+#     define HOST_c2l(c,l)	({ uint32_t r;			\
 				   asm ("rev	%w0,%w1"	\
 					:"=r"(r)		\
-					:"r"(*((const unsigned int *)(c))));\
+					:"r"(*((const uint32_t *)(c))));\
 				   (c)+=4; (l)=r;		})
-#     define HOST_l2c(l,c)	({ unsigned int r;		\
+#     define HOST_l2c(l,c)	({ uint32_t r;			\
 				   asm ("rev	%w0,%w1"	\
 					:"=r"(r)		\
-					:"r"((unsigned int)(l)));\
-				   *((unsigned int *)(c))=r; (c)+=4; r;	})
+					:"r"((uint32_t)(l)));	\
+				   *((uint32_t *)(c))=r; (c)+=4; r;	})
 #    elif defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__
-#     define HOST_c2l(c,l)	(void)((l)=*((const unsigned int *)(c)), (c)+=4)
-#     define HOST_l2c(l,c)	(*((unsigned int *)(c))=(l), (c)+=4, (l))
+#     define HOST_c2l(c,l)	(void)((l)=*((const uint32_t *)(c)), (c)+=4)
+#     define HOST_l2c(l,c)	(*((uint32_t *)(c))=(l), (c)+=4, (l))
 #    endif
 #   endif
 #  endif
@@ -202,16 +202,16 @@
 #endif
 
 #ifndef HOST_c2l
-#define HOST_c2l(c,l)	(void)(l =(((unsigned long)(*((c)++)))<<24),	\
-			 l|=(((unsigned long)(*((c)++)))<<16),		\
-			 l|=(((unsigned long)(*((c)++)))<< 8),		\
-			 l|=(((unsigned long)(*((c)++)))    ))
+#define HOST_c2l(c,l)	(void)(l =(((uint32_t)(*((c)++)))<<24),	\
+			 l|=(((uint32_t)(*((c)++)))<<16),	\
+			 l|=(((uint32_t)(*((c)++)))<< 8),	\
+			 l|=(((uint32_t)(*((c)++)))    ))
 #endif
 #ifndef HOST_l2c
-#define HOST_l2c(l,c)	(*((c)++)=(unsigned char)(((l)>>24)&0xff),	\
-			 *((c)++)=(unsigned char)(((l)>>16)&0xff),	\
-			 *((c)++)=(unsigned char)(((l)>> 8)&0xff),	\
-			 *((c)++)=(unsigned char)(((l)    )&0xff),	\
+#define HOST_l2c(l,c)	(*((c)++)=(uint8_t)(((l)>>24)&0xff),	\
+			 *((c)++)=(uint8_t)(((l)>>16)&0xff),	\
+			 *((c)++)=(uint8_t)(((l)>> 8)&0xff),	\
+			 *((c)++)=(uint8_t)(((l)    )&0xff),	\
 			 l)
 #endif
 
@@ -219,21 +219,21 @@
 
 #if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
    /* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */
-#  define HOST_c2l(c,l)	(void)((l)=*((const unsigned int *)(c)), (c)+=4)
-#  define HOST_l2c(l,c)	(*((unsigned int *)(c))=(l), (c)+=4, l)
+#  define HOST_c2l(c,l)	(void)((l)=*((const uint32_t *)(c)), (c)+=4)
+#  define HOST_l2c(l,c)	(*((uint32_t *)(c))=(l), (c)+=4, l)
 #endif
 
 #ifndef HOST_c2l
-#define HOST_c2l(c,l)	(void)(l =(((unsigned long)(*((c)++)))    ),	\
-			 l|=(((unsigned long)(*((c)++)))<< 8),		\
-			 l|=(((unsigned long)(*((c)++)))<<16),		\
-			 l|=(((unsigned long)(*((c)++)))<<24))
+#define HOST_c2l(c,l)	(void)(l =(((uint32_t)(*((c)++)))    ),	\
+			 l|=(((uint32_t)(*((c)++)))<< 8),	\
+			 l|=(((uint32_t)(*((c)++)))<<16),	\
+			 l|=(((uint32_t)(*((c)++)))<<24))
 #endif
 #ifndef HOST_l2c
-#define HOST_l2c(l,c)	(*((c)++)=(unsigned char)(((l)    )&0xff),	\
-			 *((c)++)=(unsigned char)(((l)>> 8)&0xff),	\
-			 *((c)++)=(unsigned char)(((l)>>16)&0xff),	\
-			 *((c)++)=(unsigned char)(((l)>>24)&0xff),	\
+#define HOST_l2c(l,c)	(*((c)++)=(uint8_t)(((l)    )&0xff),	\
+			 *((c)++)=(uint8_t)(((l)>> 8)&0xff),	\
+			 *((c)++)=(uint8_t)(((l)>>16)&0xff),	\
+			 *((c)++)=(uint8_t)(((l)>>24)&0xff),	\
 			 l)
 #endif
 
@@ -241,8 +241,8 @@
 
 int HASH_UPDATE (HASH_CTX *c, const void *data_, size_t len)
 	{
-	const unsigned char *data=data_;
-	unsigned char *p;
+	const uint8_t *data=data_;
+	uint8_t *p;
 	HASH_LONG l;
 	size_t n;
 
@@ -259,7 +259,7 @@
 	n = c->num;
 	if (n != 0)
 		{
-		p=(unsigned char *)c->data;
+		p=(uint8_t *)c->data;
 
 		if (len >= HASH_CBLOCK || len+n >= HASH_CBLOCK)
 			{
@@ -290,7 +290,7 @@
 
 	if (len != 0)
 		{
-		p = (unsigned char *)c->data;
+		p = (uint8_t *)c->data;
 		c->num = (unsigned int)len;
 		memcpy (p,data,len);
 		}
@@ -298,15 +298,15 @@
 	}
 
 
-void HASH_TRANSFORM (HASH_CTX *c, const unsigned char *data)
+void HASH_TRANSFORM (HASH_CTX *c, const uint8_t *data)
 	{
 	HASH_BLOCK_DATA_ORDER (c,data,1);
 	}
 
 
-int HASH_FINAL (unsigned char *md, HASH_CTX *c)
+int HASH_FINAL (uint8_t *md, HASH_CTX *c)
 	{
-	unsigned char *p = (unsigned char *)c->data;
+	uint8_t *p = (uint8_t *)c->data;
 	size_t n = c->num;
 
 	p[n] = 0x80; /* there is always room for one */
@@ -342,10 +342,6 @@
 	return 1;
 	}
 
-#ifndef MD32_REG_T
-#define MD32_REG_T int
-#endif
-
 
 #if defined(__cplusplus)
 }  /* extern C */
diff --git a/src/crypto/dsa/CMakeLists.txt b/src/crypto/dsa/CMakeLists.txt
index dab2c4c..1bb8b63 100644
--- a/src/crypto/dsa/CMakeLists.txt
+++ b/src/crypto/dsa/CMakeLists.txt
@@ -14,6 +14,8 @@
   dsa_test
 
   dsa_test.c
+
+  $<TARGET_OBJECTS:test_support>
 )
 
 target_link_libraries(dsa_test crypto)
diff --git a/src/crypto/dsa/dsa.c b/src/crypto/dsa/dsa.c
index e8e3d73..65444b1 100644
--- a/src/crypto/dsa/dsa.c
+++ b/src/crypto/dsa/dsa.c
@@ -123,7 +123,7 @@
     return;
   }
 
-  if (CRYPTO_add(&dsa->references, -1, CRYPTO_LOCK_DSA) > 0) {
+  if (!CRYPTO_refcount_dec_and_test_zero(&dsa->references)) {
     return;
   }
 
@@ -146,7 +146,7 @@
 }
 
 int DSA_up_ref(DSA *dsa) {
-  CRYPTO_add(&dsa->references, 1, CRYPTO_LOCK_DSA);
+  CRYPTO_refcount_inc(&dsa->references);
   return 1;
 }
 
diff --git a/src/crypto/dsa/dsa_impl.c b/src/crypto/dsa/dsa_impl.c
index b7e1fd8..2ab8ba8 100644
--- a/src/crypto/dsa/dsa_impl.c
+++ b/src/crypto/dsa/dsa_impl.c
@@ -501,12 +501,16 @@
   }
 
   ctx = BN_CTX_new();
+  if (ctx == NULL) {
+    goto err;
+  }
+  BN_CTX_start(ctx);
+
   mont = BN_MONT_CTX_new();
-  if (ctx == NULL || mont == NULL) {
+  if (mont == NULL) {
     goto err;
   }
 
-  BN_CTX_start(ctx);
   r0 = BN_CTX_get(ctx);
   g = BN_CTX_get(ctx);
   W = BN_CTX_get(ctx);
@@ -516,7 +520,7 @@
   p = BN_CTX_get(ctx);
   test = BN_CTX_get(ctx);
 
-  if (!BN_lshift(test, BN_value_one(), bits - 1)) {
+  if (test == NULL || !BN_lshift(test, BN_value_one(), bits - 1)) {
     goto err;
   }
 
diff --git a/src/crypto/dsa/dsa_test.c b/src/crypto/dsa/dsa_test.c
index 9b70dbe..8bdaaf4 100644
--- a/src/crypto/dsa/dsa_test.c
+++ b/src/crypto/dsa/dsa_test.c
@@ -238,8 +238,10 @@
     goto end;
   }
 
-  DSA_generate_key(dsa);
-  DSA_sign(0, fips_digest, sizeof(fips_digest), sig, &siglen, dsa);
+  if (!DSA_generate_key(dsa) ||
+      !DSA_sign(0, fips_digest, sizeof(fips_digest), sig, &siglen, dsa)) {
+    goto end;
+  }
   if (DSA_verify(0, fips_digest, sizeof(fips_digest), sig, siglen, dsa) == 1) {
     ok = 1;
   } else {
diff --git a/src/crypto/ec/CMakeLists.txt b/src/crypto/ec/CMakeLists.txt
index a218c0d..b5ebefa 100644
--- a/src/crypto/ec/CMakeLists.txt
+++ b/src/crypto/ec/CMakeLists.txt
@@ -20,12 +20,16 @@
   example_mul
 
   example_mul.c
+
+  $<TARGET_OBJECTS:test_support>
 )
 
 add_executable(
   ec_test
 
   ec_test.cc
+
+  $<TARGET_OBJECTS:test_support>
 )
 
 target_link_libraries(example_mul crypto)
diff --git a/src/crypto/ec/ec.c b/src/crypto/ec/ec.c
index 5e30730..f38eba6 100644
--- a/src/crypto/ec/ec.c
+++ b/src/crypto/ec/ec.c
@@ -289,6 +289,12 @@
 
 int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
                            const BIGNUM *order, const BIGNUM *cofactor) {
+  if (group->curve_name != NID_undef) {
+    /* |EC_GROUP_set_generator| should only be used with |EC_GROUP|s returned
+     * by |EC_GROUP_new_curve_GFp|. */
+    return 0;
+  }
+
   if (group->generator == NULL) {
     group->generator = EC_POINT_new(group);
     if (group->generator == NULL) {
diff --git a/src/crypto/ec/ec_key.c b/src/crypto/ec/ec_key.c
index 348ec46..e5cbfed 100644
--- a/src/crypto/ec/ec_key.c
+++ b/src/crypto/ec/ec_key.c
@@ -143,7 +143,7 @@
     return;
   }
 
-  if (CRYPTO_add(&r->references, -1, CRYPTO_LOCK_EC)) {
+  if (!CRYPTO_refcount_dec_and_test_zero(&r->references)) {
     return;
   }
 
@@ -234,7 +234,8 @@
 }
 
 int EC_KEY_up_ref(EC_KEY *r) {
-  return CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC) > 1;
+  CRYPTO_refcount_inc(&r->references);
+  return 1;
 }
 
 int EC_KEY_is_opaque(const EC_KEY *key) {
diff --git a/src/crypto/ec/ec_test.cc b/src/crypto/ec/ec_test.cc
index 74685eb..5af42d5 100644
--- a/src/crypto/ec/ec_test.cc
+++ b/src/crypto/ec/ec_test.cc
@@ -125,6 +125,9 @@
   }
   ScopedOpenSSLString x_hex(BN_bn2hex(x.get()));
   ScopedOpenSSLString y_hex(BN_bn2hex(y.get()));
+  if (!x_hex || !y_hex) {
+    return false;
+  }
   if (0 != strcmp(
           x_hex.get(),
           "c81561ecf2e54edefe6617db1c7a34a70744ddb261f269b83dacfcd2ade5a681") ||
diff --git a/src/crypto/ec/internal.h b/src/crypto/ec/internal.h
index 0a8bf24..71062c1 100644
--- a/src/crypto/ec/internal.h
+++ b/src/crypto/ec/internal.h
@@ -72,6 +72,7 @@
 
 #include <openssl/bn.h>
 #include <openssl/ex_data.h>
+#include <openssl/thread.h>
 
 #if defined(__cplusplus)
 extern "C" {
@@ -331,7 +332,7 @@
   unsigned int enc_flag;
   point_conversion_form_t conv_form;
 
-  int references;
+  CRYPTO_refcount_t references;
   int flags;
 
   ECDSA_METHOD *ecdsa_meth;
diff --git a/src/crypto/ec/p256-64.c b/src/crypto/ec/p256-64.c
index 8f824de..fdb942c 100644
--- a/src/crypto/ec/p256-64.c
+++ b/src/crypto/ec/p256-64.c
@@ -1601,7 +1601,6 @@
 /* Precomputation for the group generator. */
 typedef struct {
   smallfelem g_pre_comp[2][16][3];
-  int references;
 } NISTP256_PRE_COMP;
 
 /******************************************************************************/
diff --git a/src/crypto/ec/wnaf.c b/src/crypto/ec/wnaf.c
index d87a7d9..ae0d73f 100644
--- a/src/crypto/ec/wnaf.c
+++ b/src/crypto/ec/wnaf.c
@@ -75,6 +75,7 @@
 #include <openssl/thread.h>
 
 #include "internal.h"
+#include "../internal.h"
 
 
 /* This file implements the wNAF-based interleaving multi-exponentation method
@@ -91,7 +92,7 @@
   EC_POINT **points; /* array with pre-calculated multiples of generator:
                       * 'num' pointers to EC_POINT objects followed by a NULL */
   size_t num; /* numblocks * 2^(w-1) */
-  int references;
+  CRYPTO_refcount_t references;
 } EC_PRE_COMP;
 
 static EC_PRE_COMP *ec_pre_comp_new(void) {
@@ -116,13 +117,13 @@
     return NULL;
   }
 
-  CRYPTO_add(&pre_comp->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
+  CRYPTO_refcount_inc(&pre_comp->references);
   return pre_comp;
 }
 
 void ec_pre_comp_free(EC_PRE_COMP *pre_comp) {
   if (pre_comp == NULL ||
-      CRYPTO_add(&pre_comp->references, -1, CRYPTO_LOCK_EC_PRE_COMP) > 0) {
+      !CRYPTO_refcount_dec_and_test_zero(&pre_comp->references)) {
     return;
   }
 
diff --git a/src/crypto/ecdsa/CMakeLists.txt b/src/crypto/ecdsa/CMakeLists.txt
index c8645d1..f431e59 100644
--- a/src/crypto/ecdsa/CMakeLists.txt
+++ b/src/crypto/ecdsa/CMakeLists.txt
@@ -14,6 +14,8 @@
   ecdsa_test
 
   ecdsa_test.cc
+
+  $<TARGET_OBJECTS:test_support>
 )
 
 target_link_libraries(ecdsa_test crypto)
diff --git a/src/crypto/err/CMakeLists.txt b/src/crypto/err/CMakeLists.txt
index 89f96bd..5215eec 100644
--- a/src/crypto/err/CMakeLists.txt
+++ b/src/crypto/err/CMakeLists.txt
@@ -44,6 +44,8 @@
   err_test
 
   err_test.cc
+
+  $<TARGET_OBJECTS:test_support>
 )
 
 target_link_libraries(err_test crypto)
diff --git a/src/crypto/err/bio.errordata b/src/crypto/err/bio.errordata
index cd7286a..9f2af02 100644
--- a/src/crypto/err/bio.errordata
+++ b/src/crypto/err/bio.errordata
@@ -3,6 +3,7 @@
 BIO,function,102,BIO_new
 BIO,function,103,BIO_new_file
 BIO,function,104,BIO_new_mem_buf
+BIO,function,118,BIO_printf
 BIO,function,105,BIO_zero_copy_get_read_buf
 BIO,function,106,BIO_zero_copy_get_read_buf_done
 BIO,function,107,BIO_zero_copy_get_write_buf
diff --git a/src/crypto/err/bn.errordata b/src/crypto/err/bn.errordata
index ab74073..6fd4968 100644
--- a/src/crypto/err/bn.errordata
+++ b/src/crypto/err/bn.errordata
@@ -8,6 +8,7 @@
 BN,function,107,BN_exp
 BN,function,108,BN_generate_dsa_nonce
 BN,function,109,BN_generate_prime_ex
+BN,function,125,BN_lshift
 BN,function,110,BN_mod_exp2_mont
 BN,function,111,BN_mod_exp_mont
 BN,function,112,BN_mod_exp_mont_consttime
@@ -19,6 +20,7 @@
 BN,function,118,BN_new
 BN,function,119,BN_rand
 BN,function,120,BN_rand_range
+BN,function,126,BN_rshift
 BN,function,121,BN_sqrt
 BN,function,122,BN_usub
 BN,function,123,bn_wexpand
diff --git a/src/crypto/err/err.c b/src/crypto/err/err.c
index b879a22..de1b4a7 100644
--- a/src/crypto/err/err.c
+++ b/src/crypto/err/err.c
@@ -333,6 +333,10 @@
   return ret;
 }
 
+void ERR_remove_state(unsigned long pid) {
+  ERR_clear_error();
+}
+
 void ERR_clear_system_error(void) {
   errno = 0;
 }
diff --git a/src/crypto/err/ssl.errordata b/src/crypto/err/ssl.errordata
index afeaaeb..4ae0a51 100644
--- a/src/crypto/err/ssl.errordata
+++ b/src/crypto/err/ssl.errordata
@@ -1,3 +1,6 @@
+SSL,function,276,SSL_AEAD_CTX_new
+SSL,function,277,SSL_AEAD_CTX_open
+SSL,function,278,SSL_AEAD_CTX_seal
 SSL,function,100,SSL_CTX_check_private_key
 SSL,function,101,SSL_CTX_new
 SSL,function,272,SSL_CTX_set1_tls_channel_id
@@ -72,8 +75,9 @@
 SSL,function,264,dtls1_process_fragment
 SSL,function,162,dtls1_process_record
 SSL,function,163,dtls1_read_bytes
+SSL,function,279,dtls1_seal_record
 SSL,function,164,dtls1_send_hello_verify_request
-SSL,function,165,dtls1_write_app_data_bytes
+SSL,function,165,dtls1_write_app_data
 SSL,function,166,i2d_SSL_SESSION
 SSL,function,167,ssl3_accept
 SSL,function,169,ssl3_cert_verify_hash
@@ -220,6 +224,7 @@
 SSL,reason,146,DTLS_MESSAGE_TOO_BIG
 SSL,reason,147,ECC_CERT_NOT_FOR_SIGNING
 SSL,reason,148,EMPTY_SRTP_PROTECTION_PROFILE_LIST
+SSL,reason,276,EMS_STATE_INCONSISTENT
 SSL,reason,149,ENCRYPTED_LENGTH_TOO_LONG
 SSL,reason,150,ERROR_IN_RECEIVED_CIPHER_LIST
 SSL,reason,151,EVP_DIGESTSIGNFINAL_FAILED
@@ -272,6 +277,7 @@
 SSL,reason,197,NULL_SSL_METHOD_PASSED
 SSL,reason,198,OLD_SESSION_CIPHER_NOT_RETURNED
 SSL,reason,273,OLD_SESSION_VERSION_NOT_RETURNED
+SSL,reason,274,OUTPUT_ALIASES_INPUT
 SSL,reason,199,PACKET_LENGTH_TOO_LONG
 SSL,reason,200,PARSE_TLSEXT
 SSL,reason,201,PATH_TOO_LONG
@@ -289,6 +295,8 @@
 SSL,reason,213,RENEGOTIATION_ENCODING_ERR
 SSL,reason,214,RENEGOTIATION_MISMATCH
 SSL,reason,215,REQUIRED_CIPHER_MISSING
+SSL,reason,275,RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION
+SSL,reason,277,RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION
 SSL,reason,216,SCSV_RECEIVED_WHEN_RENEGOTIATING
 SSL,reason,217,SERVERHELLO_TLSEXT
 SSL,reason,218,SESSION_ID_CONTEXT_UNINITIALIZED
diff --git a/src/crypto/evp/CMakeLists.txt b/src/crypto/evp/CMakeLists.txt
index 6db9752..5769fa4 100644
--- a/src/crypto/evp/CMakeLists.txt
+++ b/src/crypto/evp/CMakeLists.txt
@@ -26,12 +26,15 @@
   evp_extra_test
 
   evp_extra_test.cc
+
+  $<TARGET_OBJECTS:test_support>
 )
 
 add_executable(
   evp_test
 
   evp_test.cc
+
   $<TARGET_OBJECTS:test_support>
 )
 
@@ -39,6 +42,8 @@
   pbkdf_test
 
   pbkdf_test.cc
+
+  $<TARGET_OBJECTS:test_support>
 )
 
 target_link_libraries(evp_extra_test crypto)
diff --git a/src/crypto/evp/evp.c b/src/crypto/evp/evp.c
index 58fd9a9..0ad5c27 100644
--- a/src/crypto/evp/evp.c
+++ b/src/crypto/evp/evp.c
@@ -70,6 +70,7 @@
 #include <openssl/thread.h>
 
 #include "internal.h"
+#include "../internal.h"
 
 
 extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meth;
@@ -106,7 +107,7 @@
     return;
   }
 
-  if (CRYPTO_add(&pkey->references, -1, CRYPTO_LOCK_EVP_PKEY)) {
+  if (!CRYPTO_refcount_dec_and_test_zero(&pkey->references)) {
     return;
   }
 
@@ -115,7 +116,7 @@
 }
 
 EVP_PKEY *EVP_PKEY_up_ref(EVP_PKEY *pkey) {
-  CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
+  CRYPTO_refcount_inc(&pkey->references);
   return pkey;
 }
 
@@ -441,4 +442,8 @@
 
 void OpenSSL_add_all_algorithms(void) {}
 
+void OpenSSL_add_all_ciphers(void) {}
+
+void OpenSSL_add_all_digests(void) {}
+
 void EVP_cleanup(void) {}
diff --git a/src/crypto/evp/p_hmac.c b/src/crypto/evp/p_hmac.c
index 21703ed..7d3254a 100644
--- a/src/crypto/evp/p_hmac.c
+++ b/src/crypto/evp/p_hmac.c
@@ -64,6 +64,7 @@
 #include <openssl/obj.h>
 
 #include "internal.h"
+#include "../digest/internal.h"
 
 
 typedef struct {
@@ -142,15 +143,14 @@
   return 1;
 }
 
-static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
+static void int_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
   HMAC_PKEY_CTX *hctx = ctx->pctx->data;
-  return HMAC_Update(&hctx->ctx, data, count);
+  HMAC_Update(&hctx->ctx, data, count);
 }
 
 static int hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) {
-  HMAC_PKEY_CTX *hctx = ctx->data;
-
-  HMAC_CTX_set_flags(&hctx->ctx, mctx->flags & ~EVP_MD_CTX_FLAG_NO_INIT);
+  /* |mctx| gets repurposed as a hook to call |HMAC_Update|. Suppress the
+   * automatic setting of |mctx->update| and the rest of its initialization. */
   EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
   mctx->update = int_update;
   return 1;
diff --git a/src/crypto/hkdf/CMakeLists.txt b/src/crypto/hkdf/CMakeLists.txt
index f8dd748..66d680a 100644
--- a/src/crypto/hkdf/CMakeLists.txt
+++ b/src/crypto/hkdf/CMakeLists.txt
@@ -12,6 +12,8 @@
   hkdf_test
 
   hkdf_test.c
+
+  $<TARGET_OBJECTS:test_support>
 )
 
 target_link_libraries(hkdf_test crypto)
diff --git a/src/crypto/hmac/CMakeLists.txt b/src/crypto/hmac/CMakeLists.txt
index 1a08c55..11d267f 100644
--- a/src/crypto/hmac/CMakeLists.txt
+++ b/src/crypto/hmac/CMakeLists.txt
@@ -13,6 +13,7 @@
   hmac_test
 
   hmac_test.cc
+
   $<TARGET_OBJECTS:test_support>
 )
 
diff --git a/src/crypto/hmac/hmac.c b/src/crypto/hmac/hmac.c
index b1b2623..556e7f9 100644
--- a/src/crypto/hmac/hmac.c
+++ b/src/crypto/hmac/hmac.c
@@ -172,6 +172,8 @@
   unsigned int i;
   uint8_t buf[EVP_MAX_MD_SIZE];
 
+  /* TODO(davidben): The only thing that can officially fail here is
+   * |EVP_MD_CTX_copy_ex|, but even that should be impossible in this case. */
   if (!EVP_DigestFinal_ex(&ctx->md_ctx, buf, &i) ||
       !EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->o_ctx) ||
       !EVP_DigestUpdate(&ctx->md_ctx, buf, i) ||
@@ -198,12 +200,6 @@
   return 1;
 }
 
-void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags) {
-  EVP_MD_CTX_set_flags(&ctx->i_ctx, flags);
-  EVP_MD_CTX_set_flags(&ctx->o_ctx, flags);
-  EVP_MD_CTX_set_flags(&ctx->md_ctx, flags);
-}
-
 int HMAC_Init(HMAC_CTX *ctx, const void *key, int key_len, const EVP_MD *md) {
   if (key && md) {
     HMAC_CTX_init(ctx);
diff --git a/src/crypto/hmac/hmac_tests.txt b/src/crypto/hmac/hmac_tests.txt
index 9caa3c9..012f593 100644
--- a/src/crypto/hmac/hmac_tests.txt
+++ b/src/crypto/hmac/hmac_tests.txt
@@ -100,3 +100,24 @@
 Input = "Sample message for keylen=blocklen"
 Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
 Output = D93EC8D2DE1AD2A9957CB9B83F14E76AD6B5E0CCE285079A127D3B14BCCB7AA7286D4AC0D4CE64215F2BC9E6870B33D97438BE4AAA20CDA5C5A912B48B8E27F3
+
+# Additional HMAC tests from OpenSSL.
+HMAC = SHA1
+Input = "My test data"
+Key =
+Output = 61afdecb95429ef494d61fdee15990cabf0826fc
+
+HMAC = SHA256
+Input = "My test data"
+Key =
+Output = 2274b195d90ce8e03406f4b526a47e0787a88a65479938f1a5baa3ce0f079776
+
+HMAC = SHA256
+Input = "My test data"
+Key = "123456"
+Output = bab53058ae861a7f191abe2d0145cbb123776a6369ee3f9d79ce455667e411dd
+
+HMAC = SHA1
+Input = "My test data"
+Key = "12345"
+Output = 7dbe8c764c068e3bcd6e6b0fbcd5e6fc197b15bb
diff --git a/src/crypto/internal.h b/src/crypto/internal.h
index 42125db..59eddd0 100644
--- a/src/crypto/internal.h
+++ b/src/crypto/internal.h
@@ -354,6 +354,28 @@
 OPENSSL_EXPORT void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void));
 
 
+/* Reference counting. */
+
+/* CRYPTO_REFCOUNT_MAX is the value at which the reference count saturates. */
+#define CRYPTO_REFCOUNT_MAX 0xffffffff
+
+/* CRYPTO_refcount_inc atomically increments the value at |*count| unless the
+ * value would overflow. It's safe for multiple threads to concurrently call
+ * this or |CRYPTO_refcount_dec_and_test_zero| on the same
+ * |CRYPTO_refcount_t|. */
+OPENSSL_EXPORT void CRYPTO_refcount_inc(CRYPTO_refcount_t *count);
+
+/* CRYPTO_refcount_dec_and_test_zero tests the value at |*count|:
+ *   if it's zero, it crashes the address space.
+ *   if it's the maximum value, it returns zero.
+ *   otherwise, it atomically decrements it and returns one iff the resulting
+ *       value is zero.
+ *
+ * It's safe for multiple threads to concurrently call this or
+ * |CRYPTO_refcount_inc| on the same |CRYPTO_refcount_t|. */
+OPENSSL_EXPORT int CRYPTO_refcount_dec_and_test_zero(CRYPTO_refcount_t *count);
+
+
 /* Locks.
  *
  * Two types of locks are defined: |CRYPTO_MUTEX|, which can be used in
@@ -387,37 +409,40 @@
 
 /* CRYPTO_MUTEX_init initialises |lock|. If |lock| is a static variable, use a
  * |CRYPTO_STATIC_MUTEX|. */
-void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock);
+OPENSSL_EXPORT void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock);
 
 /* CRYPTO_MUTEX_lock_read locks |lock| such that other threads may also have a
  * read lock, but none may have a write lock. (On Windows, read locks are
  * actually fully exclusive.) */
-void CRYPTO_MUTEX_lock_read(CRYPTO_MUTEX *lock);
+OPENSSL_EXPORT void CRYPTO_MUTEX_lock_read(CRYPTO_MUTEX *lock);
 
 /* CRYPTO_MUTEX_lock_write locks |lock| such that no other thread has any type
  * of lock on it. */
-void CRYPTO_MUTEX_lock_write(CRYPTO_MUTEX *lock);
+OPENSSL_EXPORT void CRYPTO_MUTEX_lock_write(CRYPTO_MUTEX *lock);
 
 /* CRYPTO_MUTEX_unlock unlocks |lock|. */
-void CRYPTO_MUTEX_unlock(CRYPTO_MUTEX *lock);
+OPENSSL_EXPORT void CRYPTO_MUTEX_unlock(CRYPTO_MUTEX *lock);
 
 /* CRYPTO_MUTEX_cleanup releases all resources held by |lock|. */
-void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock);
+OPENSSL_EXPORT void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock);
 
 /* CRYPTO_STATIC_MUTEX_lock_read locks |lock| such that other threads may also
  * have a read lock, but none may have a write lock. The |lock| variable does
  * not need to be initialised by any function, but must have been statically
  * initialised with |CRYPTO_STATIC_MUTEX_INIT|. */
-void CRYPTO_STATIC_MUTEX_lock_read(struct CRYPTO_STATIC_MUTEX *lock);
+OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_lock_read(
+    struct CRYPTO_STATIC_MUTEX *lock);
 
 /* CRYPTO_STATIC_MUTEX_lock_write locks |lock| such that no other thread has
  * any type of lock on it.  The |lock| variable does not need to be initialised
  * by any function, but must have been statically initialised with
  * |CRYPTO_STATIC_MUTEX_INIT|. */
-void CRYPTO_STATIC_MUTEX_lock_write(struct CRYPTO_STATIC_MUTEX *lock);
+OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_lock_write(
+    struct CRYPTO_STATIC_MUTEX *lock);
 
 /* CRYPTO_STATIC_MUTEX_unlock unlocks |lock|. */
-void CRYPTO_STATIC_MUTEX_unlock(struct CRYPTO_STATIC_MUTEX *lock);
+OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_unlock(
+    struct CRYPTO_STATIC_MUTEX *lock);
 
 
 /* Thread local storage. */
diff --git a/src/crypto/lhash/CMakeLists.txt b/src/crypto/lhash/CMakeLists.txt
index 0eaabed..c71b8a1 100644
--- a/src/crypto/lhash/CMakeLists.txt
+++ b/src/crypto/lhash/CMakeLists.txt
@@ -12,6 +12,8 @@
   lhash_test
 
   lhash_test.c
+
+  $<TARGET_OBJECTS:test_support>
 )
 
 target_link_libraries(lhash_test crypto)
diff --git a/src/crypto/lhash/lhash_test.c b/src/crypto/lhash/lhash_test.c
index cf5e99b..63748e7 100644
--- a/src/crypto/lhash/lhash_test.c
+++ b/src/crypto/lhash/lhash_test.c
@@ -123,6 +123,9 @@
   CRYPTO_library_init();
 
   lh = lh_new(NULL, NULL);
+  if (lh == NULL) {
+    return 1;
+  }
 
   for (i = 0; i < 100000; i++) {
     unsigned action;
diff --git a/src/crypto/md4/md4.c b/src/crypto/md4/md4.c
index 6150b96..5ef9ae5 100644
--- a/src/crypto/md4/md4.c
+++ b/src/crypto/md4/md4.c
@@ -83,7 +83,7 @@
 #define HASH_FINAL MD4_Final
 #define HASH_MAKE_STRING(c, s) \
   do {                         \
-    unsigned long ll;          \
+    uint32_t ll;               \
     ll = (c)->A;               \
     (void) HOST_l2c(ll, (s));  \
     ll = (c)->B;               \
diff --git a/src/crypto/md5/md5.c b/src/crypto/md5/md5.c
index e20b86b..5575efb 100644
--- a/src/crypto/md5/md5.c
+++ b/src/crypto/md5/md5.c
@@ -104,7 +104,7 @@
 #define HASH_FINAL MD5_Final
 #define HASH_MAKE_STRING(c, s) \
   do {                         \
-    unsigned long ll;          \
+    uint32_t ll;               \
     ll = (c)->A;               \
     (void) HOST_l2c(ll, (s));  \
     ll = (c)->B;               \
diff --git a/src/crypto/modes/CMakeLists.txt b/src/crypto/modes/CMakeLists.txt
index d50e97b..ffb29b6 100644
--- a/src/crypto/modes/CMakeLists.txt
+++ b/src/crypto/modes/CMakeLists.txt
@@ -58,6 +58,8 @@
   gcm_test
 
   gcm_test.c
+
+  $<TARGET_OBJECTS:test_support>
 )
 
 target_link_libraries(gcm_test crypto)
diff --git a/src/crypto/modes/cbc.c b/src/crypto/modes/cbc.c
index ba4805b..931b718 100644
--- a/src/crypto/modes/cbc.c
+++ b/src/crypto/modes/cbc.c
@@ -63,7 +63,8 @@
   size_t n;
   const uint8_t *iv = ivec;
 
-  assert(in && out && key && ivec);
+  assert(key != NULL && ivec != NULL);
+  assert(len == 0 || (in != NULL && out != NULL));
 
   if (STRICT_ALIGNMENT &&
       ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {
@@ -119,9 +120,17 @@
     uint8_t c[16];
   } tmp;
 
-  assert(in && out && key && ivec);
+  assert(key != NULL && ivec != NULL);
+  assert(len == 0 || (in != NULL && out != NULL));
 
-  if (in != out) {
+  const uintptr_t inptr = (uintptr_t) in;
+  const uintptr_t outptr = (uintptr_t) out;
+  /* If |in| and |out| alias, |in| must be ahead. */
+  assert(inptr >= outptr || inptr + len <= outptr);
+
+  if ((inptr >= 32 && outptr <= inptr - 32) || inptr < outptr) {
+    /* If |out| is at least two blocks behind |in| or completely disjoint, there
+     * is no need to decrypt to a temporary block. */
     const uint8_t *iv = ivec;
 
     if (STRICT_ALIGNMENT &&
@@ -152,6 +161,9 @@
     }
     memcpy(ivec, iv, 16);
   } else {
+    /* |out| is less than two blocks behind |in|. Decrypting an input block
+     * directly to |out| would overwrite a ciphertext block before it is used as
+     * the next block's IV. Decrypt to a temporary block instead. */
     if (STRICT_ALIGNMENT &&
         ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {
       uint8_t c;
diff --git a/src/crypto/modes/ctr.c b/src/crypto/modes/ctr.c
index 306b6f7..64062b2 100644
--- a/src/crypto/modes/ctr.c
+++ b/src/crypto/modes/ctr.c
@@ -88,7 +88,8 @@
                            block128_f block) {
   unsigned int n;
 
-  assert(in && out && key && ecount_buf && num);
+  assert(key && ecount_buf && num);
+  assert(len == 0 || (in && out));
   assert(*num < 16);
   assert((16 % sizeof(size_t)) == 0);
 
diff --git a/src/crypto/modes/gcm_test.c b/src/crypto/modes/gcm_test.c
index 3548c81..a8819ea 100644
--- a/src/crypto/modes/gcm_test.c
+++ b/src/crypto/modes/gcm_test.c
@@ -347,6 +347,9 @@
   }
 
   out = OPENSSL_malloc(plaintext_len);
+  if (out == NULL) {
+    goto out;
+  }
   if (AES_set_encrypt_key(key, key_len*8, &aes_key)) {
     fprintf(stderr, "%u: AES_set_encrypt_key failed.\n", test_num);
     goto out;
diff --git a/src/crypto/obj/obj.c b/src/crypto/obj/obj.c
index 511aba3..bf16d17 100644
--- a/src/crypto/obj/obj.c
+++ b/src/crypto/obj/obj.c
@@ -167,18 +167,18 @@
   return memcmp(a->data, b->data, a->length);
 }
 
-/* nids_cmp is called to search the kNIDsInOIDOrder array. The |key| argument
- * is an |ASN1_OBJECT|* that we're looking for and |element| is a pointer to an
+/* obj_cmp is called to search the kNIDsInOIDOrder array. The |key| argument is
+ * an |ASN1_OBJECT|* that we're looking for and |element| is a pointer to an
  * unsigned int in the array. */
 static int obj_cmp(const void *key, const void *element) {
-  int j;
-  unsigned nid = *((unsigned*) element);
+  unsigned nid = *((const unsigned*) element);
   const ASN1_OBJECT *a = key;
   const ASN1_OBJECT *b = &kObjects[nid];
 
-  j = a->length - b->length;
-  if (j) {
-    return j;
+  if (a->length < b->length) {
+    return -1;
+  } else if (a->length > b->length) {
+    return 1;
   }
   return memcmp(a->data, b->data, a->length);
 }
diff --git a/src/crypto/obj/obj_dat.h b/src/crypto/obj/obj_dat.h
index 2584d87..517dc49 100644
--- a/src/crypto/obj/obj_dat.h
+++ b/src/crypto/obj/obj_dat.h
@@ -59,11 +59,11 @@
  * [including the GNU Public Licence.] */
 
 #define NUM_NID 948
-#define NUM_SN 941
-#define NUM_LN 941
-#define NUM_OBJ 883
+#define NUM_SN 940
+#define NUM_LN 940
+#define NUM_OBJ 882
 
-static const unsigned char lvalues[6182]={
+static const unsigned char lvalues[6176]={
 0x2A,0x86,0x48,0x86,0xF7,0x0D,               /* [  0] OBJ_rsadsi */
 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,          /* [  6] OBJ_pkcs */
 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02,     /* [ 13] OBJ_md2 */
@@ -160,787 +160,786 @@
 0x2B,0x24,0x03,0x02,0x01,                    /* [597] OBJ_ripemd160 */
 0x2B,0x24,0x03,0x03,0x01,0x02,               /* [602] OBJ_ripemd160WithRSA */
 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x08,     /* [608] OBJ_rc5_cbc */
-0x29,0x01,0x01,0x85,0x1A,0x01,               /* [616] OBJ_rle_compression */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x08,/* [622] OBJ_zlib_compression */
-0x55,0x1D,0x25,                              /* [633] OBJ_ext_key_usage */
-0x2B,0x06,0x01,0x05,0x05,0x07,               /* [636] OBJ_id_pkix */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x03,          /* [642] OBJ_id_kp */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01,     /* [649] OBJ_server_auth */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,     /* [657] OBJ_client_auth */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x03,     /* [665] OBJ_code_sign */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x04,     /* [673] OBJ_email_protect */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x08,     /* [681] OBJ_time_stamp */
-0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x15,/* [689] OBJ_ms_code_ind */
-0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x16,/* [699] OBJ_ms_code_com */
-0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x01,/* [709] OBJ_ms_ctl_sign */
-0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x03,/* [719] OBJ_ms_sgc */
-0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x04,/* [729] OBJ_ms_efs */
-0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x04,0x01,/* [739] OBJ_ns_sgc */
-0x55,0x1D,0x1B,                              /* [748] OBJ_delta_crl */
-0x55,0x1D,0x15,                              /* [751] OBJ_crl_reason */
-0x55,0x1D,0x18,                              /* [754] OBJ_invalidity_date */
-0x2B,0x65,0x01,0x04,0x01,                    /* [757] OBJ_sxnet */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x01,/* [762] OBJ_pbe_WithSHA1And128BitRC4 */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x02,/* [772] OBJ_pbe_WithSHA1And40BitRC4 */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x03,/* [782] OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x04,/* [792] OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x05,/* [802] OBJ_pbe_WithSHA1And128BitRC2_CBC */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x06,/* [812] OBJ_pbe_WithSHA1And40BitRC2_CBC */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x01,/* [822] OBJ_keyBag */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x02,/* [833] OBJ_pkcs8ShroudedKeyBag */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x03,/* [844] OBJ_certBag */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x04,/* [855] OBJ_crlBag */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x05,/* [866] OBJ_secretBag */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x06,/* [877] OBJ_safeContentsBag */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x14,/* [888] OBJ_friendlyName */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x15,/* [897] OBJ_localKeyID */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x16,0x01,/* [906] OBJ_x509Certificate */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x16,0x02,/* [916] OBJ_sdsiCertificate */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x17,0x01,/* [926] OBJ_x509Crl */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0D,/* [936] OBJ_pbes2 */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0E,/* [945] OBJ_pbmac1 */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x07,     /* [954] OBJ_hmacWithSHA1 */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,     /* [962] OBJ_id_qt_cps */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x02,     /* [970] OBJ_id_qt_unotice */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0F,/* [978] OBJ_SMIMECapabilities */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x04,/* [987] OBJ_pbeWithMD2AndRC2_CBC */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x06,/* [996] OBJ_pbeWithMD5AndRC2_CBC */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0A,/* [1005] OBJ_pbeWithSHA1AndDES_CBC */
-0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x0E,/* [1014] OBJ_ms_ext_req */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0E,/* [1024] OBJ_ext_req */
-0x55,0x04,0x29,                              /* [1033] OBJ_name */
-0x55,0x04,0x2E,                              /* [1036] OBJ_dnQualifier */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x01,          /* [1039] OBJ_id_pe */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x30,          /* [1046] OBJ_id_ad */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,     /* [1053] OBJ_info_access */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,     /* [1061] OBJ_ad_OCSP */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,     /* [1069] OBJ_ad_ca_issuers */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x09,     /* [1077] OBJ_OCSP_sign */
-0x2A,                                        /* [1085] OBJ_member_body */
-0x2A,0x86,0x48,                              /* [1086] OBJ_ISO_US */
-0x2A,0x86,0x48,0xCE,0x38,                    /* [1089] OBJ_X9_57 */
-0x2A,0x86,0x48,0xCE,0x38,0x04,               /* [1094] OBJ_X9cm */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,     /* [1100] OBJ_pkcs1 */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,     /* [1108] OBJ_pkcs5 */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,/* [1116] OBJ_SMIME */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,/* [1125] OBJ_id_smime_mod */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,/* [1135] OBJ_id_smime_ct */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,/* [1145] OBJ_id_smime_aa */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,/* [1155] OBJ_id_smime_alg */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x04,/* [1165] OBJ_id_smime_cd */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,/* [1175] OBJ_id_smime_spq */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,/* [1185] OBJ_id_smime_cti */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x01,/* [1195] OBJ_id_smime_mod_cms */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x02,/* [1206] OBJ_id_smime_mod_ess */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x03,/* [1217] OBJ_id_smime_mod_oid */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x04,/* [1228] OBJ_id_smime_mod_msg_v3 */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x05,/* [1239] OBJ_id_smime_mod_ets_eSignature_88 */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x06,/* [1250] OBJ_id_smime_mod_ets_eSignature_97 */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x07,/* [1261] OBJ_id_smime_mod_ets_eSigPolicy_88 */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x08,/* [1272] OBJ_id_smime_mod_ets_eSigPolicy_97 */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x01,/* [1283] OBJ_id_smime_ct_receipt */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x02,/* [1294] OBJ_id_smime_ct_authData */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x03,/* [1305] OBJ_id_smime_ct_publishCert */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x04,/* [1316] OBJ_id_smime_ct_TSTInfo */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x05,/* [1327] OBJ_id_smime_ct_TDTInfo */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x06,/* [1338] OBJ_id_smime_ct_contentInfo */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x07,/* [1349] OBJ_id_smime_ct_DVCSRequestData */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x08,/* [1360] OBJ_id_smime_ct_DVCSResponseData */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x01,/* [1371] OBJ_id_smime_aa_receiptRequest */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x02,/* [1382] OBJ_id_smime_aa_securityLabel */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x03,/* [1393] OBJ_id_smime_aa_mlExpandHistory */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x04,/* [1404] OBJ_id_smime_aa_contentHint */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x05,/* [1415] OBJ_id_smime_aa_msgSigDigest */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x06,/* [1426] OBJ_id_smime_aa_encapContentType */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x07,/* [1437] OBJ_id_smime_aa_contentIdentifier */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x08,/* [1448] OBJ_id_smime_aa_macValue */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x09,/* [1459] OBJ_id_smime_aa_equivalentLabels */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0A,/* [1470] OBJ_id_smime_aa_contentReference */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0B,/* [1481] OBJ_id_smime_aa_encrypKeyPref */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0C,/* [1492] OBJ_id_smime_aa_signingCertificate */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0D,/* [1503] OBJ_id_smime_aa_smimeEncryptCerts */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0E,/* [1514] OBJ_id_smime_aa_timeStampToken */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0F,/* [1525] OBJ_id_smime_aa_ets_sigPolicyId */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x10,/* [1536] OBJ_id_smime_aa_ets_commitmentType */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x11,/* [1547] OBJ_id_smime_aa_ets_signerLocation */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x12,/* [1558] OBJ_id_smime_aa_ets_signerAttr */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x13,/* [1569] OBJ_id_smime_aa_ets_otherSigCert */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x14,/* [1580] OBJ_id_smime_aa_ets_contentTimestamp */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x15,/* [1591] OBJ_id_smime_aa_ets_CertificateRefs */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x16,/* [1602] OBJ_id_smime_aa_ets_RevocationRefs */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x17,/* [1613] OBJ_id_smime_aa_ets_certValues */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x18,/* [1624] OBJ_id_smime_aa_ets_revocationValues */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x19,/* [1635] OBJ_id_smime_aa_ets_escTimeStamp */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1A,/* [1646] OBJ_id_smime_aa_ets_certCRLTimestamp */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1B,/* [1657] OBJ_id_smime_aa_ets_archiveTimeStamp */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1C,/* [1668] OBJ_id_smime_aa_signatureType */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1D,/* [1679] OBJ_id_smime_aa_dvcs_dvc */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x01,/* [1690] OBJ_id_smime_alg_ESDHwith3DES */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x02,/* [1701] OBJ_id_smime_alg_ESDHwithRC2 */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x03,/* [1712] OBJ_id_smime_alg_3DESwrap */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x04,/* [1723] OBJ_id_smime_alg_RC2wrap */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x05,/* [1734] OBJ_id_smime_alg_ESDH */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x06,/* [1745] OBJ_id_smime_alg_CMS3DESwrap */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x07,/* [1756] OBJ_id_smime_alg_CMSRC2wrap */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x04,0x01,/* [1767] OBJ_id_smime_cd_ldap */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,0x01,/* [1778] OBJ_id_smime_spq_ets_sqt_uri */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,0x02,/* [1789] OBJ_id_smime_spq_ets_sqt_unotice */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x01,/* [1800] OBJ_id_smime_cti_ets_proofOfOrigin */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x02,/* [1811] OBJ_id_smime_cti_ets_proofOfReceipt */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x03,/* [1822] OBJ_id_smime_cti_ets_proofOfDelivery */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x04,/* [1833] OBJ_id_smime_cti_ets_proofOfSender */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x05,/* [1844] OBJ_id_smime_cti_ets_proofOfApproval */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x06,/* [1855] OBJ_id_smime_cti_ets_proofOfCreation */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x04,     /* [1866] OBJ_md4 */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x00,          /* [1874] OBJ_id_pkix_mod */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x02,          /* [1881] OBJ_id_qt */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x04,          /* [1888] OBJ_id_it */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x05,          /* [1895] OBJ_id_pkip */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x06,          /* [1902] OBJ_id_alg */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x07,          /* [1909] OBJ_id_cmc */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x08,          /* [1916] OBJ_id_on */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x09,          /* [1923] OBJ_id_pda */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,          /* [1930] OBJ_id_aca */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x0B,          /* [1937] OBJ_id_qcs */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,          /* [1944] OBJ_id_cct */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x01,     /* [1951] OBJ_id_pkix1_explicit_88 */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x02,     /* [1959] OBJ_id_pkix1_implicit_88 */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x03,     /* [1967] OBJ_id_pkix1_explicit_93 */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x04,     /* [1975] OBJ_id_pkix1_implicit_93 */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x05,     /* [1983] OBJ_id_mod_crmf */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x06,     /* [1991] OBJ_id_mod_cmc */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x07,     /* [1999] OBJ_id_mod_kea_profile_88 */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x08,     /* [2007] OBJ_id_mod_kea_profile_93 */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x09,     /* [2015] OBJ_id_mod_cmp */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0A,     /* [2023] OBJ_id_mod_qualified_cert_88 */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0B,     /* [2031] OBJ_id_mod_qualified_cert_93 */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0C,     /* [2039] OBJ_id_mod_attribute_cert */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0D,     /* [2047] OBJ_id_mod_timestamp_protocol */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0E,     /* [2055] OBJ_id_mod_ocsp */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0F,     /* [2063] OBJ_id_mod_dvcs */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x10,     /* [2071] OBJ_id_mod_cmp2000 */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x02,     /* [2079] OBJ_biometricInfo */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x03,     /* [2087] OBJ_qcStatements */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x04,     /* [2095] OBJ_ac_auditEntity */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x05,     /* [2103] OBJ_ac_targeting */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x06,     /* [2111] OBJ_aaControls */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x07,     /* [2119] OBJ_sbgp_ipAddrBlock */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x08,     /* [2127] OBJ_sbgp_autonomousSysNum */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x09,     /* [2135] OBJ_sbgp_routerIdentifier */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x03,     /* [2143] OBJ_textNotice */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x05,     /* [2151] OBJ_ipsecEndSystem */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x06,     /* [2159] OBJ_ipsecTunnel */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x07,     /* [2167] OBJ_ipsecUser */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x0A,     /* [2175] OBJ_dvcs */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x01,     /* [2183] OBJ_id_it_caProtEncCert */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x02,     /* [2191] OBJ_id_it_signKeyPairTypes */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x03,     /* [2199] OBJ_id_it_encKeyPairTypes */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x04,     /* [2207] OBJ_id_it_preferredSymmAlg */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x05,     /* [2215] OBJ_id_it_caKeyUpdateInfo */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x06,     /* [2223] OBJ_id_it_currentCRL */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x07,     /* [2231] OBJ_id_it_unsupportedOIDs */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x08,     /* [2239] OBJ_id_it_subscriptionRequest */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x09,     /* [2247] OBJ_id_it_subscriptionResponse */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0A,     /* [2255] OBJ_id_it_keyPairParamReq */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0B,     /* [2263] OBJ_id_it_keyPairParamRep */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0C,     /* [2271] OBJ_id_it_revPassphrase */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0D,     /* [2279] OBJ_id_it_implicitConfirm */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0E,     /* [2287] OBJ_id_it_confirmWaitTime */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0F,     /* [2295] OBJ_id_it_origPKIMessage */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,     /* [2303] OBJ_id_regCtrl */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,     /* [2311] OBJ_id_regInfo */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x01,/* [2319] OBJ_id_regCtrl_regToken */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x02,/* [2328] OBJ_id_regCtrl_authenticator */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x03,/* [2337] OBJ_id_regCtrl_pkiPublicationInfo */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x04,/* [2346] OBJ_id_regCtrl_pkiArchiveOptions */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x05,/* [2355] OBJ_id_regCtrl_oldCertID */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x06,/* [2364] OBJ_id_regCtrl_protocolEncrKey */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,0x01,/* [2373] OBJ_id_regInfo_utf8Pairs */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,0x02,/* [2382] OBJ_id_regInfo_certReq */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x01,     /* [2391] OBJ_id_alg_des40 */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x02,     /* [2399] OBJ_id_alg_noSignature */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x03,     /* [2407] OBJ_id_alg_dh_sig_hmac_sha1 */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x04,     /* [2415] OBJ_id_alg_dh_pop */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x01,     /* [2423] OBJ_id_cmc_statusInfo */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x02,     /* [2431] OBJ_id_cmc_identification */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x03,     /* [2439] OBJ_id_cmc_identityProof */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x04,     /* [2447] OBJ_id_cmc_dataReturn */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x05,     /* [2455] OBJ_id_cmc_transactionId */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x06,     /* [2463] OBJ_id_cmc_senderNonce */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x07,     /* [2471] OBJ_id_cmc_recipientNonce */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x08,     /* [2479] OBJ_id_cmc_addExtensions */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x09,     /* [2487] OBJ_id_cmc_encryptedPOP */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0A,     /* [2495] OBJ_id_cmc_decryptedPOP */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0B,     /* [2503] OBJ_id_cmc_lraPOPWitness */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0F,     /* [2511] OBJ_id_cmc_getCert */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x10,     /* [2519] OBJ_id_cmc_getCRL */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x11,     /* [2527] OBJ_id_cmc_revokeRequest */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x12,     /* [2535] OBJ_id_cmc_regInfo */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x13,     /* [2543] OBJ_id_cmc_responseInfo */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x15,     /* [2551] OBJ_id_cmc_queryPending */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x16,     /* [2559] OBJ_id_cmc_popLinkRandom */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x17,     /* [2567] OBJ_id_cmc_popLinkWitness */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x18,     /* [2575] OBJ_id_cmc_confirmCertAcceptance */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x01,     /* [2583] OBJ_id_on_personalData */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x01,     /* [2591] OBJ_id_pda_dateOfBirth */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x02,     /* [2599] OBJ_id_pda_placeOfBirth */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x03,     /* [2607] OBJ_id_pda_gender */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x04,     /* [2615] OBJ_id_pda_countryOfCitizenship */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x05,     /* [2623] OBJ_id_pda_countryOfResidence */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x01,     /* [2631] OBJ_id_aca_authenticationInfo */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x02,     /* [2639] OBJ_id_aca_accessIdentity */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x03,     /* [2647] OBJ_id_aca_chargingIdentity */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x04,     /* [2655] OBJ_id_aca_group */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x05,     /* [2663] OBJ_id_aca_role */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x0B,0x01,     /* [2671] OBJ_id_qcs_pkixQCSyntax_v1 */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x01,     /* [2679] OBJ_id_cct_crs */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x02,     /* [2687] OBJ_id_cct_PKIData */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x03,     /* [2695] OBJ_id_cct_PKIResponse */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x03,     /* [2703] OBJ_ad_timeStamping */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x04,     /* [2711] OBJ_ad_dvcs */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x01,/* [2719] OBJ_id_pkix_OCSP_basic */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x02,/* [2728] OBJ_id_pkix_OCSP_Nonce */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x03,/* [2737] OBJ_id_pkix_OCSP_CrlID */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x04,/* [2746] OBJ_id_pkix_OCSP_acceptableResponses */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x05,/* [2755] OBJ_id_pkix_OCSP_noCheck */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x06,/* [2764] OBJ_id_pkix_OCSP_archiveCutoff */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x07,/* [2773] OBJ_id_pkix_OCSP_serviceLocator */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x08,/* [2782] OBJ_id_pkix_OCSP_extendedStatus */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x09,/* [2791] OBJ_id_pkix_OCSP_valid */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x0A,/* [2800] OBJ_id_pkix_OCSP_path */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x0B,/* [2809] OBJ_id_pkix_OCSP_trustRoot */
-0x2B,0x0E,0x03,0x02,                         /* [2818] OBJ_algorithm */
-0x2B,0x0E,0x03,0x02,0x0B,                    /* [2822] OBJ_rsaSignature */
-0x55,0x08,                                   /* [2827] OBJ_X500algorithms */
-0x2B,                                        /* [2829] OBJ_org */
-0x2B,0x06,                                   /* [2830] OBJ_dod */
-0x2B,0x06,0x01,                              /* [2832] OBJ_iana */
-0x2B,0x06,0x01,0x01,                         /* [2835] OBJ_Directory */
-0x2B,0x06,0x01,0x02,                         /* [2839] OBJ_Management */
-0x2B,0x06,0x01,0x03,                         /* [2843] OBJ_Experimental */
-0x2B,0x06,0x01,0x04,                         /* [2847] OBJ_Private */
-0x2B,0x06,0x01,0x05,                         /* [2851] OBJ_Security */
-0x2B,0x06,0x01,0x06,                         /* [2855] OBJ_SNMPv2 */
-0x2B,0x06,0x01,0x07,                         /* [2859] OBJ_Mail */
-0x2B,0x06,0x01,0x04,0x01,                    /* [2863] OBJ_Enterprises */
-0x2B,0x06,0x01,0x04,0x01,0x8B,0x3A,0x82,0x58,/* [2868] OBJ_dcObject */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x19,/* [2877] OBJ_domainComponent */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0D,/* [2887] OBJ_Domain */
-0x55,0x01,0x05,                              /* [2897] OBJ_selected_attribute_types */
-0x55,0x01,0x05,0x37,                         /* [2900] OBJ_clearance */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x03,/* [2904] OBJ_md4WithRSAEncryption */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0A,     /* [2913] OBJ_ac_proxying */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0B,     /* [2921] OBJ_sinfo_access */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x06,     /* [2929] OBJ_id_aca_encAttrs */
-0x55,0x04,0x48,                              /* [2937] OBJ_role */
-0x55,0x1D,0x24,                              /* [2940] OBJ_policy_constraints */
-0x55,0x1D,0x37,                              /* [2943] OBJ_target_information */
-0x55,0x1D,0x38,                              /* [2946] OBJ_no_rev_avail */
-0x2A,0x86,0x48,0xCE,0x3D,                    /* [2949] OBJ_ansi_X9_62 */
-0x2A,0x86,0x48,0xCE,0x3D,0x01,0x01,          /* [2954] OBJ_X9_62_prime_field */
-0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,          /* [2961] OBJ_X9_62_characteristic_two_field */
-0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,          /* [2968] OBJ_X9_62_id_ecPublicKey */
-0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01,     /* [2975] OBJ_X9_62_prime192v1 */
-0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02,     /* [2983] OBJ_X9_62_prime192v2 */
-0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03,     /* [2991] OBJ_X9_62_prime192v3 */
-0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04,     /* [2999] OBJ_X9_62_prime239v1 */
-0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05,     /* [3007] OBJ_X9_62_prime239v2 */
-0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06,     /* [3015] OBJ_X9_62_prime239v3 */
-0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07,     /* [3023] OBJ_X9_62_prime256v1 */
-0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,          /* [3031] OBJ_ecdsa_with_SHA1 */
-0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x01,/* [3038] OBJ_ms_csp_name */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x01,/* [3047] OBJ_aes_128_ecb */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x02,/* [3056] OBJ_aes_128_cbc */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x03,/* [3065] OBJ_aes_128_ofb128 */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x04,/* [3074] OBJ_aes_128_cfb128 */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x15,/* [3083] OBJ_aes_192_ecb */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x16,/* [3092] OBJ_aes_192_cbc */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x17,/* [3101] OBJ_aes_192_ofb128 */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x18,/* [3110] OBJ_aes_192_cfb128 */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x29,/* [3119] OBJ_aes_256_ecb */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2A,/* [3128] OBJ_aes_256_cbc */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2B,/* [3137] OBJ_aes_256_ofb128 */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2C,/* [3146] OBJ_aes_256_cfb128 */
-0x55,0x1D,0x17,                              /* [3155] OBJ_hold_instruction_code */
-0x2A,0x86,0x48,0xCE,0x38,0x02,0x01,          /* [3158] OBJ_hold_instruction_none */
-0x2A,0x86,0x48,0xCE,0x38,0x02,0x02,          /* [3165] OBJ_hold_instruction_call_issuer */
-0x2A,0x86,0x48,0xCE,0x38,0x02,0x03,          /* [3172] OBJ_hold_instruction_reject */
-0x09,                                        /* [3179] OBJ_data */
-0x09,0x92,0x26,                              /* [3180] OBJ_pss */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,          /* [3183] OBJ_ucl */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,     /* [3190] OBJ_pilot */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,/* [3198] OBJ_pilotAttributeType */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,/* [3207] OBJ_pilotAttributeSyntax */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,/* [3216] OBJ_pilotObjectClass */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x0A,/* [3225] OBJ_pilotGroups */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,0x04,/* [3234] OBJ_iA5StringSyntax */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,0x05,/* [3244] OBJ_caseIgnoreIA5StringSyntax */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x03,/* [3254] OBJ_pilotObject */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x04,/* [3264] OBJ_pilotPerson */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x05,/* [3274] OBJ_account */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x06,/* [3284] OBJ_document */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x07,/* [3294] OBJ_room */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x09,/* [3304] OBJ_documentSeries */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0E,/* [3314] OBJ_rFC822localPart */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0F,/* [3324] OBJ_dNSDomain */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x11,/* [3334] OBJ_domainRelatedObject */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x12,/* [3344] OBJ_friendlyCountry */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x13,/* [3354] OBJ_simpleSecurityObject */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x14,/* [3364] OBJ_pilotOrganization */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x15,/* [3374] OBJ_pilotDSA */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x16,/* [3384] OBJ_qualityLabelledData */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x01,/* [3394] OBJ_userId */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x02,/* [3404] OBJ_textEncodedORAddress */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x03,/* [3414] OBJ_rfc822Mailbox */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x04,/* [3424] OBJ_info */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x05,/* [3434] OBJ_favouriteDrink */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x06,/* [3444] OBJ_roomNumber */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x07,/* [3454] OBJ_photo */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x08,/* [3464] OBJ_userClass */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x09,/* [3474] OBJ_host */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0A,/* [3484] OBJ_manager */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0B,/* [3494] OBJ_documentIdentifier */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0C,/* [3504] OBJ_documentTitle */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0D,/* [3514] OBJ_documentVersion */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0E,/* [3524] OBJ_documentAuthor */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0F,/* [3534] OBJ_documentLocation */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x14,/* [3544] OBJ_homeTelephoneNumber */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x15,/* [3554] OBJ_secretary */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x16,/* [3564] OBJ_otherMailbox */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x17,/* [3574] OBJ_lastModifiedTime */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x18,/* [3584] OBJ_lastModifiedBy */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1A,/* [3594] OBJ_aRecord */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1B,/* [3604] OBJ_pilotAttributeType27 */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1C,/* [3614] OBJ_mXRecord */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1D,/* [3624] OBJ_nSRecord */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1E,/* [3634] OBJ_sOARecord */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1F,/* [3644] OBJ_cNAMERecord */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x25,/* [3654] OBJ_associatedDomain */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x26,/* [3664] OBJ_associatedName */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x27,/* [3674] OBJ_homePostalAddress */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x28,/* [3684] OBJ_personalTitle */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x29,/* [3694] OBJ_mobileTelephoneNumber */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2A,/* [3704] OBJ_pagerTelephoneNumber */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2B,/* [3714] OBJ_friendlyCountryName */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2D,/* [3724] OBJ_organizationalStatus */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2E,/* [3734] OBJ_janetMailbox */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2F,/* [3744] OBJ_mailPreferenceOption */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x30,/* [3754] OBJ_buildingName */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x31,/* [3764] OBJ_dSAQuality */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x32,/* [3774] OBJ_singleLevelQuality */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x33,/* [3784] OBJ_subtreeMinimumQuality */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x34,/* [3794] OBJ_subtreeMaximumQuality */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x35,/* [3804] OBJ_personalSignature */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x36,/* [3814] OBJ_dITRedirect */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x37,/* [3824] OBJ_audio */
-0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x38,/* [3834] OBJ_documentPublisher */
-0x55,0x04,0x2D,                              /* [3844] OBJ_x500UniqueIdentifier */
-0x2B,0x06,0x01,0x07,0x01,                    /* [3847] OBJ_mime_mhs */
-0x2B,0x06,0x01,0x07,0x01,0x01,               /* [3852] OBJ_mime_mhs_headings */
-0x2B,0x06,0x01,0x07,0x01,0x02,               /* [3858] OBJ_mime_mhs_bodies */
-0x2B,0x06,0x01,0x07,0x01,0x01,0x01,          /* [3864] OBJ_id_hex_partial_message */
-0x2B,0x06,0x01,0x07,0x01,0x01,0x02,          /* [3871] OBJ_id_hex_multipart_message */
-0x55,0x04,0x2C,                              /* [3878] OBJ_generationQualifier */
-0x55,0x04,0x41,                              /* [3881] OBJ_pseudonym */
-0x67,0x2A,                                   /* [3884] OBJ_id_set */
-0x67,0x2A,0x00,                              /* [3886] OBJ_set_ctype */
-0x67,0x2A,0x01,                              /* [3889] OBJ_set_msgExt */
-0x67,0x2A,0x03,                              /* [3892] OBJ_set_attr */
-0x67,0x2A,0x05,                              /* [3895] OBJ_set_policy */
-0x67,0x2A,0x07,                              /* [3898] OBJ_set_certExt */
-0x67,0x2A,0x08,                              /* [3901] OBJ_set_brand */
-0x67,0x2A,0x00,0x00,                         /* [3904] OBJ_setct_PANData */
-0x67,0x2A,0x00,0x01,                         /* [3908] OBJ_setct_PANToken */
-0x67,0x2A,0x00,0x02,                         /* [3912] OBJ_setct_PANOnly */
-0x67,0x2A,0x00,0x03,                         /* [3916] OBJ_setct_OIData */
-0x67,0x2A,0x00,0x04,                         /* [3920] OBJ_setct_PI */
-0x67,0x2A,0x00,0x05,                         /* [3924] OBJ_setct_PIData */
-0x67,0x2A,0x00,0x06,                         /* [3928] OBJ_setct_PIDataUnsigned */
-0x67,0x2A,0x00,0x07,                         /* [3932] OBJ_setct_HODInput */
-0x67,0x2A,0x00,0x08,                         /* [3936] OBJ_setct_AuthResBaggage */
-0x67,0x2A,0x00,0x09,                         /* [3940] OBJ_setct_AuthRevReqBaggage */
-0x67,0x2A,0x00,0x0A,                         /* [3944] OBJ_setct_AuthRevResBaggage */
-0x67,0x2A,0x00,0x0B,                         /* [3948] OBJ_setct_CapTokenSeq */
-0x67,0x2A,0x00,0x0C,                         /* [3952] OBJ_setct_PInitResData */
-0x67,0x2A,0x00,0x0D,                         /* [3956] OBJ_setct_PI_TBS */
-0x67,0x2A,0x00,0x0E,                         /* [3960] OBJ_setct_PResData */
-0x67,0x2A,0x00,0x10,                         /* [3964] OBJ_setct_AuthReqTBS */
-0x67,0x2A,0x00,0x11,                         /* [3968] OBJ_setct_AuthResTBS */
-0x67,0x2A,0x00,0x12,                         /* [3972] OBJ_setct_AuthResTBSX */
-0x67,0x2A,0x00,0x13,                         /* [3976] OBJ_setct_AuthTokenTBS */
-0x67,0x2A,0x00,0x14,                         /* [3980] OBJ_setct_CapTokenData */
-0x67,0x2A,0x00,0x15,                         /* [3984] OBJ_setct_CapTokenTBS */
-0x67,0x2A,0x00,0x16,                         /* [3988] OBJ_setct_AcqCardCodeMsg */
-0x67,0x2A,0x00,0x17,                         /* [3992] OBJ_setct_AuthRevReqTBS */
-0x67,0x2A,0x00,0x18,                         /* [3996] OBJ_setct_AuthRevResData */
-0x67,0x2A,0x00,0x19,                         /* [4000] OBJ_setct_AuthRevResTBS */
-0x67,0x2A,0x00,0x1A,                         /* [4004] OBJ_setct_CapReqTBS */
-0x67,0x2A,0x00,0x1B,                         /* [4008] OBJ_setct_CapReqTBSX */
-0x67,0x2A,0x00,0x1C,                         /* [4012] OBJ_setct_CapResData */
-0x67,0x2A,0x00,0x1D,                         /* [4016] OBJ_setct_CapRevReqTBS */
-0x67,0x2A,0x00,0x1E,                         /* [4020] OBJ_setct_CapRevReqTBSX */
-0x67,0x2A,0x00,0x1F,                         /* [4024] OBJ_setct_CapRevResData */
-0x67,0x2A,0x00,0x20,                         /* [4028] OBJ_setct_CredReqTBS */
-0x67,0x2A,0x00,0x21,                         /* [4032] OBJ_setct_CredReqTBSX */
-0x67,0x2A,0x00,0x22,                         /* [4036] OBJ_setct_CredResData */
-0x67,0x2A,0x00,0x23,                         /* [4040] OBJ_setct_CredRevReqTBS */
-0x67,0x2A,0x00,0x24,                         /* [4044] OBJ_setct_CredRevReqTBSX */
-0x67,0x2A,0x00,0x25,                         /* [4048] OBJ_setct_CredRevResData */
-0x67,0x2A,0x00,0x26,                         /* [4052] OBJ_setct_PCertReqData */
-0x67,0x2A,0x00,0x27,                         /* [4056] OBJ_setct_PCertResTBS */
-0x67,0x2A,0x00,0x28,                         /* [4060] OBJ_setct_BatchAdminReqData */
-0x67,0x2A,0x00,0x29,                         /* [4064] OBJ_setct_BatchAdminResData */
-0x67,0x2A,0x00,0x2A,                         /* [4068] OBJ_setct_CardCInitResTBS */
-0x67,0x2A,0x00,0x2B,                         /* [4072] OBJ_setct_MeAqCInitResTBS */
-0x67,0x2A,0x00,0x2C,                         /* [4076] OBJ_setct_RegFormResTBS */
-0x67,0x2A,0x00,0x2D,                         /* [4080] OBJ_setct_CertReqData */
-0x67,0x2A,0x00,0x2E,                         /* [4084] OBJ_setct_CertReqTBS */
-0x67,0x2A,0x00,0x2F,                         /* [4088] OBJ_setct_CertResData */
-0x67,0x2A,0x00,0x30,                         /* [4092] OBJ_setct_CertInqReqTBS */
-0x67,0x2A,0x00,0x31,                         /* [4096] OBJ_setct_ErrorTBS */
-0x67,0x2A,0x00,0x32,                         /* [4100] OBJ_setct_PIDualSignedTBE */
-0x67,0x2A,0x00,0x33,                         /* [4104] OBJ_setct_PIUnsignedTBE */
-0x67,0x2A,0x00,0x34,                         /* [4108] OBJ_setct_AuthReqTBE */
-0x67,0x2A,0x00,0x35,                         /* [4112] OBJ_setct_AuthResTBE */
-0x67,0x2A,0x00,0x36,                         /* [4116] OBJ_setct_AuthResTBEX */
-0x67,0x2A,0x00,0x37,                         /* [4120] OBJ_setct_AuthTokenTBE */
-0x67,0x2A,0x00,0x38,                         /* [4124] OBJ_setct_CapTokenTBE */
-0x67,0x2A,0x00,0x39,                         /* [4128] OBJ_setct_CapTokenTBEX */
-0x67,0x2A,0x00,0x3A,                         /* [4132] OBJ_setct_AcqCardCodeMsgTBE */
-0x67,0x2A,0x00,0x3B,                         /* [4136] OBJ_setct_AuthRevReqTBE */
-0x67,0x2A,0x00,0x3C,                         /* [4140] OBJ_setct_AuthRevResTBE */
-0x67,0x2A,0x00,0x3D,                         /* [4144] OBJ_setct_AuthRevResTBEB */
-0x67,0x2A,0x00,0x3E,                         /* [4148] OBJ_setct_CapReqTBE */
-0x67,0x2A,0x00,0x3F,                         /* [4152] OBJ_setct_CapReqTBEX */
-0x67,0x2A,0x00,0x40,                         /* [4156] OBJ_setct_CapResTBE */
-0x67,0x2A,0x00,0x41,                         /* [4160] OBJ_setct_CapRevReqTBE */
-0x67,0x2A,0x00,0x42,                         /* [4164] OBJ_setct_CapRevReqTBEX */
-0x67,0x2A,0x00,0x43,                         /* [4168] OBJ_setct_CapRevResTBE */
-0x67,0x2A,0x00,0x44,                         /* [4172] OBJ_setct_CredReqTBE */
-0x67,0x2A,0x00,0x45,                         /* [4176] OBJ_setct_CredReqTBEX */
-0x67,0x2A,0x00,0x46,                         /* [4180] OBJ_setct_CredResTBE */
-0x67,0x2A,0x00,0x47,                         /* [4184] OBJ_setct_CredRevReqTBE */
-0x67,0x2A,0x00,0x48,                         /* [4188] OBJ_setct_CredRevReqTBEX */
-0x67,0x2A,0x00,0x49,                         /* [4192] OBJ_setct_CredRevResTBE */
-0x67,0x2A,0x00,0x4A,                         /* [4196] OBJ_setct_BatchAdminReqTBE */
-0x67,0x2A,0x00,0x4B,                         /* [4200] OBJ_setct_BatchAdminResTBE */
-0x67,0x2A,0x00,0x4C,                         /* [4204] OBJ_setct_RegFormReqTBE */
-0x67,0x2A,0x00,0x4D,                         /* [4208] OBJ_setct_CertReqTBE */
-0x67,0x2A,0x00,0x4E,                         /* [4212] OBJ_setct_CertReqTBEX */
-0x67,0x2A,0x00,0x4F,                         /* [4216] OBJ_setct_CertResTBE */
-0x67,0x2A,0x00,0x50,                         /* [4220] OBJ_setct_CRLNotificationTBS */
-0x67,0x2A,0x00,0x51,                         /* [4224] OBJ_setct_CRLNotificationResTBS */
-0x67,0x2A,0x00,0x52,                         /* [4228] OBJ_setct_BCIDistributionTBS */
-0x67,0x2A,0x01,0x01,                         /* [4232] OBJ_setext_genCrypt */
-0x67,0x2A,0x01,0x03,                         /* [4236] OBJ_setext_miAuth */
-0x67,0x2A,0x01,0x04,                         /* [4240] OBJ_setext_pinSecure */
-0x67,0x2A,0x01,0x05,                         /* [4244] OBJ_setext_pinAny */
-0x67,0x2A,0x01,0x07,                         /* [4248] OBJ_setext_track2 */
-0x67,0x2A,0x01,0x08,                         /* [4252] OBJ_setext_cv */
-0x67,0x2A,0x05,0x00,                         /* [4256] OBJ_set_policy_root */
-0x67,0x2A,0x07,0x00,                         /* [4260] OBJ_setCext_hashedRoot */
-0x67,0x2A,0x07,0x01,                         /* [4264] OBJ_setCext_certType */
-0x67,0x2A,0x07,0x02,                         /* [4268] OBJ_setCext_merchData */
-0x67,0x2A,0x07,0x03,                         /* [4272] OBJ_setCext_cCertRequired */
-0x67,0x2A,0x07,0x04,                         /* [4276] OBJ_setCext_tunneling */
-0x67,0x2A,0x07,0x05,                         /* [4280] OBJ_setCext_setExt */
-0x67,0x2A,0x07,0x06,                         /* [4284] OBJ_setCext_setQualf */
-0x67,0x2A,0x07,0x07,                         /* [4288] OBJ_setCext_PGWYcapabilities */
-0x67,0x2A,0x07,0x08,                         /* [4292] OBJ_setCext_TokenIdentifier */
-0x67,0x2A,0x07,0x09,                         /* [4296] OBJ_setCext_Track2Data */
-0x67,0x2A,0x07,0x0A,                         /* [4300] OBJ_setCext_TokenType */
-0x67,0x2A,0x07,0x0B,                         /* [4304] OBJ_setCext_IssuerCapabilities */
-0x67,0x2A,0x03,0x00,                         /* [4308] OBJ_setAttr_Cert */
-0x67,0x2A,0x03,0x01,                         /* [4312] OBJ_setAttr_PGWYcap */
-0x67,0x2A,0x03,0x02,                         /* [4316] OBJ_setAttr_TokenType */
-0x67,0x2A,0x03,0x03,                         /* [4320] OBJ_setAttr_IssCap */
-0x67,0x2A,0x03,0x00,0x00,                    /* [4324] OBJ_set_rootKeyThumb */
-0x67,0x2A,0x03,0x00,0x01,                    /* [4329] OBJ_set_addPolicy */
-0x67,0x2A,0x03,0x02,0x01,                    /* [4334] OBJ_setAttr_Token_EMV */
-0x67,0x2A,0x03,0x02,0x02,                    /* [4339] OBJ_setAttr_Token_B0Prime */
-0x67,0x2A,0x03,0x03,0x03,                    /* [4344] OBJ_setAttr_IssCap_CVM */
-0x67,0x2A,0x03,0x03,0x04,                    /* [4349] OBJ_setAttr_IssCap_T2 */
-0x67,0x2A,0x03,0x03,0x05,                    /* [4354] OBJ_setAttr_IssCap_Sig */
-0x67,0x2A,0x03,0x03,0x03,0x01,               /* [4359] OBJ_setAttr_GenCryptgrm */
-0x67,0x2A,0x03,0x03,0x04,0x01,               /* [4365] OBJ_setAttr_T2Enc */
-0x67,0x2A,0x03,0x03,0x04,0x02,               /* [4371] OBJ_setAttr_T2cleartxt */
-0x67,0x2A,0x03,0x03,0x05,0x01,               /* [4377] OBJ_setAttr_TokICCsig */
-0x67,0x2A,0x03,0x03,0x05,0x02,               /* [4383] OBJ_setAttr_SecDevSig */
-0x67,0x2A,0x08,0x01,                         /* [4389] OBJ_set_brand_IATA_ATA */
-0x67,0x2A,0x08,0x1E,                         /* [4393] OBJ_set_brand_Diners */
-0x67,0x2A,0x08,0x22,                         /* [4397] OBJ_set_brand_AmericanExpress */
-0x67,0x2A,0x08,0x23,                         /* [4401] OBJ_set_brand_JCB */
-0x67,0x2A,0x08,0x04,                         /* [4405] OBJ_set_brand_Visa */
-0x67,0x2A,0x08,0x05,                         /* [4409] OBJ_set_brand_MasterCard */
-0x67,0x2A,0x08,0xAE,0x7B,                    /* [4413] OBJ_set_brand_Novus */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x0A,     /* [4418] OBJ_des_cdmf */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x06,/* [4426] OBJ_rsaOAEPEncryptionSET */
-0x67,                                        /* [4435] OBJ_international_organizations */
-0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x02,/* [4436] OBJ_ms_smartcard_login */
-0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x03,/* [4446] OBJ_ms_upn */
-0x55,0x04,0x09,                              /* [4456] OBJ_streetAddress */
-0x55,0x04,0x11,                              /* [4459] OBJ_postalCode */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x15,          /* [4462] OBJ_id_ppl */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0E,     /* [4469] OBJ_proxyCertInfo */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x00,     /* [4477] OBJ_id_ppl_anyLanguage */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x01,     /* [4485] OBJ_id_ppl_inheritAll */
-0x55,0x1D,0x1E,                              /* [4493] OBJ_name_constraints */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x02,     /* [4496] OBJ_Independent */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,/* [4504] OBJ_sha256WithRSAEncryption */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0C,/* [4513] OBJ_sha384WithRSAEncryption */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0D,/* [4522] OBJ_sha512WithRSAEncryption */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0E,/* [4531] OBJ_sha224WithRSAEncryption */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,/* [4540] OBJ_sha256 */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,/* [4549] OBJ_sha384 */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,/* [4558] OBJ_sha512 */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04,/* [4567] OBJ_sha224 */
-0x2B,                                        /* [4576] OBJ_identified_organization */
-0x2B,0x81,0x04,                              /* [4577] OBJ_certicom_arc */
-0x67,0x2B,                                   /* [4580] OBJ_wap */
-0x67,0x2B,0x01,                              /* [4582] OBJ_wap_wsg */
-0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,     /* [4585] OBJ_X9_62_id_characteristic_two_basis */
-0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x01,/* [4593] OBJ_X9_62_onBasis */
-0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x02,/* [4602] OBJ_X9_62_tpBasis */
-0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x03,/* [4611] OBJ_X9_62_ppBasis */
-0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x01,     /* [4620] OBJ_X9_62_c2pnb163v1 */
-0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x02,     /* [4628] OBJ_X9_62_c2pnb163v2 */
-0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x03,     /* [4636] OBJ_X9_62_c2pnb163v3 */
-0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x04,     /* [4644] OBJ_X9_62_c2pnb176v1 */
-0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x05,     /* [4652] OBJ_X9_62_c2tnb191v1 */
-0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x06,     /* [4660] OBJ_X9_62_c2tnb191v2 */
-0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x07,     /* [4668] OBJ_X9_62_c2tnb191v3 */
-0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x08,     /* [4676] OBJ_X9_62_c2onb191v4 */
-0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x09,     /* [4684] OBJ_X9_62_c2onb191v5 */
-0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0A,     /* [4692] OBJ_X9_62_c2pnb208w1 */
-0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0B,     /* [4700] OBJ_X9_62_c2tnb239v1 */
-0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0C,     /* [4708] OBJ_X9_62_c2tnb239v2 */
-0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0D,     /* [4716] OBJ_X9_62_c2tnb239v3 */
-0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0E,     /* [4724] OBJ_X9_62_c2onb239v4 */
-0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0F,     /* [4732] OBJ_X9_62_c2onb239v5 */
-0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x10,     /* [4740] OBJ_X9_62_c2pnb272w1 */
-0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x11,     /* [4748] OBJ_X9_62_c2pnb304w1 */
-0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x12,     /* [4756] OBJ_X9_62_c2tnb359v1 */
-0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x13,     /* [4764] OBJ_X9_62_c2pnb368w1 */
-0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x14,     /* [4772] OBJ_X9_62_c2tnb431r1 */
-0x2B,0x81,0x04,0x00,0x06,                    /* [4780] OBJ_secp112r1 */
-0x2B,0x81,0x04,0x00,0x07,                    /* [4785] OBJ_secp112r2 */
-0x2B,0x81,0x04,0x00,0x1C,                    /* [4790] OBJ_secp128r1 */
-0x2B,0x81,0x04,0x00,0x1D,                    /* [4795] OBJ_secp128r2 */
-0x2B,0x81,0x04,0x00,0x09,                    /* [4800] OBJ_secp160k1 */
-0x2B,0x81,0x04,0x00,0x08,                    /* [4805] OBJ_secp160r1 */
-0x2B,0x81,0x04,0x00,0x1E,                    /* [4810] OBJ_secp160r2 */
-0x2B,0x81,0x04,0x00,0x1F,                    /* [4815] OBJ_secp192k1 */
-0x2B,0x81,0x04,0x00,0x20,                    /* [4820] OBJ_secp224k1 */
-0x2B,0x81,0x04,0x00,0x21,                    /* [4825] OBJ_secp224r1 */
-0x2B,0x81,0x04,0x00,0x0A,                    /* [4830] OBJ_secp256k1 */
-0x2B,0x81,0x04,0x00,0x22,                    /* [4835] OBJ_secp384r1 */
-0x2B,0x81,0x04,0x00,0x23,                    /* [4840] OBJ_secp521r1 */
-0x2B,0x81,0x04,0x00,0x04,                    /* [4845] OBJ_sect113r1 */
-0x2B,0x81,0x04,0x00,0x05,                    /* [4850] OBJ_sect113r2 */
-0x2B,0x81,0x04,0x00,0x16,                    /* [4855] OBJ_sect131r1 */
-0x2B,0x81,0x04,0x00,0x17,                    /* [4860] OBJ_sect131r2 */
-0x2B,0x81,0x04,0x00,0x01,                    /* [4865] OBJ_sect163k1 */
-0x2B,0x81,0x04,0x00,0x02,                    /* [4870] OBJ_sect163r1 */
-0x2B,0x81,0x04,0x00,0x0F,                    /* [4875] OBJ_sect163r2 */
-0x2B,0x81,0x04,0x00,0x18,                    /* [4880] OBJ_sect193r1 */
-0x2B,0x81,0x04,0x00,0x19,                    /* [4885] OBJ_sect193r2 */
-0x2B,0x81,0x04,0x00,0x1A,                    /* [4890] OBJ_sect233k1 */
-0x2B,0x81,0x04,0x00,0x1B,                    /* [4895] OBJ_sect233r1 */
-0x2B,0x81,0x04,0x00,0x03,                    /* [4900] OBJ_sect239k1 */
-0x2B,0x81,0x04,0x00,0x10,                    /* [4905] OBJ_sect283k1 */
-0x2B,0x81,0x04,0x00,0x11,                    /* [4910] OBJ_sect283r1 */
-0x2B,0x81,0x04,0x00,0x24,                    /* [4915] OBJ_sect409k1 */
-0x2B,0x81,0x04,0x00,0x25,                    /* [4920] OBJ_sect409r1 */
-0x2B,0x81,0x04,0x00,0x26,                    /* [4925] OBJ_sect571k1 */
-0x2B,0x81,0x04,0x00,0x27,                    /* [4930] OBJ_sect571r1 */
-0x67,0x2B,0x01,0x04,0x01,                    /* [4935] OBJ_wap_wsg_idm_ecid_wtls1 */
-0x67,0x2B,0x01,0x04,0x03,                    /* [4940] OBJ_wap_wsg_idm_ecid_wtls3 */
-0x67,0x2B,0x01,0x04,0x04,                    /* [4945] OBJ_wap_wsg_idm_ecid_wtls4 */
-0x67,0x2B,0x01,0x04,0x05,                    /* [4950] OBJ_wap_wsg_idm_ecid_wtls5 */
-0x67,0x2B,0x01,0x04,0x06,                    /* [4955] OBJ_wap_wsg_idm_ecid_wtls6 */
-0x67,0x2B,0x01,0x04,0x07,                    /* [4960] OBJ_wap_wsg_idm_ecid_wtls7 */
-0x67,0x2B,0x01,0x04,0x08,                    /* [4965] OBJ_wap_wsg_idm_ecid_wtls8 */
-0x67,0x2B,0x01,0x04,0x09,                    /* [4970] OBJ_wap_wsg_idm_ecid_wtls9 */
-0x67,0x2B,0x01,0x04,0x0A,                    /* [4975] OBJ_wap_wsg_idm_ecid_wtls10 */
-0x67,0x2B,0x01,0x04,0x0B,                    /* [4980] OBJ_wap_wsg_idm_ecid_wtls11 */
-0x67,0x2B,0x01,0x04,0x0C,                    /* [4985] OBJ_wap_wsg_idm_ecid_wtls12 */
-0x55,0x1D,0x20,0x00,                         /* [4990] OBJ_any_policy */
-0x55,0x1D,0x21,                              /* [4994] OBJ_policy_mappings */
-0x55,0x1D,0x36,                              /* [4997] OBJ_inhibit_any_policy */
-0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x02,/* [5000] OBJ_camellia_128_cbc */
-0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x03,/* [5011] OBJ_camellia_192_cbc */
-0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x04,/* [5022] OBJ_camellia_256_cbc */
-0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x01,     /* [5033] OBJ_camellia_128_ecb */
-0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x15,     /* [5041] OBJ_camellia_192_ecb */
-0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x29,     /* [5049] OBJ_camellia_256_ecb */
-0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x04,     /* [5057] OBJ_camellia_128_cfb128 */
-0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x18,     /* [5065] OBJ_camellia_192_cfb128 */
-0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2C,     /* [5073] OBJ_camellia_256_cfb128 */
-0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x03,     /* [5081] OBJ_camellia_128_ofb128 */
-0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x17,     /* [5089] OBJ_camellia_192_ofb128 */
-0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2B,     /* [5097] OBJ_camellia_256_ofb128 */
-0x55,0x1D,0x09,                              /* [5105] OBJ_subject_directory_attributes */
-0x55,0x1D,0x1C,                              /* [5108] OBJ_issuing_distribution_point */
-0x55,0x1D,0x1D,                              /* [5111] OBJ_certificate_issuer */
-0x2A,0x83,0x1A,0x8C,0x9A,0x44,               /* [5114] OBJ_kisa */
-0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x03,     /* [5120] OBJ_seed_ecb */
-0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x04,     /* [5128] OBJ_seed_cbc */
-0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x06,     /* [5136] OBJ_seed_ofb128 */
-0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x05,     /* [5144] OBJ_seed_cfb128 */
-0x2B,0x06,0x01,0x05,0x05,0x08,0x01,0x01,     /* [5152] OBJ_hmac_md5 */
-0x2B,0x06,0x01,0x05,0x05,0x08,0x01,0x02,     /* [5160] OBJ_hmac_sha1 */
-0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0D,/* [5168] OBJ_id_PasswordBasedMAC */
-0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x1E,/* [5177] OBJ_id_DHBasedMac */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x10,     /* [5186] OBJ_id_it_suppLangTags */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x05,     /* [5194] OBJ_caRepository */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x09,/* [5202] OBJ_id_smime_ct_compressedData */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x1B,/* [5213] OBJ_id_ct_asciiTextWithCRLF */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x05,/* [5224] OBJ_id_aes128_wrap */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x19,/* [5233] OBJ_id_aes192_wrap */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2D,/* [5242] OBJ_id_aes256_wrap */
-0x2A,0x86,0x48,0xCE,0x3D,0x04,0x02,          /* [5251] OBJ_ecdsa_with_Recommended */
-0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,          /* [5258] OBJ_ecdsa_with_Specified */
-0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x01,     /* [5265] OBJ_ecdsa_with_SHA224 */
-0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02,     /* [5273] OBJ_ecdsa_with_SHA256 */
-0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x03,     /* [5281] OBJ_ecdsa_with_SHA384 */
-0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x04,     /* [5289] OBJ_ecdsa_with_SHA512 */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x06,     /* [5297] OBJ_hmacWithMD5 */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x08,     /* [5305] OBJ_hmacWithSHA224 */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x09,     /* [5313] OBJ_hmacWithSHA256 */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0A,     /* [5321] OBJ_hmacWithSHA384 */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0B,     /* [5329] OBJ_hmacWithSHA512 */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x01,/* [5337] OBJ_dsa_with_SHA224 */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x02,/* [5346] OBJ_dsa_with_SHA256 */
-0x28,0xCF,0x06,0x03,0x00,0x37,               /* [5355] OBJ_whirlpool */
-0x2A,0x85,0x03,0x02,0x02,                    /* [5361] OBJ_cryptopro */
-0x2A,0x85,0x03,0x02,0x09,                    /* [5366] OBJ_cryptocom */
-0x2A,0x85,0x03,0x02,0x02,0x03,               /* [5371] OBJ_id_GostR3411_94_with_GostR3410_2001 */
-0x2A,0x85,0x03,0x02,0x02,0x04,               /* [5377] OBJ_id_GostR3411_94_with_GostR3410_94 */
-0x2A,0x85,0x03,0x02,0x02,0x09,               /* [5383] OBJ_id_GostR3411_94 */
-0x2A,0x85,0x03,0x02,0x02,0x0A,               /* [5389] OBJ_id_HMACGostR3411_94 */
-0x2A,0x85,0x03,0x02,0x02,0x13,               /* [5395] OBJ_id_GostR3410_2001 */
-0x2A,0x85,0x03,0x02,0x02,0x14,               /* [5401] OBJ_id_GostR3410_94 */
-0x2A,0x85,0x03,0x02,0x02,0x15,               /* [5407] OBJ_id_Gost28147_89 */
-0x2A,0x85,0x03,0x02,0x02,0x16,               /* [5413] OBJ_id_Gost28147_89_MAC */
-0x2A,0x85,0x03,0x02,0x02,0x17,               /* [5419] OBJ_id_GostR3411_94_prf */
-0x2A,0x85,0x03,0x02,0x02,0x62,               /* [5425] OBJ_id_GostR3410_2001DH */
-0x2A,0x85,0x03,0x02,0x02,0x63,               /* [5431] OBJ_id_GostR3410_94DH */
-0x2A,0x85,0x03,0x02,0x02,0x0E,0x01,          /* [5437] OBJ_id_Gost28147_89_CryptoPro_KeyMeshing */
-0x2A,0x85,0x03,0x02,0x02,0x0E,0x00,          /* [5444] OBJ_id_Gost28147_89_None_KeyMeshing */
-0x2A,0x85,0x03,0x02,0x02,0x1E,0x00,          /* [5451] OBJ_id_GostR3411_94_TestParamSet */
-0x2A,0x85,0x03,0x02,0x02,0x1E,0x01,          /* [5458] OBJ_id_GostR3411_94_CryptoProParamSet */
-0x2A,0x85,0x03,0x02,0x02,0x1F,0x00,          /* [5465] OBJ_id_Gost28147_89_TestParamSet */
-0x2A,0x85,0x03,0x02,0x02,0x1F,0x01,          /* [5472] OBJ_id_Gost28147_89_CryptoPro_A_ParamSet */
-0x2A,0x85,0x03,0x02,0x02,0x1F,0x02,          /* [5479] OBJ_id_Gost28147_89_CryptoPro_B_ParamSet */
-0x2A,0x85,0x03,0x02,0x02,0x1F,0x03,          /* [5486] OBJ_id_Gost28147_89_CryptoPro_C_ParamSet */
-0x2A,0x85,0x03,0x02,0x02,0x1F,0x04,          /* [5493] OBJ_id_Gost28147_89_CryptoPro_D_ParamSet */
-0x2A,0x85,0x03,0x02,0x02,0x1F,0x05,          /* [5500] OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet */
-0x2A,0x85,0x03,0x02,0x02,0x1F,0x06,          /* [5507] OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet */
-0x2A,0x85,0x03,0x02,0x02,0x1F,0x07,          /* [5514] OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet */
-0x2A,0x85,0x03,0x02,0x02,0x20,0x00,          /* [5521] OBJ_id_GostR3410_94_TestParamSet */
-0x2A,0x85,0x03,0x02,0x02,0x20,0x02,          /* [5528] OBJ_id_GostR3410_94_CryptoPro_A_ParamSet */
-0x2A,0x85,0x03,0x02,0x02,0x20,0x03,          /* [5535] OBJ_id_GostR3410_94_CryptoPro_B_ParamSet */
-0x2A,0x85,0x03,0x02,0x02,0x20,0x04,          /* [5542] OBJ_id_GostR3410_94_CryptoPro_C_ParamSet */
-0x2A,0x85,0x03,0x02,0x02,0x20,0x05,          /* [5549] OBJ_id_GostR3410_94_CryptoPro_D_ParamSet */
-0x2A,0x85,0x03,0x02,0x02,0x21,0x01,          /* [5556] OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet */
-0x2A,0x85,0x03,0x02,0x02,0x21,0x02,          /* [5563] OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet */
-0x2A,0x85,0x03,0x02,0x02,0x21,0x03,          /* [5570] OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet */
-0x2A,0x85,0x03,0x02,0x02,0x23,0x00,          /* [5577] OBJ_id_GostR3410_2001_TestParamSet */
-0x2A,0x85,0x03,0x02,0x02,0x23,0x01,          /* [5584] OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet */
-0x2A,0x85,0x03,0x02,0x02,0x23,0x02,          /* [5591] OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet */
-0x2A,0x85,0x03,0x02,0x02,0x23,0x03,          /* [5598] OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet */
-0x2A,0x85,0x03,0x02,0x02,0x24,0x00,          /* [5605] OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet */
-0x2A,0x85,0x03,0x02,0x02,0x24,0x01,          /* [5612] OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet */
-0x2A,0x85,0x03,0x02,0x02,0x14,0x01,          /* [5619] OBJ_id_GostR3410_94_a */
-0x2A,0x85,0x03,0x02,0x02,0x14,0x02,          /* [5626] OBJ_id_GostR3410_94_aBis */
-0x2A,0x85,0x03,0x02,0x02,0x14,0x03,          /* [5633] OBJ_id_GostR3410_94_b */
-0x2A,0x85,0x03,0x02,0x02,0x14,0x04,          /* [5640] OBJ_id_GostR3410_94_bBis */
-0x2A,0x85,0x03,0x02,0x09,0x01,0x06,0x01,     /* [5647] OBJ_id_Gost28147_89_cc */
-0x2A,0x85,0x03,0x02,0x09,0x01,0x05,0x03,     /* [5655] OBJ_id_GostR3410_94_cc */
-0x2A,0x85,0x03,0x02,0x09,0x01,0x05,0x04,     /* [5663] OBJ_id_GostR3410_2001_cc */
-0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x03,     /* [5671] OBJ_id_GostR3411_94_with_GostR3410_94_cc */
-0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x04,     /* [5679] OBJ_id_GostR3411_94_with_GostR3410_2001_cc */
-0x2A,0x85,0x03,0x02,0x09,0x01,0x08,0x01,     /* [5687] OBJ_id_GostR3410_2001_ParamSet_cc */
-0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x02,/* [5695] OBJ_LocalKeySet */
-0x55,0x1D,0x2E,                              /* [5704] OBJ_freshest_crl */
-0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x03,     /* [5707] OBJ_id_on_permanentIdentifier */
-0x55,0x04,0x0E,                              /* [5715] OBJ_searchGuide */
-0x55,0x04,0x0F,                              /* [5718] OBJ_businessCategory */
-0x55,0x04,0x10,                              /* [5721] OBJ_postalAddress */
-0x55,0x04,0x12,                              /* [5724] OBJ_postOfficeBox */
-0x55,0x04,0x13,                              /* [5727] OBJ_physicalDeliveryOfficeName */
-0x55,0x04,0x14,                              /* [5730] OBJ_telephoneNumber */
-0x55,0x04,0x15,                              /* [5733] OBJ_telexNumber */
-0x55,0x04,0x16,                              /* [5736] OBJ_teletexTerminalIdentifier */
-0x55,0x04,0x17,                              /* [5739] OBJ_facsimileTelephoneNumber */
-0x55,0x04,0x18,                              /* [5742] OBJ_x121Address */
-0x55,0x04,0x19,                              /* [5745] OBJ_internationaliSDNNumber */
-0x55,0x04,0x1A,                              /* [5748] OBJ_registeredAddress */
-0x55,0x04,0x1B,                              /* [5751] OBJ_destinationIndicator */
-0x55,0x04,0x1C,                              /* [5754] OBJ_preferredDeliveryMethod */
-0x55,0x04,0x1D,                              /* [5757] OBJ_presentationAddress */
-0x55,0x04,0x1E,                              /* [5760] OBJ_supportedApplicationContext */
-0x55,0x04,0x1F,                              /* [5763] OBJ_member */
-0x55,0x04,0x20,                              /* [5766] OBJ_owner */
-0x55,0x04,0x21,                              /* [5769] OBJ_roleOccupant */
-0x55,0x04,0x22,                              /* [5772] OBJ_seeAlso */
-0x55,0x04,0x23,                              /* [5775] OBJ_userPassword */
-0x55,0x04,0x24,                              /* [5778] OBJ_userCertificate */
-0x55,0x04,0x25,                              /* [5781] OBJ_cACertificate */
-0x55,0x04,0x26,                              /* [5784] OBJ_authorityRevocationList */
-0x55,0x04,0x27,                              /* [5787] OBJ_certificateRevocationList */
-0x55,0x04,0x28,                              /* [5790] OBJ_crossCertificatePair */
-0x55,0x04,0x2F,                              /* [5793] OBJ_enhancedSearchGuide */
-0x55,0x04,0x30,                              /* [5796] OBJ_protocolInformation */
-0x55,0x04,0x31,                              /* [5799] OBJ_distinguishedName */
-0x55,0x04,0x32,                              /* [5802] OBJ_uniqueMember */
-0x55,0x04,0x33,                              /* [5805] OBJ_houseIdentifier */
-0x55,0x04,0x34,                              /* [5808] OBJ_supportedAlgorithms */
-0x55,0x04,0x35,                              /* [5811] OBJ_deltaRevocationList */
-0x55,0x04,0x36,                              /* [5814] OBJ_dmdName */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x09,/* [5817] OBJ_id_alg_PWRI_KEK */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x06,/* [5828] OBJ_aes_128_gcm */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x07,/* [5837] OBJ_aes_128_ccm */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x08,/* [5846] OBJ_id_aes128_wrap_pad */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1A,/* [5855] OBJ_aes_192_gcm */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1B,/* [5864] OBJ_aes_192_ccm */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1C,/* [5873] OBJ_id_aes192_wrap_pad */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2E,/* [5882] OBJ_aes_256_gcm */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2F,/* [5891] OBJ_aes_256_ccm */
-0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x30,/* [5900] OBJ_id_aes256_wrap_pad */
-0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x02,/* [5909] OBJ_id_camellia128_wrap */
-0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x03,/* [5920] OBJ_id_camellia192_wrap */
-0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x04,/* [5931] OBJ_id_camellia256_wrap */
-0x55,0x1D,0x25,0x00,                         /* [5942] OBJ_anyExtendedKeyUsage */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x08,/* [5946] OBJ_mgf1 */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0A,/* [5955] OBJ_rsassaPss */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x07,/* [5964] OBJ_rsaesOaep */
-0x2A,0x86,0x48,0xCE,0x3E,0x02,0x01,          /* [5973] OBJ_dhpublicnumber */
-0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01,/* [5980] OBJ_brainpoolP160r1 */
-0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x02,/* [5989] OBJ_brainpoolP160t1 */
-0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03,/* [5998] OBJ_brainpoolP192r1 */
-0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x04,/* [6007] OBJ_brainpoolP192t1 */
-0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05,/* [6016] OBJ_brainpoolP224r1 */
-0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x06,/* [6025] OBJ_brainpoolP224t1 */
-0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07,/* [6034] OBJ_brainpoolP256r1 */
-0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x08,/* [6043] OBJ_brainpoolP256t1 */
-0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09,/* [6052] OBJ_brainpoolP320r1 */
-0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0A,/* [6061] OBJ_brainpoolP320t1 */
-0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B,/* [6070] OBJ_brainpoolP384r1 */
-0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0C,/* [6079] OBJ_brainpoolP384t1 */
-0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D,/* [6088] OBJ_brainpoolP512r1 */
-0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0E,/* [6097] OBJ_brainpoolP512t1 */
-0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x09,/* [6106] OBJ_pSpecified */
-0x2B,0x81,0x05,0x10,0x86,0x48,0x3F,0x00,0x02,/* [6115] OBJ_dhSinglePass_stdDH_sha1kdf_scheme */
-0x2B,0x81,0x04,0x01,0x0B,0x00,               /* [6124] OBJ_dhSinglePass_stdDH_sha224kdf_scheme */
-0x2B,0x81,0x04,0x01,0x0B,0x01,               /* [6130] OBJ_dhSinglePass_stdDH_sha256kdf_scheme */
-0x2B,0x81,0x04,0x01,0x0B,0x02,               /* [6136] OBJ_dhSinglePass_stdDH_sha384kdf_scheme */
-0x2B,0x81,0x04,0x01,0x0B,0x03,               /* [6142] OBJ_dhSinglePass_stdDH_sha512kdf_scheme */
-0x2B,0x81,0x05,0x10,0x86,0x48,0x3F,0x00,0x03,/* [6148] OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme */
-0x2B,0x81,0x04,0x01,0x0E,0x00,               /* [6157] OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme */
-0x2B,0x81,0x04,0x01,0x0E,0x01,               /* [6163] OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme */
-0x2B,0x81,0x04,0x01,0x0E,0x02,               /* [6169] OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme */
-0x2B,0x81,0x04,0x01,0x0E,0x03,               /* [6175] OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x08,/* [616] OBJ_zlib_compression */
+0x55,0x1D,0x25,                              /* [627] OBJ_ext_key_usage */
+0x2B,0x06,0x01,0x05,0x05,0x07,               /* [630] OBJ_id_pkix */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,          /* [636] OBJ_id_kp */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01,     /* [643] OBJ_server_auth */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,     /* [651] OBJ_client_auth */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x03,     /* [659] OBJ_code_sign */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x04,     /* [667] OBJ_email_protect */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x08,     /* [675] OBJ_time_stamp */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x15,/* [683] OBJ_ms_code_ind */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x16,/* [693] OBJ_ms_code_com */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x01,/* [703] OBJ_ms_ctl_sign */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x03,/* [713] OBJ_ms_sgc */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x04,/* [723] OBJ_ms_efs */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x04,0x01,/* [733] OBJ_ns_sgc */
+0x55,0x1D,0x1B,                              /* [742] OBJ_delta_crl */
+0x55,0x1D,0x15,                              /* [745] OBJ_crl_reason */
+0x55,0x1D,0x18,                              /* [748] OBJ_invalidity_date */
+0x2B,0x65,0x01,0x04,0x01,                    /* [751] OBJ_sxnet */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x01,/* [756] OBJ_pbe_WithSHA1And128BitRC4 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x02,/* [766] OBJ_pbe_WithSHA1And40BitRC4 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x03,/* [776] OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x04,/* [786] OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x05,/* [796] OBJ_pbe_WithSHA1And128BitRC2_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x06,/* [806] OBJ_pbe_WithSHA1And40BitRC2_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x01,/* [816] OBJ_keyBag */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x02,/* [827] OBJ_pkcs8ShroudedKeyBag */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x03,/* [838] OBJ_certBag */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x04,/* [849] OBJ_crlBag */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x05,/* [860] OBJ_secretBag */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x06,/* [871] OBJ_safeContentsBag */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x14,/* [882] OBJ_friendlyName */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x15,/* [891] OBJ_localKeyID */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x16,0x01,/* [900] OBJ_x509Certificate */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x16,0x02,/* [910] OBJ_sdsiCertificate */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x17,0x01,/* [920] OBJ_x509Crl */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0D,/* [930] OBJ_pbes2 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0E,/* [939] OBJ_pbmac1 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x07,     /* [948] OBJ_hmacWithSHA1 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,     /* [956] OBJ_id_qt_cps */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x02,     /* [964] OBJ_id_qt_unotice */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0F,/* [972] OBJ_SMIMECapabilities */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x04,/* [981] OBJ_pbeWithMD2AndRC2_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x06,/* [990] OBJ_pbeWithMD5AndRC2_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0A,/* [999] OBJ_pbeWithSHA1AndDES_CBC */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x0E,/* [1008] OBJ_ms_ext_req */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0E,/* [1018] OBJ_ext_req */
+0x55,0x04,0x29,                              /* [1027] OBJ_name */
+0x55,0x04,0x2E,                              /* [1030] OBJ_dnQualifier */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,          /* [1033] OBJ_id_pe */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,          /* [1040] OBJ_id_ad */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,     /* [1047] OBJ_info_access */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,     /* [1055] OBJ_ad_OCSP */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,     /* [1063] OBJ_ad_ca_issuers */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x09,     /* [1071] OBJ_OCSP_sign */
+0x2A,                                        /* [1079] OBJ_member_body */
+0x2A,0x86,0x48,                              /* [1080] OBJ_ISO_US */
+0x2A,0x86,0x48,0xCE,0x38,                    /* [1083] OBJ_X9_57 */
+0x2A,0x86,0x48,0xCE,0x38,0x04,               /* [1088] OBJ_X9cm */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,     /* [1094] OBJ_pkcs1 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,     /* [1102] OBJ_pkcs5 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,/* [1110] OBJ_SMIME */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,/* [1119] OBJ_id_smime_mod */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,/* [1129] OBJ_id_smime_ct */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,/* [1139] OBJ_id_smime_aa */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,/* [1149] OBJ_id_smime_alg */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x04,/* [1159] OBJ_id_smime_cd */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,/* [1169] OBJ_id_smime_spq */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,/* [1179] OBJ_id_smime_cti */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x01,/* [1189] OBJ_id_smime_mod_cms */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x02,/* [1200] OBJ_id_smime_mod_ess */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x03,/* [1211] OBJ_id_smime_mod_oid */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x04,/* [1222] OBJ_id_smime_mod_msg_v3 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x05,/* [1233] OBJ_id_smime_mod_ets_eSignature_88 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x06,/* [1244] OBJ_id_smime_mod_ets_eSignature_97 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x07,/* [1255] OBJ_id_smime_mod_ets_eSigPolicy_88 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x08,/* [1266] OBJ_id_smime_mod_ets_eSigPolicy_97 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x01,/* [1277] OBJ_id_smime_ct_receipt */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x02,/* [1288] OBJ_id_smime_ct_authData */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x03,/* [1299] OBJ_id_smime_ct_publishCert */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x04,/* [1310] OBJ_id_smime_ct_TSTInfo */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x05,/* [1321] OBJ_id_smime_ct_TDTInfo */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x06,/* [1332] OBJ_id_smime_ct_contentInfo */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x07,/* [1343] OBJ_id_smime_ct_DVCSRequestData */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x08,/* [1354] OBJ_id_smime_ct_DVCSResponseData */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x01,/* [1365] OBJ_id_smime_aa_receiptRequest */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x02,/* [1376] OBJ_id_smime_aa_securityLabel */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x03,/* [1387] OBJ_id_smime_aa_mlExpandHistory */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x04,/* [1398] OBJ_id_smime_aa_contentHint */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x05,/* [1409] OBJ_id_smime_aa_msgSigDigest */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x06,/* [1420] OBJ_id_smime_aa_encapContentType */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x07,/* [1431] OBJ_id_smime_aa_contentIdentifier */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x08,/* [1442] OBJ_id_smime_aa_macValue */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x09,/* [1453] OBJ_id_smime_aa_equivalentLabels */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0A,/* [1464] OBJ_id_smime_aa_contentReference */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0B,/* [1475] OBJ_id_smime_aa_encrypKeyPref */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0C,/* [1486] OBJ_id_smime_aa_signingCertificate */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0D,/* [1497] OBJ_id_smime_aa_smimeEncryptCerts */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0E,/* [1508] OBJ_id_smime_aa_timeStampToken */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0F,/* [1519] OBJ_id_smime_aa_ets_sigPolicyId */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x10,/* [1530] OBJ_id_smime_aa_ets_commitmentType */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x11,/* [1541] OBJ_id_smime_aa_ets_signerLocation */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x12,/* [1552] OBJ_id_smime_aa_ets_signerAttr */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x13,/* [1563] OBJ_id_smime_aa_ets_otherSigCert */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x14,/* [1574] OBJ_id_smime_aa_ets_contentTimestamp */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x15,/* [1585] OBJ_id_smime_aa_ets_CertificateRefs */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x16,/* [1596] OBJ_id_smime_aa_ets_RevocationRefs */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x17,/* [1607] OBJ_id_smime_aa_ets_certValues */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x18,/* [1618] OBJ_id_smime_aa_ets_revocationValues */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x19,/* [1629] OBJ_id_smime_aa_ets_escTimeStamp */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1A,/* [1640] OBJ_id_smime_aa_ets_certCRLTimestamp */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1B,/* [1651] OBJ_id_smime_aa_ets_archiveTimeStamp */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1C,/* [1662] OBJ_id_smime_aa_signatureType */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1D,/* [1673] OBJ_id_smime_aa_dvcs_dvc */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x01,/* [1684] OBJ_id_smime_alg_ESDHwith3DES */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x02,/* [1695] OBJ_id_smime_alg_ESDHwithRC2 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x03,/* [1706] OBJ_id_smime_alg_3DESwrap */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x04,/* [1717] OBJ_id_smime_alg_RC2wrap */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x05,/* [1728] OBJ_id_smime_alg_ESDH */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x06,/* [1739] OBJ_id_smime_alg_CMS3DESwrap */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x07,/* [1750] OBJ_id_smime_alg_CMSRC2wrap */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x04,0x01,/* [1761] OBJ_id_smime_cd_ldap */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,0x01,/* [1772] OBJ_id_smime_spq_ets_sqt_uri */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,0x02,/* [1783] OBJ_id_smime_spq_ets_sqt_unotice */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x01,/* [1794] OBJ_id_smime_cti_ets_proofOfOrigin */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x02,/* [1805] OBJ_id_smime_cti_ets_proofOfReceipt */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x03,/* [1816] OBJ_id_smime_cti_ets_proofOfDelivery */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x04,/* [1827] OBJ_id_smime_cti_ets_proofOfSender */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x05,/* [1838] OBJ_id_smime_cti_ets_proofOfApproval */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x06,/* [1849] OBJ_id_smime_cti_ets_proofOfCreation */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x04,     /* [1860] OBJ_md4 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,          /* [1868] OBJ_id_pkix_mod */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x02,          /* [1875] OBJ_id_qt */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,          /* [1882] OBJ_id_it */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,          /* [1889] OBJ_id_pkip */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x06,          /* [1896] OBJ_id_alg */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,          /* [1903] OBJ_id_cmc */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x08,          /* [1910] OBJ_id_on */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x09,          /* [1917] OBJ_id_pda */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,          /* [1924] OBJ_id_aca */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0B,          /* [1931] OBJ_id_qcs */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,          /* [1938] OBJ_id_cct */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x01,     /* [1945] OBJ_id_pkix1_explicit_88 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x02,     /* [1953] OBJ_id_pkix1_implicit_88 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x03,     /* [1961] OBJ_id_pkix1_explicit_93 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x04,     /* [1969] OBJ_id_pkix1_implicit_93 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x05,     /* [1977] OBJ_id_mod_crmf */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x06,     /* [1985] OBJ_id_mod_cmc */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x07,     /* [1993] OBJ_id_mod_kea_profile_88 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x08,     /* [2001] OBJ_id_mod_kea_profile_93 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x09,     /* [2009] OBJ_id_mod_cmp */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0A,     /* [2017] OBJ_id_mod_qualified_cert_88 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0B,     /* [2025] OBJ_id_mod_qualified_cert_93 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0C,     /* [2033] OBJ_id_mod_attribute_cert */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0D,     /* [2041] OBJ_id_mod_timestamp_protocol */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0E,     /* [2049] OBJ_id_mod_ocsp */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0F,     /* [2057] OBJ_id_mod_dvcs */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x10,     /* [2065] OBJ_id_mod_cmp2000 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x02,     /* [2073] OBJ_biometricInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x03,     /* [2081] OBJ_qcStatements */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x04,     /* [2089] OBJ_ac_auditEntity */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x05,     /* [2097] OBJ_ac_targeting */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x06,     /* [2105] OBJ_aaControls */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x07,     /* [2113] OBJ_sbgp_ipAddrBlock */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x08,     /* [2121] OBJ_sbgp_autonomousSysNum */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x09,     /* [2129] OBJ_sbgp_routerIdentifier */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x03,     /* [2137] OBJ_textNotice */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x05,     /* [2145] OBJ_ipsecEndSystem */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x06,     /* [2153] OBJ_ipsecTunnel */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x07,     /* [2161] OBJ_ipsecUser */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x0A,     /* [2169] OBJ_dvcs */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x01,     /* [2177] OBJ_id_it_caProtEncCert */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x02,     /* [2185] OBJ_id_it_signKeyPairTypes */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x03,     /* [2193] OBJ_id_it_encKeyPairTypes */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x04,     /* [2201] OBJ_id_it_preferredSymmAlg */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x05,     /* [2209] OBJ_id_it_caKeyUpdateInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x06,     /* [2217] OBJ_id_it_currentCRL */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x07,     /* [2225] OBJ_id_it_unsupportedOIDs */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x08,     /* [2233] OBJ_id_it_subscriptionRequest */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x09,     /* [2241] OBJ_id_it_subscriptionResponse */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0A,     /* [2249] OBJ_id_it_keyPairParamReq */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0B,     /* [2257] OBJ_id_it_keyPairParamRep */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0C,     /* [2265] OBJ_id_it_revPassphrase */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0D,     /* [2273] OBJ_id_it_implicitConfirm */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0E,     /* [2281] OBJ_id_it_confirmWaitTime */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0F,     /* [2289] OBJ_id_it_origPKIMessage */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,     /* [2297] OBJ_id_regCtrl */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,     /* [2305] OBJ_id_regInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x01,/* [2313] OBJ_id_regCtrl_regToken */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x02,/* [2322] OBJ_id_regCtrl_authenticator */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x03,/* [2331] OBJ_id_regCtrl_pkiPublicationInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x04,/* [2340] OBJ_id_regCtrl_pkiArchiveOptions */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x05,/* [2349] OBJ_id_regCtrl_oldCertID */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x06,/* [2358] OBJ_id_regCtrl_protocolEncrKey */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,0x01,/* [2367] OBJ_id_regInfo_utf8Pairs */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,0x02,/* [2376] OBJ_id_regInfo_certReq */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x01,     /* [2385] OBJ_id_alg_des40 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x02,     /* [2393] OBJ_id_alg_noSignature */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x03,     /* [2401] OBJ_id_alg_dh_sig_hmac_sha1 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x04,     /* [2409] OBJ_id_alg_dh_pop */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x01,     /* [2417] OBJ_id_cmc_statusInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x02,     /* [2425] OBJ_id_cmc_identification */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x03,     /* [2433] OBJ_id_cmc_identityProof */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x04,     /* [2441] OBJ_id_cmc_dataReturn */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x05,     /* [2449] OBJ_id_cmc_transactionId */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x06,     /* [2457] OBJ_id_cmc_senderNonce */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x07,     /* [2465] OBJ_id_cmc_recipientNonce */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x08,     /* [2473] OBJ_id_cmc_addExtensions */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x09,     /* [2481] OBJ_id_cmc_encryptedPOP */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0A,     /* [2489] OBJ_id_cmc_decryptedPOP */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0B,     /* [2497] OBJ_id_cmc_lraPOPWitness */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0F,     /* [2505] OBJ_id_cmc_getCert */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x10,     /* [2513] OBJ_id_cmc_getCRL */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x11,     /* [2521] OBJ_id_cmc_revokeRequest */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x12,     /* [2529] OBJ_id_cmc_regInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x13,     /* [2537] OBJ_id_cmc_responseInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x15,     /* [2545] OBJ_id_cmc_queryPending */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x16,     /* [2553] OBJ_id_cmc_popLinkRandom */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x17,     /* [2561] OBJ_id_cmc_popLinkWitness */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x18,     /* [2569] OBJ_id_cmc_confirmCertAcceptance */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x01,     /* [2577] OBJ_id_on_personalData */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x01,     /* [2585] OBJ_id_pda_dateOfBirth */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x02,     /* [2593] OBJ_id_pda_placeOfBirth */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x03,     /* [2601] OBJ_id_pda_gender */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x04,     /* [2609] OBJ_id_pda_countryOfCitizenship */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x05,     /* [2617] OBJ_id_pda_countryOfResidence */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x01,     /* [2625] OBJ_id_aca_authenticationInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x02,     /* [2633] OBJ_id_aca_accessIdentity */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x03,     /* [2641] OBJ_id_aca_chargingIdentity */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x04,     /* [2649] OBJ_id_aca_group */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x05,     /* [2657] OBJ_id_aca_role */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0B,0x01,     /* [2665] OBJ_id_qcs_pkixQCSyntax_v1 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x01,     /* [2673] OBJ_id_cct_crs */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x02,     /* [2681] OBJ_id_cct_PKIData */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x03,     /* [2689] OBJ_id_cct_PKIResponse */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x03,     /* [2697] OBJ_ad_timeStamping */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x04,     /* [2705] OBJ_ad_dvcs */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x01,/* [2713] OBJ_id_pkix_OCSP_basic */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x02,/* [2722] OBJ_id_pkix_OCSP_Nonce */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x03,/* [2731] OBJ_id_pkix_OCSP_CrlID */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x04,/* [2740] OBJ_id_pkix_OCSP_acceptableResponses */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x05,/* [2749] OBJ_id_pkix_OCSP_noCheck */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x06,/* [2758] OBJ_id_pkix_OCSP_archiveCutoff */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x07,/* [2767] OBJ_id_pkix_OCSP_serviceLocator */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x08,/* [2776] OBJ_id_pkix_OCSP_extendedStatus */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x09,/* [2785] OBJ_id_pkix_OCSP_valid */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x0A,/* [2794] OBJ_id_pkix_OCSP_path */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x0B,/* [2803] OBJ_id_pkix_OCSP_trustRoot */
+0x2B,0x0E,0x03,0x02,                         /* [2812] OBJ_algorithm */
+0x2B,0x0E,0x03,0x02,0x0B,                    /* [2816] OBJ_rsaSignature */
+0x55,0x08,                                   /* [2821] OBJ_X500algorithms */
+0x2B,                                        /* [2823] OBJ_org */
+0x2B,0x06,                                   /* [2824] OBJ_dod */
+0x2B,0x06,0x01,                              /* [2826] OBJ_iana */
+0x2B,0x06,0x01,0x01,                         /* [2829] OBJ_Directory */
+0x2B,0x06,0x01,0x02,                         /* [2833] OBJ_Management */
+0x2B,0x06,0x01,0x03,                         /* [2837] OBJ_Experimental */
+0x2B,0x06,0x01,0x04,                         /* [2841] OBJ_Private */
+0x2B,0x06,0x01,0x05,                         /* [2845] OBJ_Security */
+0x2B,0x06,0x01,0x06,                         /* [2849] OBJ_SNMPv2 */
+0x2B,0x06,0x01,0x07,                         /* [2853] OBJ_Mail */
+0x2B,0x06,0x01,0x04,0x01,                    /* [2857] OBJ_Enterprises */
+0x2B,0x06,0x01,0x04,0x01,0x8B,0x3A,0x82,0x58,/* [2862] OBJ_dcObject */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x19,/* [2871] OBJ_domainComponent */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0D,/* [2881] OBJ_Domain */
+0x55,0x01,0x05,                              /* [2891] OBJ_selected_attribute_types */
+0x55,0x01,0x05,0x37,                         /* [2894] OBJ_clearance */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x03,/* [2898] OBJ_md4WithRSAEncryption */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0A,     /* [2907] OBJ_ac_proxying */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0B,     /* [2915] OBJ_sinfo_access */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x06,     /* [2923] OBJ_id_aca_encAttrs */
+0x55,0x04,0x48,                              /* [2931] OBJ_role */
+0x55,0x1D,0x24,                              /* [2934] OBJ_policy_constraints */
+0x55,0x1D,0x37,                              /* [2937] OBJ_target_information */
+0x55,0x1D,0x38,                              /* [2940] OBJ_no_rev_avail */
+0x2A,0x86,0x48,0xCE,0x3D,                    /* [2943] OBJ_ansi_X9_62 */
+0x2A,0x86,0x48,0xCE,0x3D,0x01,0x01,          /* [2948] OBJ_X9_62_prime_field */
+0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,          /* [2955] OBJ_X9_62_characteristic_two_field */
+0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,          /* [2962] OBJ_X9_62_id_ecPublicKey */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01,     /* [2969] OBJ_X9_62_prime192v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02,     /* [2977] OBJ_X9_62_prime192v2 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03,     /* [2985] OBJ_X9_62_prime192v3 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04,     /* [2993] OBJ_X9_62_prime239v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05,     /* [3001] OBJ_X9_62_prime239v2 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06,     /* [3009] OBJ_X9_62_prime239v3 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07,     /* [3017] OBJ_X9_62_prime256v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,          /* [3025] OBJ_ecdsa_with_SHA1 */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x01,/* [3032] OBJ_ms_csp_name */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x01,/* [3041] OBJ_aes_128_ecb */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x02,/* [3050] OBJ_aes_128_cbc */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x03,/* [3059] OBJ_aes_128_ofb128 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x04,/* [3068] OBJ_aes_128_cfb128 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x15,/* [3077] OBJ_aes_192_ecb */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x16,/* [3086] OBJ_aes_192_cbc */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x17,/* [3095] OBJ_aes_192_ofb128 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x18,/* [3104] OBJ_aes_192_cfb128 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x29,/* [3113] OBJ_aes_256_ecb */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2A,/* [3122] OBJ_aes_256_cbc */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2B,/* [3131] OBJ_aes_256_ofb128 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2C,/* [3140] OBJ_aes_256_cfb128 */
+0x55,0x1D,0x17,                              /* [3149] OBJ_hold_instruction_code */
+0x2A,0x86,0x48,0xCE,0x38,0x02,0x01,          /* [3152] OBJ_hold_instruction_none */
+0x2A,0x86,0x48,0xCE,0x38,0x02,0x02,          /* [3159] OBJ_hold_instruction_call_issuer */
+0x2A,0x86,0x48,0xCE,0x38,0x02,0x03,          /* [3166] OBJ_hold_instruction_reject */
+0x09,                                        /* [3173] OBJ_data */
+0x09,0x92,0x26,                              /* [3174] OBJ_pss */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,          /* [3177] OBJ_ucl */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,     /* [3184] OBJ_pilot */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,/* [3192] OBJ_pilotAttributeType */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,/* [3201] OBJ_pilotAttributeSyntax */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,/* [3210] OBJ_pilotObjectClass */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x0A,/* [3219] OBJ_pilotGroups */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,0x04,/* [3228] OBJ_iA5StringSyntax */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,0x05,/* [3238] OBJ_caseIgnoreIA5StringSyntax */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x03,/* [3248] OBJ_pilotObject */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x04,/* [3258] OBJ_pilotPerson */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x05,/* [3268] OBJ_account */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x06,/* [3278] OBJ_document */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x07,/* [3288] OBJ_room */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x09,/* [3298] OBJ_documentSeries */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0E,/* [3308] OBJ_rFC822localPart */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0F,/* [3318] OBJ_dNSDomain */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x11,/* [3328] OBJ_domainRelatedObject */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x12,/* [3338] OBJ_friendlyCountry */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x13,/* [3348] OBJ_simpleSecurityObject */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x14,/* [3358] OBJ_pilotOrganization */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x15,/* [3368] OBJ_pilotDSA */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x16,/* [3378] OBJ_qualityLabelledData */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x01,/* [3388] OBJ_userId */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x02,/* [3398] OBJ_textEncodedORAddress */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x03,/* [3408] OBJ_rfc822Mailbox */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x04,/* [3418] OBJ_info */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x05,/* [3428] OBJ_favouriteDrink */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x06,/* [3438] OBJ_roomNumber */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x07,/* [3448] OBJ_photo */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x08,/* [3458] OBJ_userClass */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x09,/* [3468] OBJ_host */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0A,/* [3478] OBJ_manager */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0B,/* [3488] OBJ_documentIdentifier */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0C,/* [3498] OBJ_documentTitle */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0D,/* [3508] OBJ_documentVersion */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0E,/* [3518] OBJ_documentAuthor */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0F,/* [3528] OBJ_documentLocation */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x14,/* [3538] OBJ_homeTelephoneNumber */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x15,/* [3548] OBJ_secretary */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x16,/* [3558] OBJ_otherMailbox */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x17,/* [3568] OBJ_lastModifiedTime */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x18,/* [3578] OBJ_lastModifiedBy */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1A,/* [3588] OBJ_aRecord */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1B,/* [3598] OBJ_pilotAttributeType27 */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1C,/* [3608] OBJ_mXRecord */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1D,/* [3618] OBJ_nSRecord */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1E,/* [3628] OBJ_sOARecord */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1F,/* [3638] OBJ_cNAMERecord */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x25,/* [3648] OBJ_associatedDomain */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x26,/* [3658] OBJ_associatedName */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x27,/* [3668] OBJ_homePostalAddress */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x28,/* [3678] OBJ_personalTitle */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x29,/* [3688] OBJ_mobileTelephoneNumber */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2A,/* [3698] OBJ_pagerTelephoneNumber */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2B,/* [3708] OBJ_friendlyCountryName */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2D,/* [3718] OBJ_organizationalStatus */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2E,/* [3728] OBJ_janetMailbox */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2F,/* [3738] OBJ_mailPreferenceOption */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x30,/* [3748] OBJ_buildingName */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x31,/* [3758] OBJ_dSAQuality */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x32,/* [3768] OBJ_singleLevelQuality */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x33,/* [3778] OBJ_subtreeMinimumQuality */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x34,/* [3788] OBJ_subtreeMaximumQuality */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x35,/* [3798] OBJ_personalSignature */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x36,/* [3808] OBJ_dITRedirect */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x37,/* [3818] OBJ_audio */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x38,/* [3828] OBJ_documentPublisher */
+0x55,0x04,0x2D,                              /* [3838] OBJ_x500UniqueIdentifier */
+0x2B,0x06,0x01,0x07,0x01,                    /* [3841] OBJ_mime_mhs */
+0x2B,0x06,0x01,0x07,0x01,0x01,               /* [3846] OBJ_mime_mhs_headings */
+0x2B,0x06,0x01,0x07,0x01,0x02,               /* [3852] OBJ_mime_mhs_bodies */
+0x2B,0x06,0x01,0x07,0x01,0x01,0x01,          /* [3858] OBJ_id_hex_partial_message */
+0x2B,0x06,0x01,0x07,0x01,0x01,0x02,          /* [3865] OBJ_id_hex_multipart_message */
+0x55,0x04,0x2C,                              /* [3872] OBJ_generationQualifier */
+0x55,0x04,0x41,                              /* [3875] OBJ_pseudonym */
+0x67,0x2A,                                   /* [3878] OBJ_id_set */
+0x67,0x2A,0x00,                              /* [3880] OBJ_set_ctype */
+0x67,0x2A,0x01,                              /* [3883] OBJ_set_msgExt */
+0x67,0x2A,0x03,                              /* [3886] OBJ_set_attr */
+0x67,0x2A,0x05,                              /* [3889] OBJ_set_policy */
+0x67,0x2A,0x07,                              /* [3892] OBJ_set_certExt */
+0x67,0x2A,0x08,                              /* [3895] OBJ_set_brand */
+0x67,0x2A,0x00,0x00,                         /* [3898] OBJ_setct_PANData */
+0x67,0x2A,0x00,0x01,                         /* [3902] OBJ_setct_PANToken */
+0x67,0x2A,0x00,0x02,                         /* [3906] OBJ_setct_PANOnly */
+0x67,0x2A,0x00,0x03,                         /* [3910] OBJ_setct_OIData */
+0x67,0x2A,0x00,0x04,                         /* [3914] OBJ_setct_PI */
+0x67,0x2A,0x00,0x05,                         /* [3918] OBJ_setct_PIData */
+0x67,0x2A,0x00,0x06,                         /* [3922] OBJ_setct_PIDataUnsigned */
+0x67,0x2A,0x00,0x07,                         /* [3926] OBJ_setct_HODInput */
+0x67,0x2A,0x00,0x08,                         /* [3930] OBJ_setct_AuthResBaggage */
+0x67,0x2A,0x00,0x09,                         /* [3934] OBJ_setct_AuthRevReqBaggage */
+0x67,0x2A,0x00,0x0A,                         /* [3938] OBJ_setct_AuthRevResBaggage */
+0x67,0x2A,0x00,0x0B,                         /* [3942] OBJ_setct_CapTokenSeq */
+0x67,0x2A,0x00,0x0C,                         /* [3946] OBJ_setct_PInitResData */
+0x67,0x2A,0x00,0x0D,                         /* [3950] OBJ_setct_PI_TBS */
+0x67,0x2A,0x00,0x0E,                         /* [3954] OBJ_setct_PResData */
+0x67,0x2A,0x00,0x10,                         /* [3958] OBJ_setct_AuthReqTBS */
+0x67,0x2A,0x00,0x11,                         /* [3962] OBJ_setct_AuthResTBS */
+0x67,0x2A,0x00,0x12,                         /* [3966] OBJ_setct_AuthResTBSX */
+0x67,0x2A,0x00,0x13,                         /* [3970] OBJ_setct_AuthTokenTBS */
+0x67,0x2A,0x00,0x14,                         /* [3974] OBJ_setct_CapTokenData */
+0x67,0x2A,0x00,0x15,                         /* [3978] OBJ_setct_CapTokenTBS */
+0x67,0x2A,0x00,0x16,                         /* [3982] OBJ_setct_AcqCardCodeMsg */
+0x67,0x2A,0x00,0x17,                         /* [3986] OBJ_setct_AuthRevReqTBS */
+0x67,0x2A,0x00,0x18,                         /* [3990] OBJ_setct_AuthRevResData */
+0x67,0x2A,0x00,0x19,                         /* [3994] OBJ_setct_AuthRevResTBS */
+0x67,0x2A,0x00,0x1A,                         /* [3998] OBJ_setct_CapReqTBS */
+0x67,0x2A,0x00,0x1B,                         /* [4002] OBJ_setct_CapReqTBSX */
+0x67,0x2A,0x00,0x1C,                         /* [4006] OBJ_setct_CapResData */
+0x67,0x2A,0x00,0x1D,                         /* [4010] OBJ_setct_CapRevReqTBS */
+0x67,0x2A,0x00,0x1E,                         /* [4014] OBJ_setct_CapRevReqTBSX */
+0x67,0x2A,0x00,0x1F,                         /* [4018] OBJ_setct_CapRevResData */
+0x67,0x2A,0x00,0x20,                         /* [4022] OBJ_setct_CredReqTBS */
+0x67,0x2A,0x00,0x21,                         /* [4026] OBJ_setct_CredReqTBSX */
+0x67,0x2A,0x00,0x22,                         /* [4030] OBJ_setct_CredResData */
+0x67,0x2A,0x00,0x23,                         /* [4034] OBJ_setct_CredRevReqTBS */
+0x67,0x2A,0x00,0x24,                         /* [4038] OBJ_setct_CredRevReqTBSX */
+0x67,0x2A,0x00,0x25,                         /* [4042] OBJ_setct_CredRevResData */
+0x67,0x2A,0x00,0x26,                         /* [4046] OBJ_setct_PCertReqData */
+0x67,0x2A,0x00,0x27,                         /* [4050] OBJ_setct_PCertResTBS */
+0x67,0x2A,0x00,0x28,                         /* [4054] OBJ_setct_BatchAdminReqData */
+0x67,0x2A,0x00,0x29,                         /* [4058] OBJ_setct_BatchAdminResData */
+0x67,0x2A,0x00,0x2A,                         /* [4062] OBJ_setct_CardCInitResTBS */
+0x67,0x2A,0x00,0x2B,                         /* [4066] OBJ_setct_MeAqCInitResTBS */
+0x67,0x2A,0x00,0x2C,                         /* [4070] OBJ_setct_RegFormResTBS */
+0x67,0x2A,0x00,0x2D,                         /* [4074] OBJ_setct_CertReqData */
+0x67,0x2A,0x00,0x2E,                         /* [4078] OBJ_setct_CertReqTBS */
+0x67,0x2A,0x00,0x2F,                         /* [4082] OBJ_setct_CertResData */
+0x67,0x2A,0x00,0x30,                         /* [4086] OBJ_setct_CertInqReqTBS */
+0x67,0x2A,0x00,0x31,                         /* [4090] OBJ_setct_ErrorTBS */
+0x67,0x2A,0x00,0x32,                         /* [4094] OBJ_setct_PIDualSignedTBE */
+0x67,0x2A,0x00,0x33,                         /* [4098] OBJ_setct_PIUnsignedTBE */
+0x67,0x2A,0x00,0x34,                         /* [4102] OBJ_setct_AuthReqTBE */
+0x67,0x2A,0x00,0x35,                         /* [4106] OBJ_setct_AuthResTBE */
+0x67,0x2A,0x00,0x36,                         /* [4110] OBJ_setct_AuthResTBEX */
+0x67,0x2A,0x00,0x37,                         /* [4114] OBJ_setct_AuthTokenTBE */
+0x67,0x2A,0x00,0x38,                         /* [4118] OBJ_setct_CapTokenTBE */
+0x67,0x2A,0x00,0x39,                         /* [4122] OBJ_setct_CapTokenTBEX */
+0x67,0x2A,0x00,0x3A,                         /* [4126] OBJ_setct_AcqCardCodeMsgTBE */
+0x67,0x2A,0x00,0x3B,                         /* [4130] OBJ_setct_AuthRevReqTBE */
+0x67,0x2A,0x00,0x3C,                         /* [4134] OBJ_setct_AuthRevResTBE */
+0x67,0x2A,0x00,0x3D,                         /* [4138] OBJ_setct_AuthRevResTBEB */
+0x67,0x2A,0x00,0x3E,                         /* [4142] OBJ_setct_CapReqTBE */
+0x67,0x2A,0x00,0x3F,                         /* [4146] OBJ_setct_CapReqTBEX */
+0x67,0x2A,0x00,0x40,                         /* [4150] OBJ_setct_CapResTBE */
+0x67,0x2A,0x00,0x41,                         /* [4154] OBJ_setct_CapRevReqTBE */
+0x67,0x2A,0x00,0x42,                         /* [4158] OBJ_setct_CapRevReqTBEX */
+0x67,0x2A,0x00,0x43,                         /* [4162] OBJ_setct_CapRevResTBE */
+0x67,0x2A,0x00,0x44,                         /* [4166] OBJ_setct_CredReqTBE */
+0x67,0x2A,0x00,0x45,                         /* [4170] OBJ_setct_CredReqTBEX */
+0x67,0x2A,0x00,0x46,                         /* [4174] OBJ_setct_CredResTBE */
+0x67,0x2A,0x00,0x47,                         /* [4178] OBJ_setct_CredRevReqTBE */
+0x67,0x2A,0x00,0x48,                         /* [4182] OBJ_setct_CredRevReqTBEX */
+0x67,0x2A,0x00,0x49,                         /* [4186] OBJ_setct_CredRevResTBE */
+0x67,0x2A,0x00,0x4A,                         /* [4190] OBJ_setct_BatchAdminReqTBE */
+0x67,0x2A,0x00,0x4B,                         /* [4194] OBJ_setct_BatchAdminResTBE */
+0x67,0x2A,0x00,0x4C,                         /* [4198] OBJ_setct_RegFormReqTBE */
+0x67,0x2A,0x00,0x4D,                         /* [4202] OBJ_setct_CertReqTBE */
+0x67,0x2A,0x00,0x4E,                         /* [4206] OBJ_setct_CertReqTBEX */
+0x67,0x2A,0x00,0x4F,                         /* [4210] OBJ_setct_CertResTBE */
+0x67,0x2A,0x00,0x50,                         /* [4214] OBJ_setct_CRLNotificationTBS */
+0x67,0x2A,0x00,0x51,                         /* [4218] OBJ_setct_CRLNotificationResTBS */
+0x67,0x2A,0x00,0x52,                         /* [4222] OBJ_setct_BCIDistributionTBS */
+0x67,0x2A,0x01,0x01,                         /* [4226] OBJ_setext_genCrypt */
+0x67,0x2A,0x01,0x03,                         /* [4230] OBJ_setext_miAuth */
+0x67,0x2A,0x01,0x04,                         /* [4234] OBJ_setext_pinSecure */
+0x67,0x2A,0x01,0x05,                         /* [4238] OBJ_setext_pinAny */
+0x67,0x2A,0x01,0x07,                         /* [4242] OBJ_setext_track2 */
+0x67,0x2A,0x01,0x08,                         /* [4246] OBJ_setext_cv */
+0x67,0x2A,0x05,0x00,                         /* [4250] OBJ_set_policy_root */
+0x67,0x2A,0x07,0x00,                         /* [4254] OBJ_setCext_hashedRoot */
+0x67,0x2A,0x07,0x01,                         /* [4258] OBJ_setCext_certType */
+0x67,0x2A,0x07,0x02,                         /* [4262] OBJ_setCext_merchData */
+0x67,0x2A,0x07,0x03,                         /* [4266] OBJ_setCext_cCertRequired */
+0x67,0x2A,0x07,0x04,                         /* [4270] OBJ_setCext_tunneling */
+0x67,0x2A,0x07,0x05,                         /* [4274] OBJ_setCext_setExt */
+0x67,0x2A,0x07,0x06,                         /* [4278] OBJ_setCext_setQualf */
+0x67,0x2A,0x07,0x07,                         /* [4282] OBJ_setCext_PGWYcapabilities */
+0x67,0x2A,0x07,0x08,                         /* [4286] OBJ_setCext_TokenIdentifier */
+0x67,0x2A,0x07,0x09,                         /* [4290] OBJ_setCext_Track2Data */
+0x67,0x2A,0x07,0x0A,                         /* [4294] OBJ_setCext_TokenType */
+0x67,0x2A,0x07,0x0B,                         /* [4298] OBJ_setCext_IssuerCapabilities */
+0x67,0x2A,0x03,0x00,                         /* [4302] OBJ_setAttr_Cert */
+0x67,0x2A,0x03,0x01,                         /* [4306] OBJ_setAttr_PGWYcap */
+0x67,0x2A,0x03,0x02,                         /* [4310] OBJ_setAttr_TokenType */
+0x67,0x2A,0x03,0x03,                         /* [4314] OBJ_setAttr_IssCap */
+0x67,0x2A,0x03,0x00,0x00,                    /* [4318] OBJ_set_rootKeyThumb */
+0x67,0x2A,0x03,0x00,0x01,                    /* [4323] OBJ_set_addPolicy */
+0x67,0x2A,0x03,0x02,0x01,                    /* [4328] OBJ_setAttr_Token_EMV */
+0x67,0x2A,0x03,0x02,0x02,                    /* [4333] OBJ_setAttr_Token_B0Prime */
+0x67,0x2A,0x03,0x03,0x03,                    /* [4338] OBJ_setAttr_IssCap_CVM */
+0x67,0x2A,0x03,0x03,0x04,                    /* [4343] OBJ_setAttr_IssCap_T2 */
+0x67,0x2A,0x03,0x03,0x05,                    /* [4348] OBJ_setAttr_IssCap_Sig */
+0x67,0x2A,0x03,0x03,0x03,0x01,               /* [4353] OBJ_setAttr_GenCryptgrm */
+0x67,0x2A,0x03,0x03,0x04,0x01,               /* [4359] OBJ_setAttr_T2Enc */
+0x67,0x2A,0x03,0x03,0x04,0x02,               /* [4365] OBJ_setAttr_T2cleartxt */
+0x67,0x2A,0x03,0x03,0x05,0x01,               /* [4371] OBJ_setAttr_TokICCsig */
+0x67,0x2A,0x03,0x03,0x05,0x02,               /* [4377] OBJ_setAttr_SecDevSig */
+0x67,0x2A,0x08,0x01,                         /* [4383] OBJ_set_brand_IATA_ATA */
+0x67,0x2A,0x08,0x1E,                         /* [4387] OBJ_set_brand_Diners */
+0x67,0x2A,0x08,0x22,                         /* [4391] OBJ_set_brand_AmericanExpress */
+0x67,0x2A,0x08,0x23,                         /* [4395] OBJ_set_brand_JCB */
+0x67,0x2A,0x08,0x04,                         /* [4399] OBJ_set_brand_Visa */
+0x67,0x2A,0x08,0x05,                         /* [4403] OBJ_set_brand_MasterCard */
+0x67,0x2A,0x08,0xAE,0x7B,                    /* [4407] OBJ_set_brand_Novus */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x0A,     /* [4412] OBJ_des_cdmf */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x06,/* [4420] OBJ_rsaOAEPEncryptionSET */
+0x67,                                        /* [4429] OBJ_international_organizations */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x02,/* [4430] OBJ_ms_smartcard_login */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x03,/* [4440] OBJ_ms_upn */
+0x55,0x04,0x09,                              /* [4450] OBJ_streetAddress */
+0x55,0x04,0x11,                              /* [4453] OBJ_postalCode */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x15,          /* [4456] OBJ_id_ppl */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0E,     /* [4463] OBJ_proxyCertInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x00,     /* [4471] OBJ_id_ppl_anyLanguage */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x01,     /* [4479] OBJ_id_ppl_inheritAll */
+0x55,0x1D,0x1E,                              /* [4487] OBJ_name_constraints */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x02,     /* [4490] OBJ_Independent */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,/* [4498] OBJ_sha256WithRSAEncryption */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0C,/* [4507] OBJ_sha384WithRSAEncryption */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0D,/* [4516] OBJ_sha512WithRSAEncryption */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0E,/* [4525] OBJ_sha224WithRSAEncryption */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,/* [4534] OBJ_sha256 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,/* [4543] OBJ_sha384 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,/* [4552] OBJ_sha512 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04,/* [4561] OBJ_sha224 */
+0x2B,                                        /* [4570] OBJ_identified_organization */
+0x2B,0x81,0x04,                              /* [4571] OBJ_certicom_arc */
+0x67,0x2B,                                   /* [4574] OBJ_wap */
+0x67,0x2B,0x01,                              /* [4576] OBJ_wap_wsg */
+0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,     /* [4579] OBJ_X9_62_id_characteristic_two_basis */
+0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x01,/* [4587] OBJ_X9_62_onBasis */
+0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x02,/* [4596] OBJ_X9_62_tpBasis */
+0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x03,/* [4605] OBJ_X9_62_ppBasis */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x01,     /* [4614] OBJ_X9_62_c2pnb163v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x02,     /* [4622] OBJ_X9_62_c2pnb163v2 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x03,     /* [4630] OBJ_X9_62_c2pnb163v3 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x04,     /* [4638] OBJ_X9_62_c2pnb176v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x05,     /* [4646] OBJ_X9_62_c2tnb191v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x06,     /* [4654] OBJ_X9_62_c2tnb191v2 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x07,     /* [4662] OBJ_X9_62_c2tnb191v3 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x08,     /* [4670] OBJ_X9_62_c2onb191v4 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x09,     /* [4678] OBJ_X9_62_c2onb191v5 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0A,     /* [4686] OBJ_X9_62_c2pnb208w1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0B,     /* [4694] OBJ_X9_62_c2tnb239v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0C,     /* [4702] OBJ_X9_62_c2tnb239v2 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0D,     /* [4710] OBJ_X9_62_c2tnb239v3 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0E,     /* [4718] OBJ_X9_62_c2onb239v4 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0F,     /* [4726] OBJ_X9_62_c2onb239v5 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x10,     /* [4734] OBJ_X9_62_c2pnb272w1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x11,     /* [4742] OBJ_X9_62_c2pnb304w1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x12,     /* [4750] OBJ_X9_62_c2tnb359v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x13,     /* [4758] OBJ_X9_62_c2pnb368w1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x14,     /* [4766] OBJ_X9_62_c2tnb431r1 */
+0x2B,0x81,0x04,0x00,0x06,                    /* [4774] OBJ_secp112r1 */
+0x2B,0x81,0x04,0x00,0x07,                    /* [4779] OBJ_secp112r2 */
+0x2B,0x81,0x04,0x00,0x1C,                    /* [4784] OBJ_secp128r1 */
+0x2B,0x81,0x04,0x00,0x1D,                    /* [4789] OBJ_secp128r2 */
+0x2B,0x81,0x04,0x00,0x09,                    /* [4794] OBJ_secp160k1 */
+0x2B,0x81,0x04,0x00,0x08,                    /* [4799] OBJ_secp160r1 */
+0x2B,0x81,0x04,0x00,0x1E,                    /* [4804] OBJ_secp160r2 */
+0x2B,0x81,0x04,0x00,0x1F,                    /* [4809] OBJ_secp192k1 */
+0x2B,0x81,0x04,0x00,0x20,                    /* [4814] OBJ_secp224k1 */
+0x2B,0x81,0x04,0x00,0x21,                    /* [4819] OBJ_secp224r1 */
+0x2B,0x81,0x04,0x00,0x0A,                    /* [4824] OBJ_secp256k1 */
+0x2B,0x81,0x04,0x00,0x22,                    /* [4829] OBJ_secp384r1 */
+0x2B,0x81,0x04,0x00,0x23,                    /* [4834] OBJ_secp521r1 */
+0x2B,0x81,0x04,0x00,0x04,                    /* [4839] OBJ_sect113r1 */
+0x2B,0x81,0x04,0x00,0x05,                    /* [4844] OBJ_sect113r2 */
+0x2B,0x81,0x04,0x00,0x16,                    /* [4849] OBJ_sect131r1 */
+0x2B,0x81,0x04,0x00,0x17,                    /* [4854] OBJ_sect131r2 */
+0x2B,0x81,0x04,0x00,0x01,                    /* [4859] OBJ_sect163k1 */
+0x2B,0x81,0x04,0x00,0x02,                    /* [4864] OBJ_sect163r1 */
+0x2B,0x81,0x04,0x00,0x0F,                    /* [4869] OBJ_sect163r2 */
+0x2B,0x81,0x04,0x00,0x18,                    /* [4874] OBJ_sect193r1 */
+0x2B,0x81,0x04,0x00,0x19,                    /* [4879] OBJ_sect193r2 */
+0x2B,0x81,0x04,0x00,0x1A,                    /* [4884] OBJ_sect233k1 */
+0x2B,0x81,0x04,0x00,0x1B,                    /* [4889] OBJ_sect233r1 */
+0x2B,0x81,0x04,0x00,0x03,                    /* [4894] OBJ_sect239k1 */
+0x2B,0x81,0x04,0x00,0x10,                    /* [4899] OBJ_sect283k1 */
+0x2B,0x81,0x04,0x00,0x11,                    /* [4904] OBJ_sect283r1 */
+0x2B,0x81,0x04,0x00,0x24,                    /* [4909] OBJ_sect409k1 */
+0x2B,0x81,0x04,0x00,0x25,                    /* [4914] OBJ_sect409r1 */
+0x2B,0x81,0x04,0x00,0x26,                    /* [4919] OBJ_sect571k1 */
+0x2B,0x81,0x04,0x00,0x27,                    /* [4924] OBJ_sect571r1 */
+0x67,0x2B,0x01,0x04,0x01,                    /* [4929] OBJ_wap_wsg_idm_ecid_wtls1 */
+0x67,0x2B,0x01,0x04,0x03,                    /* [4934] OBJ_wap_wsg_idm_ecid_wtls3 */
+0x67,0x2B,0x01,0x04,0x04,                    /* [4939] OBJ_wap_wsg_idm_ecid_wtls4 */
+0x67,0x2B,0x01,0x04,0x05,                    /* [4944] OBJ_wap_wsg_idm_ecid_wtls5 */
+0x67,0x2B,0x01,0x04,0x06,                    /* [4949] OBJ_wap_wsg_idm_ecid_wtls6 */
+0x67,0x2B,0x01,0x04,0x07,                    /* [4954] OBJ_wap_wsg_idm_ecid_wtls7 */
+0x67,0x2B,0x01,0x04,0x08,                    /* [4959] OBJ_wap_wsg_idm_ecid_wtls8 */
+0x67,0x2B,0x01,0x04,0x09,                    /* [4964] OBJ_wap_wsg_idm_ecid_wtls9 */
+0x67,0x2B,0x01,0x04,0x0A,                    /* [4969] OBJ_wap_wsg_idm_ecid_wtls10 */
+0x67,0x2B,0x01,0x04,0x0B,                    /* [4974] OBJ_wap_wsg_idm_ecid_wtls11 */
+0x67,0x2B,0x01,0x04,0x0C,                    /* [4979] OBJ_wap_wsg_idm_ecid_wtls12 */
+0x55,0x1D,0x20,0x00,                         /* [4984] OBJ_any_policy */
+0x55,0x1D,0x21,                              /* [4988] OBJ_policy_mappings */
+0x55,0x1D,0x36,                              /* [4991] OBJ_inhibit_any_policy */
+0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x02,/* [4994] OBJ_camellia_128_cbc */
+0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x03,/* [5005] OBJ_camellia_192_cbc */
+0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x04,/* [5016] OBJ_camellia_256_cbc */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x01,     /* [5027] OBJ_camellia_128_ecb */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x15,     /* [5035] OBJ_camellia_192_ecb */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x29,     /* [5043] OBJ_camellia_256_ecb */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x04,     /* [5051] OBJ_camellia_128_cfb128 */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x18,     /* [5059] OBJ_camellia_192_cfb128 */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2C,     /* [5067] OBJ_camellia_256_cfb128 */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x03,     /* [5075] OBJ_camellia_128_ofb128 */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x17,     /* [5083] OBJ_camellia_192_ofb128 */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2B,     /* [5091] OBJ_camellia_256_ofb128 */
+0x55,0x1D,0x09,                              /* [5099] OBJ_subject_directory_attributes */
+0x55,0x1D,0x1C,                              /* [5102] OBJ_issuing_distribution_point */
+0x55,0x1D,0x1D,                              /* [5105] OBJ_certificate_issuer */
+0x2A,0x83,0x1A,0x8C,0x9A,0x44,               /* [5108] OBJ_kisa */
+0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x03,     /* [5114] OBJ_seed_ecb */
+0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x04,     /* [5122] OBJ_seed_cbc */
+0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x06,     /* [5130] OBJ_seed_ofb128 */
+0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x05,     /* [5138] OBJ_seed_cfb128 */
+0x2B,0x06,0x01,0x05,0x05,0x08,0x01,0x01,     /* [5146] OBJ_hmac_md5 */
+0x2B,0x06,0x01,0x05,0x05,0x08,0x01,0x02,     /* [5154] OBJ_hmac_sha1 */
+0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0D,/* [5162] OBJ_id_PasswordBasedMAC */
+0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x1E,/* [5171] OBJ_id_DHBasedMac */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x10,     /* [5180] OBJ_id_it_suppLangTags */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x05,     /* [5188] OBJ_caRepository */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x09,/* [5196] OBJ_id_smime_ct_compressedData */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x1B,/* [5207] OBJ_id_ct_asciiTextWithCRLF */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x05,/* [5218] OBJ_id_aes128_wrap */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x19,/* [5227] OBJ_id_aes192_wrap */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2D,/* [5236] OBJ_id_aes256_wrap */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x02,          /* [5245] OBJ_ecdsa_with_Recommended */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,          /* [5252] OBJ_ecdsa_with_Specified */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x01,     /* [5259] OBJ_ecdsa_with_SHA224 */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02,     /* [5267] OBJ_ecdsa_with_SHA256 */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x03,     /* [5275] OBJ_ecdsa_with_SHA384 */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x04,     /* [5283] OBJ_ecdsa_with_SHA512 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x06,     /* [5291] OBJ_hmacWithMD5 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x08,     /* [5299] OBJ_hmacWithSHA224 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x09,     /* [5307] OBJ_hmacWithSHA256 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0A,     /* [5315] OBJ_hmacWithSHA384 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0B,     /* [5323] OBJ_hmacWithSHA512 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x01,/* [5331] OBJ_dsa_with_SHA224 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x02,/* [5340] OBJ_dsa_with_SHA256 */
+0x28,0xCF,0x06,0x03,0x00,0x37,               /* [5349] OBJ_whirlpool */
+0x2A,0x85,0x03,0x02,0x02,                    /* [5355] OBJ_cryptopro */
+0x2A,0x85,0x03,0x02,0x09,                    /* [5360] OBJ_cryptocom */
+0x2A,0x85,0x03,0x02,0x02,0x03,               /* [5365] OBJ_id_GostR3411_94_with_GostR3410_2001 */
+0x2A,0x85,0x03,0x02,0x02,0x04,               /* [5371] OBJ_id_GostR3411_94_with_GostR3410_94 */
+0x2A,0x85,0x03,0x02,0x02,0x09,               /* [5377] OBJ_id_GostR3411_94 */
+0x2A,0x85,0x03,0x02,0x02,0x0A,               /* [5383] OBJ_id_HMACGostR3411_94 */
+0x2A,0x85,0x03,0x02,0x02,0x13,               /* [5389] OBJ_id_GostR3410_2001 */
+0x2A,0x85,0x03,0x02,0x02,0x14,               /* [5395] OBJ_id_GostR3410_94 */
+0x2A,0x85,0x03,0x02,0x02,0x15,               /* [5401] OBJ_id_Gost28147_89 */
+0x2A,0x85,0x03,0x02,0x02,0x16,               /* [5407] OBJ_id_Gost28147_89_MAC */
+0x2A,0x85,0x03,0x02,0x02,0x17,               /* [5413] OBJ_id_GostR3411_94_prf */
+0x2A,0x85,0x03,0x02,0x02,0x62,               /* [5419] OBJ_id_GostR3410_2001DH */
+0x2A,0x85,0x03,0x02,0x02,0x63,               /* [5425] OBJ_id_GostR3410_94DH */
+0x2A,0x85,0x03,0x02,0x02,0x0E,0x01,          /* [5431] OBJ_id_Gost28147_89_CryptoPro_KeyMeshing */
+0x2A,0x85,0x03,0x02,0x02,0x0E,0x00,          /* [5438] OBJ_id_Gost28147_89_None_KeyMeshing */
+0x2A,0x85,0x03,0x02,0x02,0x1E,0x00,          /* [5445] OBJ_id_GostR3411_94_TestParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1E,0x01,          /* [5452] OBJ_id_GostR3411_94_CryptoProParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x00,          /* [5459] OBJ_id_Gost28147_89_TestParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x01,          /* [5466] OBJ_id_Gost28147_89_CryptoPro_A_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x02,          /* [5473] OBJ_id_Gost28147_89_CryptoPro_B_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x03,          /* [5480] OBJ_id_Gost28147_89_CryptoPro_C_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x04,          /* [5487] OBJ_id_Gost28147_89_CryptoPro_D_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x05,          /* [5494] OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x06,          /* [5501] OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x07,          /* [5508] OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x20,0x00,          /* [5515] OBJ_id_GostR3410_94_TestParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x20,0x02,          /* [5522] OBJ_id_GostR3410_94_CryptoPro_A_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x20,0x03,          /* [5529] OBJ_id_GostR3410_94_CryptoPro_B_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x20,0x04,          /* [5536] OBJ_id_GostR3410_94_CryptoPro_C_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x20,0x05,          /* [5543] OBJ_id_GostR3410_94_CryptoPro_D_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x21,0x01,          /* [5550] OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x21,0x02,          /* [5557] OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x21,0x03,          /* [5564] OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x23,0x00,          /* [5571] OBJ_id_GostR3410_2001_TestParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x23,0x01,          /* [5578] OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x23,0x02,          /* [5585] OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x23,0x03,          /* [5592] OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x24,0x00,          /* [5599] OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x24,0x01,          /* [5606] OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x14,0x01,          /* [5613] OBJ_id_GostR3410_94_a */
+0x2A,0x85,0x03,0x02,0x02,0x14,0x02,          /* [5620] OBJ_id_GostR3410_94_aBis */
+0x2A,0x85,0x03,0x02,0x02,0x14,0x03,          /* [5627] OBJ_id_GostR3410_94_b */
+0x2A,0x85,0x03,0x02,0x02,0x14,0x04,          /* [5634] OBJ_id_GostR3410_94_bBis */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x06,0x01,     /* [5641] OBJ_id_Gost28147_89_cc */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x05,0x03,     /* [5649] OBJ_id_GostR3410_94_cc */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x05,0x04,     /* [5657] OBJ_id_GostR3410_2001_cc */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x03,     /* [5665] OBJ_id_GostR3411_94_with_GostR3410_94_cc */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x04,     /* [5673] OBJ_id_GostR3411_94_with_GostR3410_2001_cc */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x08,0x01,     /* [5681] OBJ_id_GostR3410_2001_ParamSet_cc */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x02,/* [5689] OBJ_LocalKeySet */
+0x55,0x1D,0x2E,                              /* [5698] OBJ_freshest_crl */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x03,     /* [5701] OBJ_id_on_permanentIdentifier */
+0x55,0x04,0x0E,                              /* [5709] OBJ_searchGuide */
+0x55,0x04,0x0F,                              /* [5712] OBJ_businessCategory */
+0x55,0x04,0x10,                              /* [5715] OBJ_postalAddress */
+0x55,0x04,0x12,                              /* [5718] OBJ_postOfficeBox */
+0x55,0x04,0x13,                              /* [5721] OBJ_physicalDeliveryOfficeName */
+0x55,0x04,0x14,                              /* [5724] OBJ_telephoneNumber */
+0x55,0x04,0x15,                              /* [5727] OBJ_telexNumber */
+0x55,0x04,0x16,                              /* [5730] OBJ_teletexTerminalIdentifier */
+0x55,0x04,0x17,                              /* [5733] OBJ_facsimileTelephoneNumber */
+0x55,0x04,0x18,                              /* [5736] OBJ_x121Address */
+0x55,0x04,0x19,                              /* [5739] OBJ_internationaliSDNNumber */
+0x55,0x04,0x1A,                              /* [5742] OBJ_registeredAddress */
+0x55,0x04,0x1B,                              /* [5745] OBJ_destinationIndicator */
+0x55,0x04,0x1C,                              /* [5748] OBJ_preferredDeliveryMethod */
+0x55,0x04,0x1D,                              /* [5751] OBJ_presentationAddress */
+0x55,0x04,0x1E,                              /* [5754] OBJ_supportedApplicationContext */
+0x55,0x04,0x1F,                              /* [5757] OBJ_member */
+0x55,0x04,0x20,                              /* [5760] OBJ_owner */
+0x55,0x04,0x21,                              /* [5763] OBJ_roleOccupant */
+0x55,0x04,0x22,                              /* [5766] OBJ_seeAlso */
+0x55,0x04,0x23,                              /* [5769] OBJ_userPassword */
+0x55,0x04,0x24,                              /* [5772] OBJ_userCertificate */
+0x55,0x04,0x25,                              /* [5775] OBJ_cACertificate */
+0x55,0x04,0x26,                              /* [5778] OBJ_authorityRevocationList */
+0x55,0x04,0x27,                              /* [5781] OBJ_certificateRevocationList */
+0x55,0x04,0x28,                              /* [5784] OBJ_crossCertificatePair */
+0x55,0x04,0x2F,                              /* [5787] OBJ_enhancedSearchGuide */
+0x55,0x04,0x30,                              /* [5790] OBJ_protocolInformation */
+0x55,0x04,0x31,                              /* [5793] OBJ_distinguishedName */
+0x55,0x04,0x32,                              /* [5796] OBJ_uniqueMember */
+0x55,0x04,0x33,                              /* [5799] OBJ_houseIdentifier */
+0x55,0x04,0x34,                              /* [5802] OBJ_supportedAlgorithms */
+0x55,0x04,0x35,                              /* [5805] OBJ_deltaRevocationList */
+0x55,0x04,0x36,                              /* [5808] OBJ_dmdName */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x09,/* [5811] OBJ_id_alg_PWRI_KEK */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x06,/* [5822] OBJ_aes_128_gcm */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x07,/* [5831] OBJ_aes_128_ccm */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x08,/* [5840] OBJ_id_aes128_wrap_pad */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1A,/* [5849] OBJ_aes_192_gcm */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1B,/* [5858] OBJ_aes_192_ccm */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1C,/* [5867] OBJ_id_aes192_wrap_pad */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2E,/* [5876] OBJ_aes_256_gcm */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2F,/* [5885] OBJ_aes_256_ccm */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x30,/* [5894] OBJ_id_aes256_wrap_pad */
+0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x02,/* [5903] OBJ_id_camellia128_wrap */
+0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x03,/* [5914] OBJ_id_camellia192_wrap */
+0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x04,/* [5925] OBJ_id_camellia256_wrap */
+0x55,0x1D,0x25,0x00,                         /* [5936] OBJ_anyExtendedKeyUsage */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x08,/* [5940] OBJ_mgf1 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0A,/* [5949] OBJ_rsassaPss */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x07,/* [5958] OBJ_rsaesOaep */
+0x2A,0x86,0x48,0xCE,0x3E,0x02,0x01,          /* [5967] OBJ_dhpublicnumber */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01,/* [5974] OBJ_brainpoolP160r1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x02,/* [5983] OBJ_brainpoolP160t1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03,/* [5992] OBJ_brainpoolP192r1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x04,/* [6001] OBJ_brainpoolP192t1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05,/* [6010] OBJ_brainpoolP224r1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x06,/* [6019] OBJ_brainpoolP224t1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07,/* [6028] OBJ_brainpoolP256r1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x08,/* [6037] OBJ_brainpoolP256t1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09,/* [6046] OBJ_brainpoolP320r1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0A,/* [6055] OBJ_brainpoolP320t1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B,/* [6064] OBJ_brainpoolP384r1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0C,/* [6073] OBJ_brainpoolP384t1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D,/* [6082] OBJ_brainpoolP512r1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0E,/* [6091] OBJ_brainpoolP512t1 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x09,/* [6100] OBJ_pSpecified */
+0x2B,0x81,0x05,0x10,0x86,0x48,0x3F,0x00,0x02,/* [6109] OBJ_dhSinglePass_stdDH_sha1kdf_scheme */
+0x2B,0x81,0x04,0x01,0x0B,0x00,               /* [6118] OBJ_dhSinglePass_stdDH_sha224kdf_scheme */
+0x2B,0x81,0x04,0x01,0x0B,0x01,               /* [6124] OBJ_dhSinglePass_stdDH_sha256kdf_scheme */
+0x2B,0x81,0x04,0x01,0x0B,0x02,               /* [6130] OBJ_dhSinglePass_stdDH_sha384kdf_scheme */
+0x2B,0x81,0x04,0x01,0x0B,0x03,               /* [6136] OBJ_dhSinglePass_stdDH_sha512kdf_scheme */
+0x2B,0x81,0x05,0x10,0x86,0x48,0x3F,0x00,0x03,/* [6142] OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme */
+0x2B,0x81,0x04,0x01,0x0E,0x00,               /* [6151] OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme */
+0x2B,0x81,0x04,0x01,0x0E,0x01,               /* [6157] OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme */
+0x2B,0x81,0x04,0x01,0x0E,0x02,               /* [6163] OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme */
+0x2B,0x81,0x04,0x01,0x0E,0x03,               /* [6169] OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme */
 };
 
 static const ASN1_OBJECT kObjects[NUM_NID]={
@@ -1110,880 +1109,880 @@
 {"RC5-ECB","rc5-ecb",NID_rc5_ecb,0,NULL,0},
 {"RC5-CFB","rc5-cfb",NID_rc5_cfb64,0,NULL,0},
 {"RC5-OFB","rc5-ofb",NID_rc5_ofb64,0,NULL,0},
-{"RLE","run length compression",NID_rle_compression,6,&(lvalues[616]),0},
-{"ZLIB","zlib compression",NID_zlib_compression,11,&(lvalues[622]),0},
+{NULL,NULL,NID_undef,0,NULL,0},
+{"ZLIB","zlib compression",NID_zlib_compression,11,&(lvalues[616]),0},
 {"extendedKeyUsage","X509v3 Extended Key Usage",NID_ext_key_usage,3,
-	&(lvalues[633]),0},
-{"PKIX","PKIX",NID_id_pkix,6,&(lvalues[636]),0},
-{"id-kp","id-kp",NID_id_kp,7,&(lvalues[642]),0},
+	&(lvalues[627]),0},
+{"PKIX","PKIX",NID_id_pkix,6,&(lvalues[630]),0},
+{"id-kp","id-kp",NID_id_kp,7,&(lvalues[636]),0},
 {"serverAuth","TLS Web Server Authentication",NID_server_auth,8,
-	&(lvalues[649]),0},
+	&(lvalues[643]),0},
 {"clientAuth","TLS Web Client Authentication",NID_client_auth,8,
-	&(lvalues[657]),0},
-{"codeSigning","Code Signing",NID_code_sign,8,&(lvalues[665]),0},
+	&(lvalues[651]),0},
+{"codeSigning","Code Signing",NID_code_sign,8,&(lvalues[659]),0},
 {"emailProtection","E-mail Protection",NID_email_protect,8,
-	&(lvalues[673]),0},
-{"timeStamping","Time Stamping",NID_time_stamp,8,&(lvalues[681]),0},
+	&(lvalues[667]),0},
+{"timeStamping","Time Stamping",NID_time_stamp,8,&(lvalues[675]),0},
 {"msCodeInd","Microsoft Individual Code Signing",NID_ms_code_ind,10,
-	&(lvalues[689]),0},
+	&(lvalues[683]),0},
 {"msCodeCom","Microsoft Commercial Code Signing",NID_ms_code_com,10,
-	&(lvalues[699]),0},
+	&(lvalues[693]),0},
 {"msCTLSign","Microsoft Trust List Signing",NID_ms_ctl_sign,10,
-	&(lvalues[709]),0},
-{"msSGC","Microsoft Server Gated Crypto",NID_ms_sgc,10,&(lvalues[719]),0},
+	&(lvalues[703]),0},
+{"msSGC","Microsoft Server Gated Crypto",NID_ms_sgc,10,&(lvalues[713]),0},
 {"msEFS","Microsoft Encrypted File System",NID_ms_efs,10,
-	&(lvalues[729]),0},
-{"nsSGC","Netscape Server Gated Crypto",NID_ns_sgc,9,&(lvalues[739]),0},
+	&(lvalues[723]),0},
+{"nsSGC","Netscape Server Gated Crypto",NID_ns_sgc,9,&(lvalues[733]),0},
 {"deltaCRL","X509v3 Delta CRL Indicator",NID_delta_crl,3,
-	&(lvalues[748]),0},
-{"CRLReason","X509v3 CRL Reason Code",NID_crl_reason,3,&(lvalues[751]),0},
+	&(lvalues[742]),0},
+{"CRLReason","X509v3 CRL Reason Code",NID_crl_reason,3,&(lvalues[745]),0},
 {"invalidityDate","Invalidity Date",NID_invalidity_date,3,
-	&(lvalues[754]),0},
-{"SXNetID","Strong Extranet ID",NID_sxnet,5,&(lvalues[757]),0},
+	&(lvalues[748]),0},
+{"SXNetID","Strong Extranet ID",NID_sxnet,5,&(lvalues[751]),0},
 {"PBE-SHA1-RC4-128","pbeWithSHA1And128BitRC4",
-	NID_pbe_WithSHA1And128BitRC4,10,&(lvalues[762]),0},
+	NID_pbe_WithSHA1And128BitRC4,10,&(lvalues[756]),0},
 {"PBE-SHA1-RC4-40","pbeWithSHA1And40BitRC4",
-	NID_pbe_WithSHA1And40BitRC4,10,&(lvalues[772]),0},
+	NID_pbe_WithSHA1And40BitRC4,10,&(lvalues[766]),0},
 {"PBE-SHA1-3DES","pbeWithSHA1And3-KeyTripleDES-CBC",
-	NID_pbe_WithSHA1And3_Key_TripleDES_CBC,10,&(lvalues[782]),0},
+	NID_pbe_WithSHA1And3_Key_TripleDES_CBC,10,&(lvalues[776]),0},
 {"PBE-SHA1-2DES","pbeWithSHA1And2-KeyTripleDES-CBC",
-	NID_pbe_WithSHA1And2_Key_TripleDES_CBC,10,&(lvalues[792]),0},
+	NID_pbe_WithSHA1And2_Key_TripleDES_CBC,10,&(lvalues[786]),0},
 {"PBE-SHA1-RC2-128","pbeWithSHA1And128BitRC2-CBC",
-	NID_pbe_WithSHA1And128BitRC2_CBC,10,&(lvalues[802]),0},
+	NID_pbe_WithSHA1And128BitRC2_CBC,10,&(lvalues[796]),0},
 {"PBE-SHA1-RC2-40","pbeWithSHA1And40BitRC2-CBC",
-	NID_pbe_WithSHA1And40BitRC2_CBC,10,&(lvalues[812]),0},
-{"keyBag","keyBag",NID_keyBag,11,&(lvalues[822]),0},
+	NID_pbe_WithSHA1And40BitRC2_CBC,10,&(lvalues[806]),0},
+{"keyBag","keyBag",NID_keyBag,11,&(lvalues[816]),0},
 {"pkcs8ShroudedKeyBag","pkcs8ShroudedKeyBag",NID_pkcs8ShroudedKeyBag,
-	11,&(lvalues[833]),0},
-{"certBag","certBag",NID_certBag,11,&(lvalues[844]),0},
-{"crlBag","crlBag",NID_crlBag,11,&(lvalues[855]),0},
-{"secretBag","secretBag",NID_secretBag,11,&(lvalues[866]),0},
+	11,&(lvalues[827]),0},
+{"certBag","certBag",NID_certBag,11,&(lvalues[838]),0},
+{"crlBag","crlBag",NID_crlBag,11,&(lvalues[849]),0},
+{"secretBag","secretBag",NID_secretBag,11,&(lvalues[860]),0},
 {"safeContentsBag","safeContentsBag",NID_safeContentsBag,11,
-	&(lvalues[877]),0},
-{"friendlyName","friendlyName",NID_friendlyName,9,&(lvalues[888]),0},
-{"localKeyID","localKeyID",NID_localKeyID,9,&(lvalues[897]),0},
+	&(lvalues[871]),0},
+{"friendlyName","friendlyName",NID_friendlyName,9,&(lvalues[882]),0},
+{"localKeyID","localKeyID",NID_localKeyID,9,&(lvalues[891]),0},
 {"x509Certificate","x509Certificate",NID_x509Certificate,10,
-	&(lvalues[906]),0},
+	&(lvalues[900]),0},
 {"sdsiCertificate","sdsiCertificate",NID_sdsiCertificate,10,
-	&(lvalues[916]),0},
-{"x509Crl","x509Crl",NID_x509Crl,10,&(lvalues[926]),0},
-{"PBES2","PBES2",NID_pbes2,9,&(lvalues[936]),0},
-{"PBMAC1","PBMAC1",NID_pbmac1,9,&(lvalues[945]),0},
-{"hmacWithSHA1","hmacWithSHA1",NID_hmacWithSHA1,8,&(lvalues[954]),0},
-{"id-qt-cps","Policy Qualifier CPS",NID_id_qt_cps,8,&(lvalues[962]),0},
+	&(lvalues[910]),0},
+{"x509Crl","x509Crl",NID_x509Crl,10,&(lvalues[920]),0},
+{"PBES2","PBES2",NID_pbes2,9,&(lvalues[930]),0},
+{"PBMAC1","PBMAC1",NID_pbmac1,9,&(lvalues[939]),0},
+{"hmacWithSHA1","hmacWithSHA1",NID_hmacWithSHA1,8,&(lvalues[948]),0},
+{"id-qt-cps","Policy Qualifier CPS",NID_id_qt_cps,8,&(lvalues[956]),0},
 {"id-qt-unotice","Policy Qualifier User Notice",NID_id_qt_unotice,8,
-	&(lvalues[970]),0},
+	&(lvalues[964]),0},
 {"RC2-64-CBC","rc2-64-cbc",NID_rc2_64_cbc,0,NULL,0},
 {"SMIME-CAPS","S/MIME Capabilities",NID_SMIMECapabilities,9,
-	&(lvalues[978]),0},
+	&(lvalues[972]),0},
 {"PBE-MD2-RC2-64","pbeWithMD2AndRC2-CBC",NID_pbeWithMD2AndRC2_CBC,9,
-	&(lvalues[987]),0},
+	&(lvalues[981]),0},
 {"PBE-MD5-RC2-64","pbeWithMD5AndRC2-CBC",NID_pbeWithMD5AndRC2_CBC,9,
-	&(lvalues[996]),0},
+	&(lvalues[990]),0},
 {"PBE-SHA1-DES","pbeWithSHA1AndDES-CBC",NID_pbeWithSHA1AndDES_CBC,9,
-	&(lvalues[1005]),0},
+	&(lvalues[999]),0},
 {"msExtReq","Microsoft Extension Request",NID_ms_ext_req,10,
-	&(lvalues[1014]),0},
-{"extReq","Extension Request",NID_ext_req,9,&(lvalues[1024]),0},
-{"name","name",NID_name,3,&(lvalues[1033]),0},
-{"dnQualifier","dnQualifier",NID_dnQualifier,3,&(lvalues[1036]),0},
-{"id-pe","id-pe",NID_id_pe,7,&(lvalues[1039]),0},
-{"id-ad","id-ad",NID_id_ad,7,&(lvalues[1046]),0},
+	&(lvalues[1008]),0},
+{"extReq","Extension Request",NID_ext_req,9,&(lvalues[1018]),0},
+{"name","name",NID_name,3,&(lvalues[1027]),0},
+{"dnQualifier","dnQualifier",NID_dnQualifier,3,&(lvalues[1030]),0},
+{"id-pe","id-pe",NID_id_pe,7,&(lvalues[1033]),0},
+{"id-ad","id-ad",NID_id_ad,7,&(lvalues[1040]),0},
 {"authorityInfoAccess","Authority Information Access",NID_info_access,
-	8,&(lvalues[1053]),0},
-{"OCSP","OCSP",NID_ad_OCSP,8,&(lvalues[1061]),0},
-{"caIssuers","CA Issuers",NID_ad_ca_issuers,8,&(lvalues[1069]),0},
-{"OCSPSigning","OCSP Signing",NID_OCSP_sign,8,&(lvalues[1077]),0},
+	8,&(lvalues[1047]),0},
+{"OCSP","OCSP",NID_ad_OCSP,8,&(lvalues[1055]),0},
+{"caIssuers","CA Issuers",NID_ad_ca_issuers,8,&(lvalues[1063]),0},
+{"OCSPSigning","OCSP Signing",NID_OCSP_sign,8,&(lvalues[1071]),0},
 {"ISO","iso",NID_iso,0,NULL,0},
-{"member-body","ISO Member Body",NID_member_body,1,&(lvalues[1085]),0},
-{"ISO-US","ISO US Member Body",NID_ISO_US,3,&(lvalues[1086]),0},
-{"X9-57","X9.57",NID_X9_57,5,&(lvalues[1089]),0},
-{"X9cm","X9.57 CM ?",NID_X9cm,6,&(lvalues[1094]),0},
-{"pkcs1","pkcs1",NID_pkcs1,8,&(lvalues[1100]),0},
-{"pkcs5","pkcs5",NID_pkcs5,8,&(lvalues[1108]),0},
-{"SMIME","S/MIME",NID_SMIME,9,&(lvalues[1116]),0},
-{"id-smime-mod","id-smime-mod",NID_id_smime_mod,10,&(lvalues[1125]),0},
-{"id-smime-ct","id-smime-ct",NID_id_smime_ct,10,&(lvalues[1135]),0},
-{"id-smime-aa","id-smime-aa",NID_id_smime_aa,10,&(lvalues[1145]),0},
-{"id-smime-alg","id-smime-alg",NID_id_smime_alg,10,&(lvalues[1155]),0},
-{"id-smime-cd","id-smime-cd",NID_id_smime_cd,10,&(lvalues[1165]),0},
-{"id-smime-spq","id-smime-spq",NID_id_smime_spq,10,&(lvalues[1175]),0},
-{"id-smime-cti","id-smime-cti",NID_id_smime_cti,10,&(lvalues[1185]),0},
+{"member-body","ISO Member Body",NID_member_body,1,&(lvalues[1079]),0},
+{"ISO-US","ISO US Member Body",NID_ISO_US,3,&(lvalues[1080]),0},
+{"X9-57","X9.57",NID_X9_57,5,&(lvalues[1083]),0},
+{"X9cm","X9.57 CM ?",NID_X9cm,6,&(lvalues[1088]),0},
+{"pkcs1","pkcs1",NID_pkcs1,8,&(lvalues[1094]),0},
+{"pkcs5","pkcs5",NID_pkcs5,8,&(lvalues[1102]),0},
+{"SMIME","S/MIME",NID_SMIME,9,&(lvalues[1110]),0},
+{"id-smime-mod","id-smime-mod",NID_id_smime_mod,10,&(lvalues[1119]),0},
+{"id-smime-ct","id-smime-ct",NID_id_smime_ct,10,&(lvalues[1129]),0},
+{"id-smime-aa","id-smime-aa",NID_id_smime_aa,10,&(lvalues[1139]),0},
+{"id-smime-alg","id-smime-alg",NID_id_smime_alg,10,&(lvalues[1149]),0},
+{"id-smime-cd","id-smime-cd",NID_id_smime_cd,10,&(lvalues[1159]),0},
+{"id-smime-spq","id-smime-spq",NID_id_smime_spq,10,&(lvalues[1169]),0},
+{"id-smime-cti","id-smime-cti",NID_id_smime_cti,10,&(lvalues[1179]),0},
 {"id-smime-mod-cms","id-smime-mod-cms",NID_id_smime_mod_cms,11,
-	&(lvalues[1195]),0},
+	&(lvalues[1189]),0},
 {"id-smime-mod-ess","id-smime-mod-ess",NID_id_smime_mod_ess,11,
-	&(lvalues[1206]),0},
+	&(lvalues[1200]),0},
 {"id-smime-mod-oid","id-smime-mod-oid",NID_id_smime_mod_oid,11,
-	&(lvalues[1217]),0},
+	&(lvalues[1211]),0},
 {"id-smime-mod-msg-v3","id-smime-mod-msg-v3",NID_id_smime_mod_msg_v3,
-	11,&(lvalues[1228]),0},
+	11,&(lvalues[1222]),0},
 {"id-smime-mod-ets-eSignature-88","id-smime-mod-ets-eSignature-88",
-	NID_id_smime_mod_ets_eSignature_88,11,&(lvalues[1239]),0},
+	NID_id_smime_mod_ets_eSignature_88,11,&(lvalues[1233]),0},
 {"id-smime-mod-ets-eSignature-97","id-smime-mod-ets-eSignature-97",
-	NID_id_smime_mod_ets_eSignature_97,11,&(lvalues[1250]),0},
+	NID_id_smime_mod_ets_eSignature_97,11,&(lvalues[1244]),0},
 {"id-smime-mod-ets-eSigPolicy-88","id-smime-mod-ets-eSigPolicy-88",
-	NID_id_smime_mod_ets_eSigPolicy_88,11,&(lvalues[1261]),0},
+	NID_id_smime_mod_ets_eSigPolicy_88,11,&(lvalues[1255]),0},
 {"id-smime-mod-ets-eSigPolicy-97","id-smime-mod-ets-eSigPolicy-97",
-	NID_id_smime_mod_ets_eSigPolicy_97,11,&(lvalues[1272]),0},
+	NID_id_smime_mod_ets_eSigPolicy_97,11,&(lvalues[1266]),0},
 {"id-smime-ct-receipt","id-smime-ct-receipt",NID_id_smime_ct_receipt,
-	11,&(lvalues[1283]),0},
+	11,&(lvalues[1277]),0},
 {"id-smime-ct-authData","id-smime-ct-authData",
-	NID_id_smime_ct_authData,11,&(lvalues[1294]),0},
+	NID_id_smime_ct_authData,11,&(lvalues[1288]),0},
 {"id-smime-ct-publishCert","id-smime-ct-publishCert",
-	NID_id_smime_ct_publishCert,11,&(lvalues[1305]),0},
+	NID_id_smime_ct_publishCert,11,&(lvalues[1299]),0},
 {"id-smime-ct-TSTInfo","id-smime-ct-TSTInfo",NID_id_smime_ct_TSTInfo,
-	11,&(lvalues[1316]),0},
+	11,&(lvalues[1310]),0},
 {"id-smime-ct-TDTInfo","id-smime-ct-TDTInfo",NID_id_smime_ct_TDTInfo,
-	11,&(lvalues[1327]),0},
+	11,&(lvalues[1321]),0},
 {"id-smime-ct-contentInfo","id-smime-ct-contentInfo",
-	NID_id_smime_ct_contentInfo,11,&(lvalues[1338]),0},
+	NID_id_smime_ct_contentInfo,11,&(lvalues[1332]),0},
 {"id-smime-ct-DVCSRequestData","id-smime-ct-DVCSRequestData",
-	NID_id_smime_ct_DVCSRequestData,11,&(lvalues[1349]),0},
+	NID_id_smime_ct_DVCSRequestData,11,&(lvalues[1343]),0},
 {"id-smime-ct-DVCSResponseData","id-smime-ct-DVCSResponseData",
-	NID_id_smime_ct_DVCSResponseData,11,&(lvalues[1360]),0},
+	NID_id_smime_ct_DVCSResponseData,11,&(lvalues[1354]),0},
 {"id-smime-aa-receiptRequest","id-smime-aa-receiptRequest",
-	NID_id_smime_aa_receiptRequest,11,&(lvalues[1371]),0},
+	NID_id_smime_aa_receiptRequest,11,&(lvalues[1365]),0},
 {"id-smime-aa-securityLabel","id-smime-aa-securityLabel",
-	NID_id_smime_aa_securityLabel,11,&(lvalues[1382]),0},
+	NID_id_smime_aa_securityLabel,11,&(lvalues[1376]),0},
 {"id-smime-aa-mlExpandHistory","id-smime-aa-mlExpandHistory",
-	NID_id_smime_aa_mlExpandHistory,11,&(lvalues[1393]),0},
+	NID_id_smime_aa_mlExpandHistory,11,&(lvalues[1387]),0},
 {"id-smime-aa-contentHint","id-smime-aa-contentHint",
-	NID_id_smime_aa_contentHint,11,&(lvalues[1404]),0},
+	NID_id_smime_aa_contentHint,11,&(lvalues[1398]),0},
 {"id-smime-aa-msgSigDigest","id-smime-aa-msgSigDigest",
-	NID_id_smime_aa_msgSigDigest,11,&(lvalues[1415]),0},
+	NID_id_smime_aa_msgSigDigest,11,&(lvalues[1409]),0},
 {"id-smime-aa-encapContentType","id-smime-aa-encapContentType",
-	NID_id_smime_aa_encapContentType,11,&(lvalues[1426]),0},
+	NID_id_smime_aa_encapContentType,11,&(lvalues[1420]),0},
 {"id-smime-aa-contentIdentifier","id-smime-aa-contentIdentifier",
-	NID_id_smime_aa_contentIdentifier,11,&(lvalues[1437]),0},
+	NID_id_smime_aa_contentIdentifier,11,&(lvalues[1431]),0},
 {"id-smime-aa-macValue","id-smime-aa-macValue",
-	NID_id_smime_aa_macValue,11,&(lvalues[1448]),0},
+	NID_id_smime_aa_macValue,11,&(lvalues[1442]),0},
 {"id-smime-aa-equivalentLabels","id-smime-aa-equivalentLabels",
-	NID_id_smime_aa_equivalentLabels,11,&(lvalues[1459]),0},
+	NID_id_smime_aa_equivalentLabels,11,&(lvalues[1453]),0},
 {"id-smime-aa-contentReference","id-smime-aa-contentReference",
-	NID_id_smime_aa_contentReference,11,&(lvalues[1470]),0},
+	NID_id_smime_aa_contentReference,11,&(lvalues[1464]),0},
 {"id-smime-aa-encrypKeyPref","id-smime-aa-encrypKeyPref",
-	NID_id_smime_aa_encrypKeyPref,11,&(lvalues[1481]),0},
+	NID_id_smime_aa_encrypKeyPref,11,&(lvalues[1475]),0},
 {"id-smime-aa-signingCertificate","id-smime-aa-signingCertificate",
-	NID_id_smime_aa_signingCertificate,11,&(lvalues[1492]),0},
+	NID_id_smime_aa_signingCertificate,11,&(lvalues[1486]),0},
 {"id-smime-aa-smimeEncryptCerts","id-smime-aa-smimeEncryptCerts",
-	NID_id_smime_aa_smimeEncryptCerts,11,&(lvalues[1503]),0},
+	NID_id_smime_aa_smimeEncryptCerts,11,&(lvalues[1497]),0},
 {"id-smime-aa-timeStampToken","id-smime-aa-timeStampToken",
-	NID_id_smime_aa_timeStampToken,11,&(lvalues[1514]),0},
+	NID_id_smime_aa_timeStampToken,11,&(lvalues[1508]),0},
 {"id-smime-aa-ets-sigPolicyId","id-smime-aa-ets-sigPolicyId",
-	NID_id_smime_aa_ets_sigPolicyId,11,&(lvalues[1525]),0},
+	NID_id_smime_aa_ets_sigPolicyId,11,&(lvalues[1519]),0},
 {"id-smime-aa-ets-commitmentType","id-smime-aa-ets-commitmentType",
-	NID_id_smime_aa_ets_commitmentType,11,&(lvalues[1536]),0},
+	NID_id_smime_aa_ets_commitmentType,11,&(lvalues[1530]),0},
 {"id-smime-aa-ets-signerLocation","id-smime-aa-ets-signerLocation",
-	NID_id_smime_aa_ets_signerLocation,11,&(lvalues[1547]),0},
+	NID_id_smime_aa_ets_signerLocation,11,&(lvalues[1541]),0},
 {"id-smime-aa-ets-signerAttr","id-smime-aa-ets-signerAttr",
-	NID_id_smime_aa_ets_signerAttr,11,&(lvalues[1558]),0},
+	NID_id_smime_aa_ets_signerAttr,11,&(lvalues[1552]),0},
 {"id-smime-aa-ets-otherSigCert","id-smime-aa-ets-otherSigCert",
-	NID_id_smime_aa_ets_otherSigCert,11,&(lvalues[1569]),0},
+	NID_id_smime_aa_ets_otherSigCert,11,&(lvalues[1563]),0},
 {"id-smime-aa-ets-contentTimestamp",
 	"id-smime-aa-ets-contentTimestamp",
-	NID_id_smime_aa_ets_contentTimestamp,11,&(lvalues[1580]),0},
+	NID_id_smime_aa_ets_contentTimestamp,11,&(lvalues[1574]),0},
 {"id-smime-aa-ets-CertificateRefs","id-smime-aa-ets-CertificateRefs",
-	NID_id_smime_aa_ets_CertificateRefs,11,&(lvalues[1591]),0},
+	NID_id_smime_aa_ets_CertificateRefs,11,&(lvalues[1585]),0},
 {"id-smime-aa-ets-RevocationRefs","id-smime-aa-ets-RevocationRefs",
-	NID_id_smime_aa_ets_RevocationRefs,11,&(lvalues[1602]),0},
+	NID_id_smime_aa_ets_RevocationRefs,11,&(lvalues[1596]),0},
 {"id-smime-aa-ets-certValues","id-smime-aa-ets-certValues",
-	NID_id_smime_aa_ets_certValues,11,&(lvalues[1613]),0},
+	NID_id_smime_aa_ets_certValues,11,&(lvalues[1607]),0},
 {"id-smime-aa-ets-revocationValues",
 	"id-smime-aa-ets-revocationValues",
-	NID_id_smime_aa_ets_revocationValues,11,&(lvalues[1624]),0},
+	NID_id_smime_aa_ets_revocationValues,11,&(lvalues[1618]),0},
 {"id-smime-aa-ets-escTimeStamp","id-smime-aa-ets-escTimeStamp",
-	NID_id_smime_aa_ets_escTimeStamp,11,&(lvalues[1635]),0},
+	NID_id_smime_aa_ets_escTimeStamp,11,&(lvalues[1629]),0},
 {"id-smime-aa-ets-certCRLTimestamp",
 	"id-smime-aa-ets-certCRLTimestamp",
-	NID_id_smime_aa_ets_certCRLTimestamp,11,&(lvalues[1646]),0},
+	NID_id_smime_aa_ets_certCRLTimestamp,11,&(lvalues[1640]),0},
 {"id-smime-aa-ets-archiveTimeStamp",
 	"id-smime-aa-ets-archiveTimeStamp",
-	NID_id_smime_aa_ets_archiveTimeStamp,11,&(lvalues[1657]),0},
+	NID_id_smime_aa_ets_archiveTimeStamp,11,&(lvalues[1651]),0},
 {"id-smime-aa-signatureType","id-smime-aa-signatureType",
-	NID_id_smime_aa_signatureType,11,&(lvalues[1668]),0},
+	NID_id_smime_aa_signatureType,11,&(lvalues[1662]),0},
 {"id-smime-aa-dvcs-dvc","id-smime-aa-dvcs-dvc",
-	NID_id_smime_aa_dvcs_dvc,11,&(lvalues[1679]),0},
+	NID_id_smime_aa_dvcs_dvc,11,&(lvalues[1673]),0},
 {"id-smime-alg-ESDHwith3DES","id-smime-alg-ESDHwith3DES",
-	NID_id_smime_alg_ESDHwith3DES,11,&(lvalues[1690]),0},
+	NID_id_smime_alg_ESDHwith3DES,11,&(lvalues[1684]),0},
 {"id-smime-alg-ESDHwithRC2","id-smime-alg-ESDHwithRC2",
-	NID_id_smime_alg_ESDHwithRC2,11,&(lvalues[1701]),0},
+	NID_id_smime_alg_ESDHwithRC2,11,&(lvalues[1695]),0},
 {"id-smime-alg-3DESwrap","id-smime-alg-3DESwrap",
-	NID_id_smime_alg_3DESwrap,11,&(lvalues[1712]),0},
+	NID_id_smime_alg_3DESwrap,11,&(lvalues[1706]),0},
 {"id-smime-alg-RC2wrap","id-smime-alg-RC2wrap",
-	NID_id_smime_alg_RC2wrap,11,&(lvalues[1723]),0},
+	NID_id_smime_alg_RC2wrap,11,&(lvalues[1717]),0},
 {"id-smime-alg-ESDH","id-smime-alg-ESDH",NID_id_smime_alg_ESDH,11,
-	&(lvalues[1734]),0},
+	&(lvalues[1728]),0},
 {"id-smime-alg-CMS3DESwrap","id-smime-alg-CMS3DESwrap",
-	NID_id_smime_alg_CMS3DESwrap,11,&(lvalues[1745]),0},
+	NID_id_smime_alg_CMS3DESwrap,11,&(lvalues[1739]),0},
 {"id-smime-alg-CMSRC2wrap","id-smime-alg-CMSRC2wrap",
-	NID_id_smime_alg_CMSRC2wrap,11,&(lvalues[1756]),0},
+	NID_id_smime_alg_CMSRC2wrap,11,&(lvalues[1750]),0},
 {"id-smime-cd-ldap","id-smime-cd-ldap",NID_id_smime_cd_ldap,11,
-	&(lvalues[1767]),0},
+	&(lvalues[1761]),0},
 {"id-smime-spq-ets-sqt-uri","id-smime-spq-ets-sqt-uri",
-	NID_id_smime_spq_ets_sqt_uri,11,&(lvalues[1778]),0},
+	NID_id_smime_spq_ets_sqt_uri,11,&(lvalues[1772]),0},
 {"id-smime-spq-ets-sqt-unotice","id-smime-spq-ets-sqt-unotice",
-	NID_id_smime_spq_ets_sqt_unotice,11,&(lvalues[1789]),0},
+	NID_id_smime_spq_ets_sqt_unotice,11,&(lvalues[1783]),0},
 {"id-smime-cti-ets-proofOfOrigin","id-smime-cti-ets-proofOfOrigin",
-	NID_id_smime_cti_ets_proofOfOrigin,11,&(lvalues[1800]),0},
+	NID_id_smime_cti_ets_proofOfOrigin,11,&(lvalues[1794]),0},
 {"id-smime-cti-ets-proofOfReceipt","id-smime-cti-ets-proofOfReceipt",
-	NID_id_smime_cti_ets_proofOfReceipt,11,&(lvalues[1811]),0},
+	NID_id_smime_cti_ets_proofOfReceipt,11,&(lvalues[1805]),0},
 {"id-smime-cti-ets-proofOfDelivery",
 	"id-smime-cti-ets-proofOfDelivery",
-	NID_id_smime_cti_ets_proofOfDelivery,11,&(lvalues[1822]),0},
+	NID_id_smime_cti_ets_proofOfDelivery,11,&(lvalues[1816]),0},
 {"id-smime-cti-ets-proofOfSender","id-smime-cti-ets-proofOfSender",
-	NID_id_smime_cti_ets_proofOfSender,11,&(lvalues[1833]),0},
+	NID_id_smime_cti_ets_proofOfSender,11,&(lvalues[1827]),0},
 {"id-smime-cti-ets-proofOfApproval",
 	"id-smime-cti-ets-proofOfApproval",
-	NID_id_smime_cti_ets_proofOfApproval,11,&(lvalues[1844]),0},
+	NID_id_smime_cti_ets_proofOfApproval,11,&(lvalues[1838]),0},
 {"id-smime-cti-ets-proofOfCreation",
 	"id-smime-cti-ets-proofOfCreation",
-	NID_id_smime_cti_ets_proofOfCreation,11,&(lvalues[1855]),0},
-{"MD4","md4",NID_md4,8,&(lvalues[1866]),0},
-{"id-pkix-mod","id-pkix-mod",NID_id_pkix_mod,7,&(lvalues[1874]),0},
-{"id-qt","id-qt",NID_id_qt,7,&(lvalues[1881]),0},
-{"id-it","id-it",NID_id_it,7,&(lvalues[1888]),0},
-{"id-pkip","id-pkip",NID_id_pkip,7,&(lvalues[1895]),0},
-{"id-alg","id-alg",NID_id_alg,7,&(lvalues[1902]),0},
-{"id-cmc","id-cmc",NID_id_cmc,7,&(lvalues[1909]),0},
-{"id-on","id-on",NID_id_on,7,&(lvalues[1916]),0},
-{"id-pda","id-pda",NID_id_pda,7,&(lvalues[1923]),0},
-{"id-aca","id-aca",NID_id_aca,7,&(lvalues[1930]),0},
-{"id-qcs","id-qcs",NID_id_qcs,7,&(lvalues[1937]),0},
-{"id-cct","id-cct",NID_id_cct,7,&(lvalues[1944]),0},
+	NID_id_smime_cti_ets_proofOfCreation,11,&(lvalues[1849]),0},
+{"MD4","md4",NID_md4,8,&(lvalues[1860]),0},
+{"id-pkix-mod","id-pkix-mod",NID_id_pkix_mod,7,&(lvalues[1868]),0},
+{"id-qt","id-qt",NID_id_qt,7,&(lvalues[1875]),0},
+{"id-it","id-it",NID_id_it,7,&(lvalues[1882]),0},
+{"id-pkip","id-pkip",NID_id_pkip,7,&(lvalues[1889]),0},
+{"id-alg","id-alg",NID_id_alg,7,&(lvalues[1896]),0},
+{"id-cmc","id-cmc",NID_id_cmc,7,&(lvalues[1903]),0},
+{"id-on","id-on",NID_id_on,7,&(lvalues[1910]),0},
+{"id-pda","id-pda",NID_id_pda,7,&(lvalues[1917]),0},
+{"id-aca","id-aca",NID_id_aca,7,&(lvalues[1924]),0},
+{"id-qcs","id-qcs",NID_id_qcs,7,&(lvalues[1931]),0},
+{"id-cct","id-cct",NID_id_cct,7,&(lvalues[1938]),0},
 {"id-pkix1-explicit-88","id-pkix1-explicit-88",
-	NID_id_pkix1_explicit_88,8,&(lvalues[1951]),0},
+	NID_id_pkix1_explicit_88,8,&(lvalues[1945]),0},
 {"id-pkix1-implicit-88","id-pkix1-implicit-88",
-	NID_id_pkix1_implicit_88,8,&(lvalues[1959]),0},
+	NID_id_pkix1_implicit_88,8,&(lvalues[1953]),0},
 {"id-pkix1-explicit-93","id-pkix1-explicit-93",
-	NID_id_pkix1_explicit_93,8,&(lvalues[1967]),0},
+	NID_id_pkix1_explicit_93,8,&(lvalues[1961]),0},
 {"id-pkix1-implicit-93","id-pkix1-implicit-93",
-	NID_id_pkix1_implicit_93,8,&(lvalues[1975]),0},
-{"id-mod-crmf","id-mod-crmf",NID_id_mod_crmf,8,&(lvalues[1983]),0},
-{"id-mod-cmc","id-mod-cmc",NID_id_mod_cmc,8,&(lvalues[1991]),0},
+	NID_id_pkix1_implicit_93,8,&(lvalues[1969]),0},
+{"id-mod-crmf","id-mod-crmf",NID_id_mod_crmf,8,&(lvalues[1977]),0},
+{"id-mod-cmc","id-mod-cmc",NID_id_mod_cmc,8,&(lvalues[1985]),0},
 {"id-mod-kea-profile-88","id-mod-kea-profile-88",
-	NID_id_mod_kea_profile_88,8,&(lvalues[1999]),0},
+	NID_id_mod_kea_profile_88,8,&(lvalues[1993]),0},
 {"id-mod-kea-profile-93","id-mod-kea-profile-93",
-	NID_id_mod_kea_profile_93,8,&(lvalues[2007]),0},
-{"id-mod-cmp","id-mod-cmp",NID_id_mod_cmp,8,&(lvalues[2015]),0},
+	NID_id_mod_kea_profile_93,8,&(lvalues[2001]),0},
+{"id-mod-cmp","id-mod-cmp",NID_id_mod_cmp,8,&(lvalues[2009]),0},
 {"id-mod-qualified-cert-88","id-mod-qualified-cert-88",
-	NID_id_mod_qualified_cert_88,8,&(lvalues[2023]),0},
+	NID_id_mod_qualified_cert_88,8,&(lvalues[2017]),0},
 {"id-mod-qualified-cert-93","id-mod-qualified-cert-93",
-	NID_id_mod_qualified_cert_93,8,&(lvalues[2031]),0},
+	NID_id_mod_qualified_cert_93,8,&(lvalues[2025]),0},
 {"id-mod-attribute-cert","id-mod-attribute-cert",
-	NID_id_mod_attribute_cert,8,&(lvalues[2039]),0},
+	NID_id_mod_attribute_cert,8,&(lvalues[2033]),0},
 {"id-mod-timestamp-protocol","id-mod-timestamp-protocol",
-	NID_id_mod_timestamp_protocol,8,&(lvalues[2047]),0},
-{"id-mod-ocsp","id-mod-ocsp",NID_id_mod_ocsp,8,&(lvalues[2055]),0},
-{"id-mod-dvcs","id-mod-dvcs",NID_id_mod_dvcs,8,&(lvalues[2063]),0},
+	NID_id_mod_timestamp_protocol,8,&(lvalues[2041]),0},
+{"id-mod-ocsp","id-mod-ocsp",NID_id_mod_ocsp,8,&(lvalues[2049]),0},
+{"id-mod-dvcs","id-mod-dvcs",NID_id_mod_dvcs,8,&(lvalues[2057]),0},
 {"id-mod-cmp2000","id-mod-cmp2000",NID_id_mod_cmp2000,8,
-	&(lvalues[2071]),0},
-{"biometricInfo","Biometric Info",NID_biometricInfo,8,&(lvalues[2079]),0},
-{"qcStatements","qcStatements",NID_qcStatements,8,&(lvalues[2087]),0},
+	&(lvalues[2065]),0},
+{"biometricInfo","Biometric Info",NID_biometricInfo,8,&(lvalues[2073]),0},
+{"qcStatements","qcStatements",NID_qcStatements,8,&(lvalues[2081]),0},
 {"ac-auditEntity","ac-auditEntity",NID_ac_auditEntity,8,
-	&(lvalues[2095]),0},
-{"ac-targeting","ac-targeting",NID_ac_targeting,8,&(lvalues[2103]),0},
-{"aaControls","aaControls",NID_aaControls,8,&(lvalues[2111]),0},
+	&(lvalues[2089]),0},
+{"ac-targeting","ac-targeting",NID_ac_targeting,8,&(lvalues[2097]),0},
+{"aaControls","aaControls",NID_aaControls,8,&(lvalues[2105]),0},
 {"sbgp-ipAddrBlock","sbgp-ipAddrBlock",NID_sbgp_ipAddrBlock,8,
-	&(lvalues[2119]),0},
+	&(lvalues[2113]),0},
 {"sbgp-autonomousSysNum","sbgp-autonomousSysNum",
-	NID_sbgp_autonomousSysNum,8,&(lvalues[2127]),0},
+	NID_sbgp_autonomousSysNum,8,&(lvalues[2121]),0},
 {"sbgp-routerIdentifier","sbgp-routerIdentifier",
-	NID_sbgp_routerIdentifier,8,&(lvalues[2135]),0},
-{"textNotice","textNotice",NID_textNotice,8,&(lvalues[2143]),0},
+	NID_sbgp_routerIdentifier,8,&(lvalues[2129]),0},
+{"textNotice","textNotice",NID_textNotice,8,&(lvalues[2137]),0},
 {"ipsecEndSystem","IPSec End System",NID_ipsecEndSystem,8,
-	&(lvalues[2151]),0},
-{"ipsecTunnel","IPSec Tunnel",NID_ipsecTunnel,8,&(lvalues[2159]),0},
-{"ipsecUser","IPSec User",NID_ipsecUser,8,&(lvalues[2167]),0},
-{"DVCS","dvcs",NID_dvcs,8,&(lvalues[2175]),0},
+	&(lvalues[2145]),0},
+{"ipsecTunnel","IPSec Tunnel",NID_ipsecTunnel,8,&(lvalues[2153]),0},
+{"ipsecUser","IPSec User",NID_ipsecUser,8,&(lvalues[2161]),0},
+{"DVCS","dvcs",NID_dvcs,8,&(lvalues[2169]),0},
 {"id-it-caProtEncCert","id-it-caProtEncCert",NID_id_it_caProtEncCert,
-	8,&(lvalues[2183]),0},
+	8,&(lvalues[2177]),0},
 {"id-it-signKeyPairTypes","id-it-signKeyPairTypes",
-	NID_id_it_signKeyPairTypes,8,&(lvalues[2191]),0},
+	NID_id_it_signKeyPairTypes,8,&(lvalues[2185]),0},
 {"id-it-encKeyPairTypes","id-it-encKeyPairTypes",
-	NID_id_it_encKeyPairTypes,8,&(lvalues[2199]),0},
+	NID_id_it_encKeyPairTypes,8,&(lvalues[2193]),0},
 {"id-it-preferredSymmAlg","id-it-preferredSymmAlg",
-	NID_id_it_preferredSymmAlg,8,&(lvalues[2207]),0},
+	NID_id_it_preferredSymmAlg,8,&(lvalues[2201]),0},
 {"id-it-caKeyUpdateInfo","id-it-caKeyUpdateInfo",
-	NID_id_it_caKeyUpdateInfo,8,&(lvalues[2215]),0},
+	NID_id_it_caKeyUpdateInfo,8,&(lvalues[2209]),0},
 {"id-it-currentCRL","id-it-currentCRL",NID_id_it_currentCRL,8,
-	&(lvalues[2223]),0},
+	&(lvalues[2217]),0},
 {"id-it-unsupportedOIDs","id-it-unsupportedOIDs",
-	NID_id_it_unsupportedOIDs,8,&(lvalues[2231]),0},
+	NID_id_it_unsupportedOIDs,8,&(lvalues[2225]),0},
 {"id-it-subscriptionRequest","id-it-subscriptionRequest",
-	NID_id_it_subscriptionRequest,8,&(lvalues[2239]),0},
+	NID_id_it_subscriptionRequest,8,&(lvalues[2233]),0},
 {"id-it-subscriptionResponse","id-it-subscriptionResponse",
-	NID_id_it_subscriptionResponse,8,&(lvalues[2247]),0},
+	NID_id_it_subscriptionResponse,8,&(lvalues[2241]),0},
 {"id-it-keyPairParamReq","id-it-keyPairParamReq",
-	NID_id_it_keyPairParamReq,8,&(lvalues[2255]),0},
+	NID_id_it_keyPairParamReq,8,&(lvalues[2249]),0},
 {"id-it-keyPairParamRep","id-it-keyPairParamRep",
-	NID_id_it_keyPairParamRep,8,&(lvalues[2263]),0},
+	NID_id_it_keyPairParamRep,8,&(lvalues[2257]),0},
 {"id-it-revPassphrase","id-it-revPassphrase",NID_id_it_revPassphrase,
-	8,&(lvalues[2271]),0},
+	8,&(lvalues[2265]),0},
 {"id-it-implicitConfirm","id-it-implicitConfirm",
-	NID_id_it_implicitConfirm,8,&(lvalues[2279]),0},
+	NID_id_it_implicitConfirm,8,&(lvalues[2273]),0},
 {"id-it-confirmWaitTime","id-it-confirmWaitTime",
-	NID_id_it_confirmWaitTime,8,&(lvalues[2287]),0},
+	NID_id_it_confirmWaitTime,8,&(lvalues[2281]),0},
 {"id-it-origPKIMessage","id-it-origPKIMessage",
-	NID_id_it_origPKIMessage,8,&(lvalues[2295]),0},
-{"id-regCtrl","id-regCtrl",NID_id_regCtrl,8,&(lvalues[2303]),0},
-{"id-regInfo","id-regInfo",NID_id_regInfo,8,&(lvalues[2311]),0},
+	NID_id_it_origPKIMessage,8,&(lvalues[2289]),0},
+{"id-regCtrl","id-regCtrl",NID_id_regCtrl,8,&(lvalues[2297]),0},
+{"id-regInfo","id-regInfo",NID_id_regInfo,8,&(lvalues[2305]),0},
 {"id-regCtrl-regToken","id-regCtrl-regToken",NID_id_regCtrl_regToken,
-	9,&(lvalues[2319]),0},
+	9,&(lvalues[2313]),0},
 {"id-regCtrl-authenticator","id-regCtrl-authenticator",
-	NID_id_regCtrl_authenticator,9,&(lvalues[2328]),0},
+	NID_id_regCtrl_authenticator,9,&(lvalues[2322]),0},
 {"id-regCtrl-pkiPublicationInfo","id-regCtrl-pkiPublicationInfo",
-	NID_id_regCtrl_pkiPublicationInfo,9,&(lvalues[2337]),0},
+	NID_id_regCtrl_pkiPublicationInfo,9,&(lvalues[2331]),0},
 {"id-regCtrl-pkiArchiveOptions","id-regCtrl-pkiArchiveOptions",
-	NID_id_regCtrl_pkiArchiveOptions,9,&(lvalues[2346]),0},
+	NID_id_regCtrl_pkiArchiveOptions,9,&(lvalues[2340]),0},
 {"id-regCtrl-oldCertID","id-regCtrl-oldCertID",
-	NID_id_regCtrl_oldCertID,9,&(lvalues[2355]),0},
+	NID_id_regCtrl_oldCertID,9,&(lvalues[2349]),0},
 {"id-regCtrl-protocolEncrKey","id-regCtrl-protocolEncrKey",
-	NID_id_regCtrl_protocolEncrKey,9,&(lvalues[2364]),0},
+	NID_id_regCtrl_protocolEncrKey,9,&(lvalues[2358]),0},
 {"id-regInfo-utf8Pairs","id-regInfo-utf8Pairs",
-	NID_id_regInfo_utf8Pairs,9,&(lvalues[2373]),0},
+	NID_id_regInfo_utf8Pairs,9,&(lvalues[2367]),0},
 {"id-regInfo-certReq","id-regInfo-certReq",NID_id_regInfo_certReq,9,
-	&(lvalues[2382]),0},
-{"id-alg-des40","id-alg-des40",NID_id_alg_des40,8,&(lvalues[2391]),0},
+	&(lvalues[2376]),0},
+{"id-alg-des40","id-alg-des40",NID_id_alg_des40,8,&(lvalues[2385]),0},
 {"id-alg-noSignature","id-alg-noSignature",NID_id_alg_noSignature,8,
-	&(lvalues[2399]),0},
+	&(lvalues[2393]),0},
 {"id-alg-dh-sig-hmac-sha1","id-alg-dh-sig-hmac-sha1",
-	NID_id_alg_dh_sig_hmac_sha1,8,&(lvalues[2407]),0},
-{"id-alg-dh-pop","id-alg-dh-pop",NID_id_alg_dh_pop,8,&(lvalues[2415]),0},
+	NID_id_alg_dh_sig_hmac_sha1,8,&(lvalues[2401]),0},
+{"id-alg-dh-pop","id-alg-dh-pop",NID_id_alg_dh_pop,8,&(lvalues[2409]),0},
 {"id-cmc-statusInfo","id-cmc-statusInfo",NID_id_cmc_statusInfo,8,
-	&(lvalues[2423]),0},
+	&(lvalues[2417]),0},
 {"id-cmc-identification","id-cmc-identification",
-	NID_id_cmc_identification,8,&(lvalues[2431]),0},
+	NID_id_cmc_identification,8,&(lvalues[2425]),0},
 {"id-cmc-identityProof","id-cmc-identityProof",
-	NID_id_cmc_identityProof,8,&(lvalues[2439]),0},
+	NID_id_cmc_identityProof,8,&(lvalues[2433]),0},
 {"id-cmc-dataReturn","id-cmc-dataReturn",NID_id_cmc_dataReturn,8,
-	&(lvalues[2447]),0},
+	&(lvalues[2441]),0},
 {"id-cmc-transactionId","id-cmc-transactionId",
-	NID_id_cmc_transactionId,8,&(lvalues[2455]),0},
+	NID_id_cmc_transactionId,8,&(lvalues[2449]),0},
 {"id-cmc-senderNonce","id-cmc-senderNonce",NID_id_cmc_senderNonce,8,
-	&(lvalues[2463]),0},
+	&(lvalues[2457]),0},
 {"id-cmc-recipientNonce","id-cmc-recipientNonce",
-	NID_id_cmc_recipientNonce,8,&(lvalues[2471]),0},
+	NID_id_cmc_recipientNonce,8,&(lvalues[2465]),0},
 {"id-cmc-addExtensions","id-cmc-addExtensions",
-	NID_id_cmc_addExtensions,8,&(lvalues[2479]),0},
+	NID_id_cmc_addExtensions,8,&(lvalues[2473]),0},
 {"id-cmc-encryptedPOP","id-cmc-encryptedPOP",NID_id_cmc_encryptedPOP,
-	8,&(lvalues[2487]),0},
+	8,&(lvalues[2481]),0},
 {"id-cmc-decryptedPOP","id-cmc-decryptedPOP",NID_id_cmc_decryptedPOP,
-	8,&(lvalues[2495]),0},
+	8,&(lvalues[2489]),0},
 {"id-cmc-lraPOPWitness","id-cmc-lraPOPWitness",
-	NID_id_cmc_lraPOPWitness,8,&(lvalues[2503]),0},
+	NID_id_cmc_lraPOPWitness,8,&(lvalues[2497]),0},
 {"id-cmc-getCert","id-cmc-getCert",NID_id_cmc_getCert,8,
-	&(lvalues[2511]),0},
-{"id-cmc-getCRL","id-cmc-getCRL",NID_id_cmc_getCRL,8,&(lvalues[2519]),0},
+	&(lvalues[2505]),0},
+{"id-cmc-getCRL","id-cmc-getCRL",NID_id_cmc_getCRL,8,&(lvalues[2513]),0},
 {"id-cmc-revokeRequest","id-cmc-revokeRequest",
-	NID_id_cmc_revokeRequest,8,&(lvalues[2527]),0},
+	NID_id_cmc_revokeRequest,8,&(lvalues[2521]),0},
 {"id-cmc-regInfo","id-cmc-regInfo",NID_id_cmc_regInfo,8,
-	&(lvalues[2535]),0},
+	&(lvalues[2529]),0},
 {"id-cmc-responseInfo","id-cmc-responseInfo",NID_id_cmc_responseInfo,
-	8,&(lvalues[2543]),0},
+	8,&(lvalues[2537]),0},
 {"id-cmc-queryPending","id-cmc-queryPending",NID_id_cmc_queryPending,
-	8,&(lvalues[2551]),0},
+	8,&(lvalues[2545]),0},
 {"id-cmc-popLinkRandom","id-cmc-popLinkRandom",
-	NID_id_cmc_popLinkRandom,8,&(lvalues[2559]),0},
+	NID_id_cmc_popLinkRandom,8,&(lvalues[2553]),0},
 {"id-cmc-popLinkWitness","id-cmc-popLinkWitness",
-	NID_id_cmc_popLinkWitness,8,&(lvalues[2567]),0},
+	NID_id_cmc_popLinkWitness,8,&(lvalues[2561]),0},
 {"id-cmc-confirmCertAcceptance","id-cmc-confirmCertAcceptance",
-	NID_id_cmc_confirmCertAcceptance,8,&(lvalues[2575]),0},
+	NID_id_cmc_confirmCertAcceptance,8,&(lvalues[2569]),0},
 {"id-on-personalData","id-on-personalData",NID_id_on_personalData,8,
-	&(lvalues[2583]),0},
+	&(lvalues[2577]),0},
 {"id-pda-dateOfBirth","id-pda-dateOfBirth",NID_id_pda_dateOfBirth,8,
-	&(lvalues[2591]),0},
+	&(lvalues[2585]),0},
 {"id-pda-placeOfBirth","id-pda-placeOfBirth",NID_id_pda_placeOfBirth,
-	8,&(lvalues[2599]),0},
+	8,&(lvalues[2593]),0},
 {NULL,NULL,NID_undef,0,NULL,0},
-{"id-pda-gender","id-pda-gender",NID_id_pda_gender,8,&(lvalues[2607]),0},
+{"id-pda-gender","id-pda-gender",NID_id_pda_gender,8,&(lvalues[2601]),0},
 {"id-pda-countryOfCitizenship","id-pda-countryOfCitizenship",
-	NID_id_pda_countryOfCitizenship,8,&(lvalues[2615]),0},
+	NID_id_pda_countryOfCitizenship,8,&(lvalues[2609]),0},
 {"id-pda-countryOfResidence","id-pda-countryOfResidence",
-	NID_id_pda_countryOfResidence,8,&(lvalues[2623]),0},
+	NID_id_pda_countryOfResidence,8,&(lvalues[2617]),0},
 {"id-aca-authenticationInfo","id-aca-authenticationInfo",
-	NID_id_aca_authenticationInfo,8,&(lvalues[2631]),0},
+	NID_id_aca_authenticationInfo,8,&(lvalues[2625]),0},
 {"id-aca-accessIdentity","id-aca-accessIdentity",
-	NID_id_aca_accessIdentity,8,&(lvalues[2639]),0},
+	NID_id_aca_accessIdentity,8,&(lvalues[2633]),0},
 {"id-aca-chargingIdentity","id-aca-chargingIdentity",
-	NID_id_aca_chargingIdentity,8,&(lvalues[2647]),0},
-{"id-aca-group","id-aca-group",NID_id_aca_group,8,&(lvalues[2655]),0},
-{"id-aca-role","id-aca-role",NID_id_aca_role,8,&(lvalues[2663]),0},
+	NID_id_aca_chargingIdentity,8,&(lvalues[2641]),0},
+{"id-aca-group","id-aca-group",NID_id_aca_group,8,&(lvalues[2649]),0},
+{"id-aca-role","id-aca-role",NID_id_aca_role,8,&(lvalues[2657]),0},
 {"id-qcs-pkixQCSyntax-v1","id-qcs-pkixQCSyntax-v1",
-	NID_id_qcs_pkixQCSyntax_v1,8,&(lvalues[2671]),0},
-{"id-cct-crs","id-cct-crs",NID_id_cct_crs,8,&(lvalues[2679]),0},
+	NID_id_qcs_pkixQCSyntax_v1,8,&(lvalues[2665]),0},
+{"id-cct-crs","id-cct-crs",NID_id_cct_crs,8,&(lvalues[2673]),0},
 {"id-cct-PKIData","id-cct-PKIData",NID_id_cct_PKIData,8,
-	&(lvalues[2687]),0},
+	&(lvalues[2681]),0},
 {"id-cct-PKIResponse","id-cct-PKIResponse",NID_id_cct_PKIResponse,8,
-	&(lvalues[2695]),0},
+	&(lvalues[2689]),0},
 {"ad_timestamping","AD Time Stamping",NID_ad_timeStamping,8,
-	&(lvalues[2703]),0},
-{"AD_DVCS","ad dvcs",NID_ad_dvcs,8,&(lvalues[2711]),0},
+	&(lvalues[2697]),0},
+{"AD_DVCS","ad dvcs",NID_ad_dvcs,8,&(lvalues[2705]),0},
 {"basicOCSPResponse","Basic OCSP Response",NID_id_pkix_OCSP_basic,9,
-	&(lvalues[2719]),0},
-{"Nonce","OCSP Nonce",NID_id_pkix_OCSP_Nonce,9,&(lvalues[2728]),0},
-{"CrlID","OCSP CRL ID",NID_id_pkix_OCSP_CrlID,9,&(lvalues[2737]),0},
+	&(lvalues[2713]),0},
+{"Nonce","OCSP Nonce",NID_id_pkix_OCSP_Nonce,9,&(lvalues[2722]),0},
+{"CrlID","OCSP CRL ID",NID_id_pkix_OCSP_CrlID,9,&(lvalues[2731]),0},
 {"acceptableResponses","Acceptable OCSP Responses",
-	NID_id_pkix_OCSP_acceptableResponses,9,&(lvalues[2746]),0},
-{"noCheck","OCSP No Check",NID_id_pkix_OCSP_noCheck,9,&(lvalues[2755]),0},
+	NID_id_pkix_OCSP_acceptableResponses,9,&(lvalues[2740]),0},
+{"noCheck","OCSP No Check",NID_id_pkix_OCSP_noCheck,9,&(lvalues[2749]),0},
 {"archiveCutoff","OCSP Archive Cutoff",NID_id_pkix_OCSP_archiveCutoff,
-	9,&(lvalues[2764]),0},
+	9,&(lvalues[2758]),0},
 {"serviceLocator","OCSP Service Locator",
-	NID_id_pkix_OCSP_serviceLocator,9,&(lvalues[2773]),0},
+	NID_id_pkix_OCSP_serviceLocator,9,&(lvalues[2767]),0},
 {"extendedStatus","Extended OCSP Status",
-	NID_id_pkix_OCSP_extendedStatus,9,&(lvalues[2782]),0},
-{"valid","valid",NID_id_pkix_OCSP_valid,9,&(lvalues[2791]),0},
-{"path","path",NID_id_pkix_OCSP_path,9,&(lvalues[2800]),0},
+	NID_id_pkix_OCSP_extendedStatus,9,&(lvalues[2776]),0},
+{"valid","valid",NID_id_pkix_OCSP_valid,9,&(lvalues[2785]),0},
+{"path","path",NID_id_pkix_OCSP_path,9,&(lvalues[2794]),0},
 {"trustRoot","Trust Root",NID_id_pkix_OCSP_trustRoot,9,
-	&(lvalues[2809]),0},
-{"algorithm","algorithm",NID_algorithm,4,&(lvalues[2818]),0},
-{"rsaSignature","rsaSignature",NID_rsaSignature,5,&(lvalues[2822]),0},
+	&(lvalues[2803]),0},
+{"algorithm","algorithm",NID_algorithm,4,&(lvalues[2812]),0},
+{"rsaSignature","rsaSignature",NID_rsaSignature,5,&(lvalues[2816]),0},
 {"X500algorithms","directory services - algorithms",
-	NID_X500algorithms,2,&(lvalues[2827]),0},
-{"ORG","org",NID_org,1,&(lvalues[2829]),0},
-{"DOD","dod",NID_dod,2,&(lvalues[2830]),0},
-{"IANA","iana",NID_iana,3,&(lvalues[2832]),0},
-{"directory","Directory",NID_Directory,4,&(lvalues[2835]),0},
-{"mgmt","Management",NID_Management,4,&(lvalues[2839]),0},
-{"experimental","Experimental",NID_Experimental,4,&(lvalues[2843]),0},
-{"private","Private",NID_Private,4,&(lvalues[2847]),0},
-{"security","Security",NID_Security,4,&(lvalues[2851]),0},
-{"snmpv2","SNMPv2",NID_SNMPv2,4,&(lvalues[2855]),0},
-{"Mail","Mail",NID_Mail,4,&(lvalues[2859]),0},
-{"enterprises","Enterprises",NID_Enterprises,5,&(lvalues[2863]),0},
-{"dcobject","dcObject",NID_dcObject,9,&(lvalues[2868]),0},
-{"DC","domainComponent",NID_domainComponent,10,&(lvalues[2877]),0},
-{"domain","Domain",NID_Domain,10,&(lvalues[2887]),0},
+	NID_X500algorithms,2,&(lvalues[2821]),0},
+{"ORG","org",NID_org,1,&(lvalues[2823]),0},
+{"DOD","dod",NID_dod,2,&(lvalues[2824]),0},
+{"IANA","iana",NID_iana,3,&(lvalues[2826]),0},
+{"directory","Directory",NID_Directory,4,&(lvalues[2829]),0},
+{"mgmt","Management",NID_Management,4,&(lvalues[2833]),0},
+{"experimental","Experimental",NID_Experimental,4,&(lvalues[2837]),0},
+{"private","Private",NID_Private,4,&(lvalues[2841]),0},
+{"security","Security",NID_Security,4,&(lvalues[2845]),0},
+{"snmpv2","SNMPv2",NID_SNMPv2,4,&(lvalues[2849]),0},
+{"Mail","Mail",NID_Mail,4,&(lvalues[2853]),0},
+{"enterprises","Enterprises",NID_Enterprises,5,&(lvalues[2857]),0},
+{"dcobject","dcObject",NID_dcObject,9,&(lvalues[2862]),0},
+{"DC","domainComponent",NID_domainComponent,10,&(lvalues[2871]),0},
+{"domain","Domain",NID_Domain,10,&(lvalues[2881]),0},
 {"NULL","NULL",NID_joint_iso_ccitt,0,NULL,0},
 {"selected-attribute-types","Selected Attribute Types",
-	NID_selected_attribute_types,3,&(lvalues[2897]),0},
-{"clearance","clearance",NID_clearance,4,&(lvalues[2900]),0},
+	NID_selected_attribute_types,3,&(lvalues[2891]),0},
+{"clearance","clearance",NID_clearance,4,&(lvalues[2894]),0},
 {"RSA-MD4","md4WithRSAEncryption",NID_md4WithRSAEncryption,9,
-	&(lvalues[2904]),0},
-{"ac-proxying","ac-proxying",NID_ac_proxying,8,&(lvalues[2913]),0},
+	&(lvalues[2898]),0},
+{"ac-proxying","ac-proxying",NID_ac_proxying,8,&(lvalues[2907]),0},
 {"subjectInfoAccess","Subject Information Access",NID_sinfo_access,8,
-	&(lvalues[2921]),0},
+	&(lvalues[2915]),0},
 {"id-aca-encAttrs","id-aca-encAttrs",NID_id_aca_encAttrs,8,
-	&(lvalues[2929]),0},
-{"role","role",NID_role,3,&(lvalues[2937]),0},
+	&(lvalues[2923]),0},
+{"role","role",NID_role,3,&(lvalues[2931]),0},
 {"policyConstraints","X509v3 Policy Constraints",
-	NID_policy_constraints,3,&(lvalues[2940]),0},
+	NID_policy_constraints,3,&(lvalues[2934]),0},
 {"targetInformation","X509v3 AC Targeting",NID_target_information,3,
-	&(lvalues[2943]),0},
+	&(lvalues[2937]),0},
 {"noRevAvail","X509v3 No Revocation Available",NID_no_rev_avail,3,
-	&(lvalues[2946]),0},
+	&(lvalues[2940]),0},
 {"NULL","NULL",NID_ccitt,0,NULL,0},
-{"ansi-X9-62","ANSI X9.62",NID_ansi_X9_62,5,&(lvalues[2949]),0},
-{"prime-field","prime-field",NID_X9_62_prime_field,7,&(lvalues[2954]),0},
+{"ansi-X9-62","ANSI X9.62",NID_ansi_X9_62,5,&(lvalues[2943]),0},
+{"prime-field","prime-field",NID_X9_62_prime_field,7,&(lvalues[2948]),0},
 {"characteristic-two-field","characteristic-two-field",
-	NID_X9_62_characteristic_two_field,7,&(lvalues[2961]),0},
+	NID_X9_62_characteristic_two_field,7,&(lvalues[2955]),0},
 {"id-ecPublicKey","id-ecPublicKey",NID_X9_62_id_ecPublicKey,7,
-	&(lvalues[2968]),0},
-{"prime192v1","prime192v1",NID_X9_62_prime192v1,8,&(lvalues[2975]),0},
-{"prime192v2","prime192v2",NID_X9_62_prime192v2,8,&(lvalues[2983]),0},
-{"prime192v3","prime192v3",NID_X9_62_prime192v3,8,&(lvalues[2991]),0},
-{"prime239v1","prime239v1",NID_X9_62_prime239v1,8,&(lvalues[2999]),0},
-{"prime239v2","prime239v2",NID_X9_62_prime239v2,8,&(lvalues[3007]),0},
-{"prime239v3","prime239v3",NID_X9_62_prime239v3,8,&(lvalues[3015]),0},
-{"prime256v1","prime256v1",NID_X9_62_prime256v1,8,&(lvalues[3023]),0},
+	&(lvalues[2962]),0},
+{"prime192v1","prime192v1",NID_X9_62_prime192v1,8,&(lvalues[2969]),0},
+{"prime192v2","prime192v2",NID_X9_62_prime192v2,8,&(lvalues[2977]),0},
+{"prime192v3","prime192v3",NID_X9_62_prime192v3,8,&(lvalues[2985]),0},
+{"prime239v1","prime239v1",NID_X9_62_prime239v1,8,&(lvalues[2993]),0},
+{"prime239v2","prime239v2",NID_X9_62_prime239v2,8,&(lvalues[3001]),0},
+{"prime239v3","prime239v3",NID_X9_62_prime239v3,8,&(lvalues[3009]),0},
+{"prime256v1","prime256v1",NID_X9_62_prime256v1,8,&(lvalues[3017]),0},
 {"ecdsa-with-SHA1","ecdsa-with-SHA1",NID_ecdsa_with_SHA1,7,
-	&(lvalues[3031]),0},
-{"CSPName","Microsoft CSP Name",NID_ms_csp_name,9,&(lvalues[3038]),0},
-{"AES-128-ECB","aes-128-ecb",NID_aes_128_ecb,9,&(lvalues[3047]),0},
-{"AES-128-CBC","aes-128-cbc",NID_aes_128_cbc,9,&(lvalues[3056]),0},
-{"AES-128-OFB","aes-128-ofb",NID_aes_128_ofb128,9,&(lvalues[3065]),0},
-{"AES-128-CFB","aes-128-cfb",NID_aes_128_cfb128,9,&(lvalues[3074]),0},
-{"AES-192-ECB","aes-192-ecb",NID_aes_192_ecb,9,&(lvalues[3083]),0},
-{"AES-192-CBC","aes-192-cbc",NID_aes_192_cbc,9,&(lvalues[3092]),0},
-{"AES-192-OFB","aes-192-ofb",NID_aes_192_ofb128,9,&(lvalues[3101]),0},
-{"AES-192-CFB","aes-192-cfb",NID_aes_192_cfb128,9,&(lvalues[3110]),0},
-{"AES-256-ECB","aes-256-ecb",NID_aes_256_ecb,9,&(lvalues[3119]),0},
-{"AES-256-CBC","aes-256-cbc",NID_aes_256_cbc,9,&(lvalues[3128]),0},
-{"AES-256-OFB","aes-256-ofb",NID_aes_256_ofb128,9,&(lvalues[3137]),0},
-{"AES-256-CFB","aes-256-cfb",NID_aes_256_cfb128,9,&(lvalues[3146]),0},
+	&(lvalues[3025]),0},
+{"CSPName","Microsoft CSP Name",NID_ms_csp_name,9,&(lvalues[3032]),0},
+{"AES-128-ECB","aes-128-ecb",NID_aes_128_ecb,9,&(lvalues[3041]),0},
+{"AES-128-CBC","aes-128-cbc",NID_aes_128_cbc,9,&(lvalues[3050]),0},
+{"AES-128-OFB","aes-128-ofb",NID_aes_128_ofb128,9,&(lvalues[3059]),0},
+{"AES-128-CFB","aes-128-cfb",NID_aes_128_cfb128,9,&(lvalues[3068]),0},
+{"AES-192-ECB","aes-192-ecb",NID_aes_192_ecb,9,&(lvalues[3077]),0},
+{"AES-192-CBC","aes-192-cbc",NID_aes_192_cbc,9,&(lvalues[3086]),0},
+{"AES-192-OFB","aes-192-ofb",NID_aes_192_ofb128,9,&(lvalues[3095]),0},
+{"AES-192-CFB","aes-192-cfb",NID_aes_192_cfb128,9,&(lvalues[3104]),0},
+{"AES-256-ECB","aes-256-ecb",NID_aes_256_ecb,9,&(lvalues[3113]),0},
+{"AES-256-CBC","aes-256-cbc",NID_aes_256_cbc,9,&(lvalues[3122]),0},
+{"AES-256-OFB","aes-256-ofb",NID_aes_256_ofb128,9,&(lvalues[3131]),0},
+{"AES-256-CFB","aes-256-cfb",NID_aes_256_cfb128,9,&(lvalues[3140]),0},
 {"holdInstructionCode","Hold Instruction Code",
-	NID_hold_instruction_code,3,&(lvalues[3155]),0},
+	NID_hold_instruction_code,3,&(lvalues[3149]),0},
 {"holdInstructionNone","Hold Instruction None",
-	NID_hold_instruction_none,7,&(lvalues[3158]),0},
+	NID_hold_instruction_none,7,&(lvalues[3152]),0},
 {"holdInstructionCallIssuer","Hold Instruction Call Issuer",
-	NID_hold_instruction_call_issuer,7,&(lvalues[3165]),0},
+	NID_hold_instruction_call_issuer,7,&(lvalues[3159]),0},
 {"holdInstructionReject","Hold Instruction Reject",
-	NID_hold_instruction_reject,7,&(lvalues[3172]),0},
-{"data","data",NID_data,1,&(lvalues[3179]),0},
-{"pss","pss",NID_pss,3,&(lvalues[3180]),0},
-{"ucl","ucl",NID_ucl,7,&(lvalues[3183]),0},
-{"pilot","pilot",NID_pilot,8,&(lvalues[3190]),0},
+	NID_hold_instruction_reject,7,&(lvalues[3166]),0},
+{"data","data",NID_data,1,&(lvalues[3173]),0},
+{"pss","pss",NID_pss,3,&(lvalues[3174]),0},
+{"ucl","ucl",NID_ucl,7,&(lvalues[3177]),0},
+{"pilot","pilot",NID_pilot,8,&(lvalues[3184]),0},
 {"pilotAttributeType","pilotAttributeType",NID_pilotAttributeType,9,
-	&(lvalues[3198]),0},
+	&(lvalues[3192]),0},
 {"pilotAttributeSyntax","pilotAttributeSyntax",
-	NID_pilotAttributeSyntax,9,&(lvalues[3207]),0},
+	NID_pilotAttributeSyntax,9,&(lvalues[3201]),0},
 {"pilotObjectClass","pilotObjectClass",NID_pilotObjectClass,9,
-	&(lvalues[3216]),0},
-{"pilotGroups","pilotGroups",NID_pilotGroups,9,&(lvalues[3225]),0},
+	&(lvalues[3210]),0},
+{"pilotGroups","pilotGroups",NID_pilotGroups,9,&(lvalues[3219]),0},
 {"iA5StringSyntax","iA5StringSyntax",NID_iA5StringSyntax,10,
-	&(lvalues[3234]),0},
+	&(lvalues[3228]),0},
 {"caseIgnoreIA5StringSyntax","caseIgnoreIA5StringSyntax",
-	NID_caseIgnoreIA5StringSyntax,10,&(lvalues[3244]),0},
-{"pilotObject","pilotObject",NID_pilotObject,10,&(lvalues[3254]),0},
-{"pilotPerson","pilotPerson",NID_pilotPerson,10,&(lvalues[3264]),0},
-{"account","account",NID_account,10,&(lvalues[3274]),0},
-{"document","document",NID_document,10,&(lvalues[3284]),0},
-{"room","room",NID_room,10,&(lvalues[3294]),0},
+	NID_caseIgnoreIA5StringSyntax,10,&(lvalues[3238]),0},
+{"pilotObject","pilotObject",NID_pilotObject,10,&(lvalues[3248]),0},
+{"pilotPerson","pilotPerson",NID_pilotPerson,10,&(lvalues[3258]),0},
+{"account","account",NID_account,10,&(lvalues[3268]),0},
+{"document","document",NID_document,10,&(lvalues[3278]),0},
+{"room","room",NID_room,10,&(lvalues[3288]),0},
 {"documentSeries","documentSeries",NID_documentSeries,10,
-	&(lvalues[3304]),0},
+	&(lvalues[3298]),0},
 {"rFC822localPart","rFC822localPart",NID_rFC822localPart,10,
-	&(lvalues[3314]),0},
-{"dNSDomain","dNSDomain",NID_dNSDomain,10,&(lvalues[3324]),0},
+	&(lvalues[3308]),0},
+{"dNSDomain","dNSDomain",NID_dNSDomain,10,&(lvalues[3318]),0},
 {"domainRelatedObject","domainRelatedObject",NID_domainRelatedObject,
-	10,&(lvalues[3334]),0},
+	10,&(lvalues[3328]),0},
 {"friendlyCountry","friendlyCountry",NID_friendlyCountry,10,
-	&(lvalues[3344]),0},
+	&(lvalues[3338]),0},
 {"simpleSecurityObject","simpleSecurityObject",
-	NID_simpleSecurityObject,10,&(lvalues[3354]),0},
+	NID_simpleSecurityObject,10,&(lvalues[3348]),0},
 {"pilotOrganization","pilotOrganization",NID_pilotOrganization,10,
-	&(lvalues[3364]),0},
-{"pilotDSA","pilotDSA",NID_pilotDSA,10,&(lvalues[3374]),0},
+	&(lvalues[3358]),0},
+{"pilotDSA","pilotDSA",NID_pilotDSA,10,&(lvalues[3368]),0},
 {"qualityLabelledData","qualityLabelledData",NID_qualityLabelledData,
-	10,&(lvalues[3384]),0},
-{"UID","userId",NID_userId,10,&(lvalues[3394]),0},
+	10,&(lvalues[3378]),0},
+{"UID","userId",NID_userId,10,&(lvalues[3388]),0},
 {"textEncodedORAddress","textEncodedORAddress",
-	NID_textEncodedORAddress,10,&(lvalues[3404]),0},
-{"mail","rfc822Mailbox",NID_rfc822Mailbox,10,&(lvalues[3414]),0},
-{"info","info",NID_info,10,&(lvalues[3424]),0},
+	NID_textEncodedORAddress,10,&(lvalues[3398]),0},
+{"mail","rfc822Mailbox",NID_rfc822Mailbox,10,&(lvalues[3408]),0},
+{"info","info",NID_info,10,&(lvalues[3418]),0},
 {"favouriteDrink","favouriteDrink",NID_favouriteDrink,10,
-	&(lvalues[3434]),0},
-{"roomNumber","roomNumber",NID_roomNumber,10,&(lvalues[3444]),0},
-{"photo","photo",NID_photo,10,&(lvalues[3454]),0},
-{"userClass","userClass",NID_userClass,10,&(lvalues[3464]),0},
-{"host","host",NID_host,10,&(lvalues[3474]),0},
-{"manager","manager",NID_manager,10,&(lvalues[3484]),0},
+	&(lvalues[3428]),0},
+{"roomNumber","roomNumber",NID_roomNumber,10,&(lvalues[3438]),0},
+{"photo","photo",NID_photo,10,&(lvalues[3448]),0},
+{"userClass","userClass",NID_userClass,10,&(lvalues[3458]),0},
+{"host","host",NID_host,10,&(lvalues[3468]),0},
+{"manager","manager",NID_manager,10,&(lvalues[3478]),0},
 {"documentIdentifier","documentIdentifier",NID_documentIdentifier,10,
-	&(lvalues[3494]),0},
-{"documentTitle","documentTitle",NID_documentTitle,10,&(lvalues[3504]),0},
+	&(lvalues[3488]),0},
+{"documentTitle","documentTitle",NID_documentTitle,10,&(lvalues[3498]),0},
 {"documentVersion","documentVersion",NID_documentVersion,10,
-	&(lvalues[3514]),0},
+	&(lvalues[3508]),0},
 {"documentAuthor","documentAuthor",NID_documentAuthor,10,
-	&(lvalues[3524]),0},
+	&(lvalues[3518]),0},
 {"documentLocation","documentLocation",NID_documentLocation,10,
-	&(lvalues[3534]),0},
+	&(lvalues[3528]),0},
 {"homeTelephoneNumber","homeTelephoneNumber",NID_homeTelephoneNumber,
-	10,&(lvalues[3544]),0},
-{"secretary","secretary",NID_secretary,10,&(lvalues[3554]),0},
-{"otherMailbox","otherMailbox",NID_otherMailbox,10,&(lvalues[3564]),0},
+	10,&(lvalues[3538]),0},
+{"secretary","secretary",NID_secretary,10,&(lvalues[3548]),0},
+{"otherMailbox","otherMailbox",NID_otherMailbox,10,&(lvalues[3558]),0},
 {"lastModifiedTime","lastModifiedTime",NID_lastModifiedTime,10,
-	&(lvalues[3574]),0},
+	&(lvalues[3568]),0},
 {"lastModifiedBy","lastModifiedBy",NID_lastModifiedBy,10,
-	&(lvalues[3584]),0},
-{"aRecord","aRecord",NID_aRecord,10,&(lvalues[3594]),0},
+	&(lvalues[3578]),0},
+{"aRecord","aRecord",NID_aRecord,10,&(lvalues[3588]),0},
 {"pilotAttributeType27","pilotAttributeType27",
-	NID_pilotAttributeType27,10,&(lvalues[3604]),0},
-{"mXRecord","mXRecord",NID_mXRecord,10,&(lvalues[3614]),0},
-{"nSRecord","nSRecord",NID_nSRecord,10,&(lvalues[3624]),0},
-{"sOARecord","sOARecord",NID_sOARecord,10,&(lvalues[3634]),0},
-{"cNAMERecord","cNAMERecord",NID_cNAMERecord,10,&(lvalues[3644]),0},
+	NID_pilotAttributeType27,10,&(lvalues[3598]),0},
+{"mXRecord","mXRecord",NID_mXRecord,10,&(lvalues[3608]),0},
+{"nSRecord","nSRecord",NID_nSRecord,10,&(lvalues[3618]),0},
+{"sOARecord","sOARecord",NID_sOARecord,10,&(lvalues[3628]),0},
+{"cNAMERecord","cNAMERecord",NID_cNAMERecord,10,&(lvalues[3638]),0},
 {"associatedDomain","associatedDomain",NID_associatedDomain,10,
-	&(lvalues[3654]),0},
+	&(lvalues[3648]),0},
 {"associatedName","associatedName",NID_associatedName,10,
-	&(lvalues[3664]),0},
+	&(lvalues[3658]),0},
 {"homePostalAddress","homePostalAddress",NID_homePostalAddress,10,
-	&(lvalues[3674]),0},
-{"personalTitle","personalTitle",NID_personalTitle,10,&(lvalues[3684]),0},
+	&(lvalues[3668]),0},
+{"personalTitle","personalTitle",NID_personalTitle,10,&(lvalues[3678]),0},
 {"mobileTelephoneNumber","mobileTelephoneNumber",
-	NID_mobileTelephoneNumber,10,&(lvalues[3694]),0},
+	NID_mobileTelephoneNumber,10,&(lvalues[3688]),0},
 {"pagerTelephoneNumber","pagerTelephoneNumber",
-	NID_pagerTelephoneNumber,10,&(lvalues[3704]),0},
+	NID_pagerTelephoneNumber,10,&(lvalues[3698]),0},
 {"friendlyCountryName","friendlyCountryName",NID_friendlyCountryName,
-	10,&(lvalues[3714]),0},
+	10,&(lvalues[3708]),0},
 {"organizationalStatus","organizationalStatus",
-	NID_organizationalStatus,10,&(lvalues[3724]),0},
-{"janetMailbox","janetMailbox",NID_janetMailbox,10,&(lvalues[3734]),0},
+	NID_organizationalStatus,10,&(lvalues[3718]),0},
+{"janetMailbox","janetMailbox",NID_janetMailbox,10,&(lvalues[3728]),0},
 {"mailPreferenceOption","mailPreferenceOption",
-	NID_mailPreferenceOption,10,&(lvalues[3744]),0},
-{"buildingName","buildingName",NID_buildingName,10,&(lvalues[3754]),0},
-{"dSAQuality","dSAQuality",NID_dSAQuality,10,&(lvalues[3764]),0},
+	NID_mailPreferenceOption,10,&(lvalues[3738]),0},
+{"buildingName","buildingName",NID_buildingName,10,&(lvalues[3748]),0},
+{"dSAQuality","dSAQuality",NID_dSAQuality,10,&(lvalues[3758]),0},
 {"singleLevelQuality","singleLevelQuality",NID_singleLevelQuality,10,
-	&(lvalues[3774]),0},
+	&(lvalues[3768]),0},
 {"subtreeMinimumQuality","subtreeMinimumQuality",
-	NID_subtreeMinimumQuality,10,&(lvalues[3784]),0},
+	NID_subtreeMinimumQuality,10,&(lvalues[3778]),0},
 {"subtreeMaximumQuality","subtreeMaximumQuality",
-	NID_subtreeMaximumQuality,10,&(lvalues[3794]),0},
+	NID_subtreeMaximumQuality,10,&(lvalues[3788]),0},
 {"personalSignature","personalSignature",NID_personalSignature,10,
-	&(lvalues[3804]),0},
-{"dITRedirect","dITRedirect",NID_dITRedirect,10,&(lvalues[3814]),0},
-{"audio","audio",NID_audio,10,&(lvalues[3824]),0},
+	&(lvalues[3798]),0},
+{"dITRedirect","dITRedirect",NID_dITRedirect,10,&(lvalues[3808]),0},
+{"audio","audio",NID_audio,10,&(lvalues[3818]),0},
 {"documentPublisher","documentPublisher",NID_documentPublisher,10,
-	&(lvalues[3834]),0},
+	&(lvalues[3828]),0},
 {"x500UniqueIdentifier","x500UniqueIdentifier",
-	NID_x500UniqueIdentifier,3,&(lvalues[3844]),0},
-{"mime-mhs","MIME MHS",NID_mime_mhs,5,&(lvalues[3847]),0},
+	NID_x500UniqueIdentifier,3,&(lvalues[3838]),0},
+{"mime-mhs","MIME MHS",NID_mime_mhs,5,&(lvalues[3841]),0},
 {"mime-mhs-headings","mime-mhs-headings",NID_mime_mhs_headings,6,
-	&(lvalues[3852]),0},
+	&(lvalues[3846]),0},
 {"mime-mhs-bodies","mime-mhs-bodies",NID_mime_mhs_bodies,6,
-	&(lvalues[3858]),0},
+	&(lvalues[3852]),0},
 {"id-hex-partial-message","id-hex-partial-message",
-	NID_id_hex_partial_message,7,&(lvalues[3864]),0},
+	NID_id_hex_partial_message,7,&(lvalues[3858]),0},
 {"id-hex-multipart-message","id-hex-multipart-message",
-	NID_id_hex_multipart_message,7,&(lvalues[3871]),0},
+	NID_id_hex_multipart_message,7,&(lvalues[3865]),0},
 {"generationQualifier","generationQualifier",NID_generationQualifier,
-	3,&(lvalues[3878]),0},
-{"pseudonym","pseudonym",NID_pseudonym,3,&(lvalues[3881]),0},
+	3,&(lvalues[3872]),0},
+{"pseudonym","pseudonym",NID_pseudonym,3,&(lvalues[3875]),0},
 {NULL,NULL,NID_undef,0,NULL,0},
 {"id-set","Secure Electronic Transactions",NID_id_set,2,
-	&(lvalues[3884]),0},
-{"set-ctype","content types",NID_set_ctype,3,&(lvalues[3886]),0},
-{"set-msgExt","message extensions",NID_set_msgExt,3,&(lvalues[3889]),0},
-{"set-attr","set-attr",NID_set_attr,3,&(lvalues[3892]),0},
-{"set-policy","set-policy",NID_set_policy,3,&(lvalues[3895]),0},
+	&(lvalues[3878]),0},
+{"set-ctype","content types",NID_set_ctype,3,&(lvalues[3880]),0},
+{"set-msgExt","message extensions",NID_set_msgExt,3,&(lvalues[3883]),0},
+{"set-attr","set-attr",NID_set_attr,3,&(lvalues[3886]),0},
+{"set-policy","set-policy",NID_set_policy,3,&(lvalues[3889]),0},
 {"set-certExt","certificate extensions",NID_set_certExt,3,
-	&(lvalues[3898]),0},
-{"set-brand","set-brand",NID_set_brand,3,&(lvalues[3901]),0},
-{"setct-PANData","setct-PANData",NID_setct_PANData,4,&(lvalues[3904]),0},
+	&(lvalues[3892]),0},
+{"set-brand","set-brand",NID_set_brand,3,&(lvalues[3895]),0},
+{"setct-PANData","setct-PANData",NID_setct_PANData,4,&(lvalues[3898]),0},
 {"setct-PANToken","setct-PANToken",NID_setct_PANToken,4,
-	&(lvalues[3908]),0},
-{"setct-PANOnly","setct-PANOnly",NID_setct_PANOnly,4,&(lvalues[3912]),0},
-{"setct-OIData","setct-OIData",NID_setct_OIData,4,&(lvalues[3916]),0},
-{"setct-PI","setct-PI",NID_setct_PI,4,&(lvalues[3920]),0},
-{"setct-PIData","setct-PIData",NID_setct_PIData,4,&(lvalues[3924]),0},
+	&(lvalues[3902]),0},
+{"setct-PANOnly","setct-PANOnly",NID_setct_PANOnly,4,&(lvalues[3906]),0},
+{"setct-OIData","setct-OIData",NID_setct_OIData,4,&(lvalues[3910]),0},
+{"setct-PI","setct-PI",NID_setct_PI,4,&(lvalues[3914]),0},
+{"setct-PIData","setct-PIData",NID_setct_PIData,4,&(lvalues[3918]),0},
 {"setct-PIDataUnsigned","setct-PIDataUnsigned",
-	NID_setct_PIDataUnsigned,4,&(lvalues[3928]),0},
+	NID_setct_PIDataUnsigned,4,&(lvalues[3922]),0},
 {"setct-HODInput","setct-HODInput",NID_setct_HODInput,4,
-	&(lvalues[3932]),0},
+	&(lvalues[3926]),0},
 {"setct-AuthResBaggage","setct-AuthResBaggage",
-	NID_setct_AuthResBaggage,4,&(lvalues[3936]),0},
+	NID_setct_AuthResBaggage,4,&(lvalues[3930]),0},
 {"setct-AuthRevReqBaggage","setct-AuthRevReqBaggage",
-	NID_setct_AuthRevReqBaggage,4,&(lvalues[3940]),0},
+	NID_setct_AuthRevReqBaggage,4,&(lvalues[3934]),0},
 {"setct-AuthRevResBaggage","setct-AuthRevResBaggage",
-	NID_setct_AuthRevResBaggage,4,&(lvalues[3944]),0},
+	NID_setct_AuthRevResBaggage,4,&(lvalues[3938]),0},
 {"setct-CapTokenSeq","setct-CapTokenSeq",NID_setct_CapTokenSeq,4,
-	&(lvalues[3948]),0},
+	&(lvalues[3942]),0},
 {"setct-PInitResData","setct-PInitResData",NID_setct_PInitResData,4,
-	&(lvalues[3952]),0},
-{"setct-PI-TBS","setct-PI-TBS",NID_setct_PI_TBS,4,&(lvalues[3956]),0},
+	&(lvalues[3946]),0},
+{"setct-PI-TBS","setct-PI-TBS",NID_setct_PI_TBS,4,&(lvalues[3950]),0},
 {"setct-PResData","setct-PResData",NID_setct_PResData,4,
-	&(lvalues[3960]),0},
+	&(lvalues[3954]),0},
 {"setct-AuthReqTBS","setct-AuthReqTBS",NID_setct_AuthReqTBS,4,
-	&(lvalues[3964]),0},
+	&(lvalues[3958]),0},
 {"setct-AuthResTBS","setct-AuthResTBS",NID_setct_AuthResTBS,4,
-	&(lvalues[3968]),0},
+	&(lvalues[3962]),0},
 {"setct-AuthResTBSX","setct-AuthResTBSX",NID_setct_AuthResTBSX,4,
-	&(lvalues[3972]),0},
+	&(lvalues[3966]),0},
 {"setct-AuthTokenTBS","setct-AuthTokenTBS",NID_setct_AuthTokenTBS,4,
-	&(lvalues[3976]),0},
+	&(lvalues[3970]),0},
 {"setct-CapTokenData","setct-CapTokenData",NID_setct_CapTokenData,4,
-	&(lvalues[3980]),0},
+	&(lvalues[3974]),0},
 {"setct-CapTokenTBS","setct-CapTokenTBS",NID_setct_CapTokenTBS,4,
-	&(lvalues[3984]),0},
+	&(lvalues[3978]),0},
 {"setct-AcqCardCodeMsg","setct-AcqCardCodeMsg",
-	NID_setct_AcqCardCodeMsg,4,&(lvalues[3988]),0},
+	NID_setct_AcqCardCodeMsg,4,&(lvalues[3982]),0},
 {"setct-AuthRevReqTBS","setct-AuthRevReqTBS",NID_setct_AuthRevReqTBS,
-	4,&(lvalues[3992]),0},
+	4,&(lvalues[3986]),0},
 {"setct-AuthRevResData","setct-AuthRevResData",
-	NID_setct_AuthRevResData,4,&(lvalues[3996]),0},
+	NID_setct_AuthRevResData,4,&(lvalues[3990]),0},
 {"setct-AuthRevResTBS","setct-AuthRevResTBS",NID_setct_AuthRevResTBS,
-	4,&(lvalues[4000]),0},
+	4,&(lvalues[3994]),0},
 {"setct-CapReqTBS","setct-CapReqTBS",NID_setct_CapReqTBS,4,
-	&(lvalues[4004]),0},
+	&(lvalues[3998]),0},
 {"setct-CapReqTBSX","setct-CapReqTBSX",NID_setct_CapReqTBSX,4,
-	&(lvalues[4008]),0},
+	&(lvalues[4002]),0},
 {"setct-CapResData","setct-CapResData",NID_setct_CapResData,4,
-	&(lvalues[4012]),0},
+	&(lvalues[4006]),0},
 {"setct-CapRevReqTBS","setct-CapRevReqTBS",NID_setct_CapRevReqTBS,4,
-	&(lvalues[4016]),0},
+	&(lvalues[4010]),0},
 {"setct-CapRevReqTBSX","setct-CapRevReqTBSX",NID_setct_CapRevReqTBSX,
-	4,&(lvalues[4020]),0},
+	4,&(lvalues[4014]),0},
 {"setct-CapRevResData","setct-CapRevResData",NID_setct_CapRevResData,
-	4,&(lvalues[4024]),0},
+	4,&(lvalues[4018]),0},
 {"setct-CredReqTBS","setct-CredReqTBS",NID_setct_CredReqTBS,4,
-	&(lvalues[4028]),0},
+	&(lvalues[4022]),0},
 {"setct-CredReqTBSX","setct-CredReqTBSX",NID_setct_CredReqTBSX,4,
-	&(lvalues[4032]),0},
+	&(lvalues[4026]),0},
 {"setct-CredResData","setct-CredResData",NID_setct_CredResData,4,
-	&(lvalues[4036]),0},
+	&(lvalues[4030]),0},
 {"setct-CredRevReqTBS","setct-CredRevReqTBS",NID_setct_CredRevReqTBS,
-	4,&(lvalues[4040]),0},
+	4,&(lvalues[4034]),0},
 {"setct-CredRevReqTBSX","setct-CredRevReqTBSX",
-	NID_setct_CredRevReqTBSX,4,&(lvalues[4044]),0},
+	NID_setct_CredRevReqTBSX,4,&(lvalues[4038]),0},
 {"setct-CredRevResData","setct-CredRevResData",
-	NID_setct_CredRevResData,4,&(lvalues[4048]),0},
+	NID_setct_CredRevResData,4,&(lvalues[4042]),0},
 {"setct-PCertReqData","setct-PCertReqData",NID_setct_PCertReqData,4,
-	&(lvalues[4052]),0},
+	&(lvalues[4046]),0},
 {"setct-PCertResTBS","setct-PCertResTBS",NID_setct_PCertResTBS,4,
-	&(lvalues[4056]),0},
+	&(lvalues[4050]),0},
 {"setct-BatchAdminReqData","setct-BatchAdminReqData",
-	NID_setct_BatchAdminReqData,4,&(lvalues[4060]),0},
+	NID_setct_BatchAdminReqData,4,&(lvalues[4054]),0},
 {"setct-BatchAdminResData","setct-BatchAdminResData",
-	NID_setct_BatchAdminResData,4,&(lvalues[4064]),0},
+	NID_setct_BatchAdminResData,4,&(lvalues[4058]),0},
 {"setct-CardCInitResTBS","setct-CardCInitResTBS",
-	NID_setct_CardCInitResTBS,4,&(lvalues[4068]),0},
+	NID_setct_CardCInitResTBS,4,&(lvalues[4062]),0},
 {"setct-MeAqCInitResTBS","setct-MeAqCInitResTBS",
-	NID_setct_MeAqCInitResTBS,4,&(lvalues[4072]),0},
+	NID_setct_MeAqCInitResTBS,4,&(lvalues[4066]),0},
 {"setct-RegFormResTBS","setct-RegFormResTBS",NID_setct_RegFormResTBS,
-	4,&(lvalues[4076]),0},
+	4,&(lvalues[4070]),0},
 {"setct-CertReqData","setct-CertReqData",NID_setct_CertReqData,4,
-	&(lvalues[4080]),0},
+	&(lvalues[4074]),0},
 {"setct-CertReqTBS","setct-CertReqTBS",NID_setct_CertReqTBS,4,
-	&(lvalues[4084]),0},
+	&(lvalues[4078]),0},
 {"setct-CertResData","setct-CertResData",NID_setct_CertResData,4,
-	&(lvalues[4088]),0},
+	&(lvalues[4082]),0},
 {"setct-CertInqReqTBS","setct-CertInqReqTBS",NID_setct_CertInqReqTBS,
-	4,&(lvalues[4092]),0},
+	4,&(lvalues[4086]),0},
 {"setct-ErrorTBS","setct-ErrorTBS",NID_setct_ErrorTBS,4,
-	&(lvalues[4096]),0},
+	&(lvalues[4090]),0},
 {"setct-PIDualSignedTBE","setct-PIDualSignedTBE",
-	NID_setct_PIDualSignedTBE,4,&(lvalues[4100]),0},
+	NID_setct_PIDualSignedTBE,4,&(lvalues[4094]),0},
 {"setct-PIUnsignedTBE","setct-PIUnsignedTBE",NID_setct_PIUnsignedTBE,
-	4,&(lvalues[4104]),0},
+	4,&(lvalues[4098]),0},
 {"setct-AuthReqTBE","setct-AuthReqTBE",NID_setct_AuthReqTBE,4,
-	&(lvalues[4108]),0},
+	&(lvalues[4102]),0},
 {"setct-AuthResTBE","setct-AuthResTBE",NID_setct_AuthResTBE,4,
-	&(lvalues[4112]),0},
+	&(lvalues[4106]),0},
 {"setct-AuthResTBEX","setct-AuthResTBEX",NID_setct_AuthResTBEX,4,
-	&(lvalues[4116]),0},
+	&(lvalues[4110]),0},
 {"setct-AuthTokenTBE","setct-AuthTokenTBE",NID_setct_AuthTokenTBE,4,
-	&(lvalues[4120]),0},
+	&(lvalues[4114]),0},
 {"setct-CapTokenTBE","setct-CapTokenTBE",NID_setct_CapTokenTBE,4,
-	&(lvalues[4124]),0},
+	&(lvalues[4118]),0},
 {"setct-CapTokenTBEX","setct-CapTokenTBEX",NID_setct_CapTokenTBEX,4,
-	&(lvalues[4128]),0},
+	&(lvalues[4122]),0},
 {"setct-AcqCardCodeMsgTBE","setct-AcqCardCodeMsgTBE",
-	NID_setct_AcqCardCodeMsgTBE,4,&(lvalues[4132]),0},
+	NID_setct_AcqCardCodeMsgTBE,4,&(lvalues[4126]),0},
 {"setct-AuthRevReqTBE","setct-AuthRevReqTBE",NID_setct_AuthRevReqTBE,
-	4,&(lvalues[4136]),0},
+	4,&(lvalues[4130]),0},
 {"setct-AuthRevResTBE","setct-AuthRevResTBE",NID_setct_AuthRevResTBE,
-	4,&(lvalues[4140]),0},
+	4,&(lvalues[4134]),0},
 {"setct-AuthRevResTBEB","setct-AuthRevResTBEB",
-	NID_setct_AuthRevResTBEB,4,&(lvalues[4144]),0},
+	NID_setct_AuthRevResTBEB,4,&(lvalues[4138]),0},
 {"setct-CapReqTBE","setct-CapReqTBE",NID_setct_CapReqTBE,4,
-	&(lvalues[4148]),0},
+	&(lvalues[4142]),0},
 {"setct-CapReqTBEX","setct-CapReqTBEX",NID_setct_CapReqTBEX,4,
-	&(lvalues[4152]),0},
+	&(lvalues[4146]),0},
 {"setct-CapResTBE","setct-CapResTBE",NID_setct_CapResTBE,4,
-	&(lvalues[4156]),0},
+	&(lvalues[4150]),0},
 {"setct-CapRevReqTBE","setct-CapRevReqTBE",NID_setct_CapRevReqTBE,4,
-	&(lvalues[4160]),0},
+	&(lvalues[4154]),0},
 {"setct-CapRevReqTBEX","setct-CapRevReqTBEX",NID_setct_CapRevReqTBEX,
-	4,&(lvalues[4164]),0},
+	4,&(lvalues[4158]),0},
 {"setct-CapRevResTBE","setct-CapRevResTBE",NID_setct_CapRevResTBE,4,
-	&(lvalues[4168]),0},
+	&(lvalues[4162]),0},
 {"setct-CredReqTBE","setct-CredReqTBE",NID_setct_CredReqTBE,4,
-	&(lvalues[4172]),0},
+	&(lvalues[4166]),0},
 {"setct-CredReqTBEX","setct-CredReqTBEX",NID_setct_CredReqTBEX,4,
-	&(lvalues[4176]),0},
+	&(lvalues[4170]),0},
 {"setct-CredResTBE","setct-CredResTBE",NID_setct_CredResTBE,4,
-	&(lvalues[4180]),0},
+	&(lvalues[4174]),0},
 {"setct-CredRevReqTBE","setct-CredRevReqTBE",NID_setct_CredRevReqTBE,
-	4,&(lvalues[4184]),0},
+	4,&(lvalues[4178]),0},
 {"setct-CredRevReqTBEX","setct-CredRevReqTBEX",
-	NID_setct_CredRevReqTBEX,4,&(lvalues[4188]),0},
+	NID_setct_CredRevReqTBEX,4,&(lvalues[4182]),0},
 {"setct-CredRevResTBE","setct-CredRevResTBE",NID_setct_CredRevResTBE,
-	4,&(lvalues[4192]),0},
+	4,&(lvalues[4186]),0},
 {"setct-BatchAdminReqTBE","setct-BatchAdminReqTBE",
-	NID_setct_BatchAdminReqTBE,4,&(lvalues[4196]),0},
+	NID_setct_BatchAdminReqTBE,4,&(lvalues[4190]),0},
 {"setct-BatchAdminResTBE","setct-BatchAdminResTBE",
-	NID_setct_BatchAdminResTBE,4,&(lvalues[4200]),0},
+	NID_setct_BatchAdminResTBE,4,&(lvalues[4194]),0},
 {"setct-RegFormReqTBE","setct-RegFormReqTBE",NID_setct_RegFormReqTBE,
-	4,&(lvalues[4204]),0},
+	4,&(lvalues[4198]),0},
 {"setct-CertReqTBE","setct-CertReqTBE",NID_setct_CertReqTBE,4,
-	&(lvalues[4208]),0},
+	&(lvalues[4202]),0},
 {"setct-CertReqTBEX","setct-CertReqTBEX",NID_setct_CertReqTBEX,4,
-	&(lvalues[4212]),0},
+	&(lvalues[4206]),0},
 {"setct-CertResTBE","setct-CertResTBE",NID_setct_CertResTBE,4,
-	&(lvalues[4216]),0},
+	&(lvalues[4210]),0},
 {"setct-CRLNotificationTBS","setct-CRLNotificationTBS",
-	NID_setct_CRLNotificationTBS,4,&(lvalues[4220]),0},
+	NID_setct_CRLNotificationTBS,4,&(lvalues[4214]),0},
 {"setct-CRLNotificationResTBS","setct-CRLNotificationResTBS",
-	NID_setct_CRLNotificationResTBS,4,&(lvalues[4224]),0},
+	NID_setct_CRLNotificationResTBS,4,&(lvalues[4218]),0},
 {"setct-BCIDistributionTBS","setct-BCIDistributionTBS",
-	NID_setct_BCIDistributionTBS,4,&(lvalues[4228]),0},
+	NID_setct_BCIDistributionTBS,4,&(lvalues[4222]),0},
 {"setext-genCrypt","generic cryptogram",NID_setext_genCrypt,4,
-	&(lvalues[4232]),0},
+	&(lvalues[4226]),0},
 {"setext-miAuth","merchant initiated auth",NID_setext_miAuth,4,
-	&(lvalues[4236]),0},
+	&(lvalues[4230]),0},
 {"setext-pinSecure","setext-pinSecure",NID_setext_pinSecure,4,
-	&(lvalues[4240]),0},
-{"setext-pinAny","setext-pinAny",NID_setext_pinAny,4,&(lvalues[4244]),0},
-{"setext-track2","setext-track2",NID_setext_track2,4,&(lvalues[4248]),0},
+	&(lvalues[4234]),0},
+{"setext-pinAny","setext-pinAny",NID_setext_pinAny,4,&(lvalues[4238]),0},
+{"setext-track2","setext-track2",NID_setext_track2,4,&(lvalues[4242]),0},
 {"setext-cv","additional verification",NID_setext_cv,4,
-	&(lvalues[4252]),0},
+	&(lvalues[4246]),0},
 {"set-policy-root","set-policy-root",NID_set_policy_root,4,
-	&(lvalues[4256]),0},
+	&(lvalues[4250]),0},
 {"setCext-hashedRoot","setCext-hashedRoot",NID_setCext_hashedRoot,4,
-	&(lvalues[4260]),0},
+	&(lvalues[4254]),0},
 {"setCext-certType","setCext-certType",NID_setCext_certType,4,
-	&(lvalues[4264]),0},
+	&(lvalues[4258]),0},
 {"setCext-merchData","setCext-merchData",NID_setCext_merchData,4,
-	&(lvalues[4268]),0},
+	&(lvalues[4262]),0},
 {"setCext-cCertRequired","setCext-cCertRequired",
-	NID_setCext_cCertRequired,4,&(lvalues[4272]),0},
+	NID_setCext_cCertRequired,4,&(lvalues[4266]),0},
 {"setCext-tunneling","setCext-tunneling",NID_setCext_tunneling,4,
-	&(lvalues[4276]),0},
+	&(lvalues[4270]),0},
 {"setCext-setExt","setCext-setExt",NID_setCext_setExt,4,
-	&(lvalues[4280]),0},
+	&(lvalues[4274]),0},
 {"setCext-setQualf","setCext-setQualf",NID_setCext_setQualf,4,
-	&(lvalues[4284]),0},
+	&(lvalues[4278]),0},
 {"setCext-PGWYcapabilities","setCext-PGWYcapabilities",
-	NID_setCext_PGWYcapabilities,4,&(lvalues[4288]),0},
+	NID_setCext_PGWYcapabilities,4,&(lvalues[4282]),0},
 {"setCext-TokenIdentifier","setCext-TokenIdentifier",
-	NID_setCext_TokenIdentifier,4,&(lvalues[4292]),0},
+	NID_setCext_TokenIdentifier,4,&(lvalues[4286]),0},
 {"setCext-Track2Data","setCext-Track2Data",NID_setCext_Track2Data,4,
-	&(lvalues[4296]),0},
+	&(lvalues[4290]),0},
 {"setCext-TokenType","setCext-TokenType",NID_setCext_TokenType,4,
-	&(lvalues[4300]),0},
+	&(lvalues[4294]),0},
 {"setCext-IssuerCapabilities","setCext-IssuerCapabilities",
-	NID_setCext_IssuerCapabilities,4,&(lvalues[4304]),0},
-{"setAttr-Cert","setAttr-Cert",NID_setAttr_Cert,4,&(lvalues[4308]),0},
+	NID_setCext_IssuerCapabilities,4,&(lvalues[4298]),0},
+{"setAttr-Cert","setAttr-Cert",NID_setAttr_Cert,4,&(lvalues[4302]),0},
 {"setAttr-PGWYcap","payment gateway capabilities",NID_setAttr_PGWYcap,
-	4,&(lvalues[4312]),0},
+	4,&(lvalues[4306]),0},
 {"setAttr-TokenType","setAttr-TokenType",NID_setAttr_TokenType,4,
-	&(lvalues[4316]),0},
+	&(lvalues[4310]),0},
 {"setAttr-IssCap","issuer capabilities",NID_setAttr_IssCap,4,
-	&(lvalues[4320]),0},
+	&(lvalues[4314]),0},
 {"set-rootKeyThumb","set-rootKeyThumb",NID_set_rootKeyThumb,5,
-	&(lvalues[4324]),0},
-{"set-addPolicy","set-addPolicy",NID_set_addPolicy,5,&(lvalues[4329]),0},
+	&(lvalues[4318]),0},
+{"set-addPolicy","set-addPolicy",NID_set_addPolicy,5,&(lvalues[4323]),0},
 {"setAttr-Token-EMV","setAttr-Token-EMV",NID_setAttr_Token_EMV,5,
-	&(lvalues[4334]),0},
+	&(lvalues[4328]),0},
 {"setAttr-Token-B0Prime","setAttr-Token-B0Prime",
-	NID_setAttr_Token_B0Prime,5,&(lvalues[4339]),0},
+	NID_setAttr_Token_B0Prime,5,&(lvalues[4333]),0},
 {"setAttr-IssCap-CVM","setAttr-IssCap-CVM",NID_setAttr_IssCap_CVM,5,
-	&(lvalues[4344]),0},
+	&(lvalues[4338]),0},
 {"setAttr-IssCap-T2","setAttr-IssCap-T2",NID_setAttr_IssCap_T2,5,
-	&(lvalues[4349]),0},
+	&(lvalues[4343]),0},
 {"setAttr-IssCap-Sig","setAttr-IssCap-Sig",NID_setAttr_IssCap_Sig,5,
-	&(lvalues[4354]),0},
+	&(lvalues[4348]),0},
 {"setAttr-GenCryptgrm","generate cryptogram",NID_setAttr_GenCryptgrm,
-	6,&(lvalues[4359]),0},
+	6,&(lvalues[4353]),0},
 {"setAttr-T2Enc","encrypted track 2",NID_setAttr_T2Enc,6,
-	&(lvalues[4365]),0},
+	&(lvalues[4359]),0},
 {"setAttr-T2cleartxt","cleartext track 2",NID_setAttr_T2cleartxt,6,
-	&(lvalues[4371]),0},
+	&(lvalues[4365]),0},
 {"setAttr-TokICCsig","ICC or token signature",NID_setAttr_TokICCsig,6,
-	&(lvalues[4377]),0},
+	&(lvalues[4371]),0},
 {"setAttr-SecDevSig","secure device signature",NID_setAttr_SecDevSig,
-	6,&(lvalues[4383]),0},
+	6,&(lvalues[4377]),0},
 {"set-brand-IATA-ATA","set-brand-IATA-ATA",NID_set_brand_IATA_ATA,4,
-	&(lvalues[4389]),0},
+	&(lvalues[4383]),0},
 {"set-brand-Diners","set-brand-Diners",NID_set_brand_Diners,4,
-	&(lvalues[4393]),0},
+	&(lvalues[4387]),0},
 {"set-brand-AmericanExpress","set-brand-AmericanExpress",
-	NID_set_brand_AmericanExpress,4,&(lvalues[4397]),0},
-{"set-brand-JCB","set-brand-JCB",NID_set_brand_JCB,4,&(lvalues[4401]),0},
+	NID_set_brand_AmericanExpress,4,&(lvalues[4391]),0},
+{"set-brand-JCB","set-brand-JCB",NID_set_brand_JCB,4,&(lvalues[4395]),0},
 {"set-brand-Visa","set-brand-Visa",NID_set_brand_Visa,4,
-	&(lvalues[4405]),0},
+	&(lvalues[4399]),0},
 {"set-brand-MasterCard","set-brand-MasterCard",
-	NID_set_brand_MasterCard,4,&(lvalues[4409]),0},
+	NID_set_brand_MasterCard,4,&(lvalues[4403]),0},
 {"set-brand-Novus","set-brand-Novus",NID_set_brand_Novus,5,
-	&(lvalues[4413]),0},
-{"DES-CDMF","des-cdmf",NID_des_cdmf,8,&(lvalues[4418]),0},
+	&(lvalues[4407]),0},
+{"DES-CDMF","des-cdmf",NID_des_cdmf,8,&(lvalues[4412]),0},
 {"rsaOAEPEncryptionSET","rsaOAEPEncryptionSET",
-	NID_rsaOAEPEncryptionSET,9,&(lvalues[4426]),0},
+	NID_rsaOAEPEncryptionSET,9,&(lvalues[4420]),0},
 {"ITU-T","itu-t",NID_itu_t,0,NULL,0},
 {"JOINT-ISO-ITU-T","joint-iso-itu-t",NID_joint_iso_itu_t,0,NULL,0},
 {"international-organizations","International Organizations",
-	NID_international_organizations,1,&(lvalues[4435]),0},
+	NID_international_organizations,1,&(lvalues[4429]),0},
 {"msSmartcardLogin","Microsoft Smartcardlogin",NID_ms_smartcard_login,
-	10,&(lvalues[4436]),0},
+	10,&(lvalues[4430]),0},
 {"msUPN","Microsoft Universal Principal Name",NID_ms_upn,10,
-	&(lvalues[4446]),0},
+	&(lvalues[4440]),0},
 {"AES-128-CFB1","aes-128-cfb1",NID_aes_128_cfb1,0,NULL,0},
 {"AES-192-CFB1","aes-192-cfb1",NID_aes_192_cfb1,0,NULL,0},
 {"AES-256-CFB1","aes-256-cfb1",NID_aes_256_cfb1,0,NULL,0},
@@ -1994,138 +1993,138 @@
 {"DES-CFB8","des-cfb8",NID_des_cfb8,0,NULL,0},
 {"DES-EDE3-CFB1","des-ede3-cfb1",NID_des_ede3_cfb1,0,NULL,0},
 {"DES-EDE3-CFB8","des-ede3-cfb8",NID_des_ede3_cfb8,0,NULL,0},
-{"street","streetAddress",NID_streetAddress,3,&(lvalues[4456]),0},
-{"postalCode","postalCode",NID_postalCode,3,&(lvalues[4459]),0},
-{"id-ppl","id-ppl",NID_id_ppl,7,&(lvalues[4462]),0},
+{"street","streetAddress",NID_streetAddress,3,&(lvalues[4450]),0},
+{"postalCode","postalCode",NID_postalCode,3,&(lvalues[4453]),0},
+{"id-ppl","id-ppl",NID_id_ppl,7,&(lvalues[4456]),0},
 {"proxyCertInfo","Proxy Certificate Information",NID_proxyCertInfo,8,
-	&(lvalues[4469]),0},
+	&(lvalues[4463]),0},
 {"id-ppl-anyLanguage","Any language",NID_id_ppl_anyLanguage,8,
-	&(lvalues[4477]),0},
+	&(lvalues[4471]),0},
 {"id-ppl-inheritAll","Inherit all",NID_id_ppl_inheritAll,8,
-	&(lvalues[4485]),0},
+	&(lvalues[4479]),0},
 {"nameConstraints","X509v3 Name Constraints",NID_name_constraints,3,
-	&(lvalues[4493]),0},
-{"id-ppl-independent","Independent",NID_Independent,8,&(lvalues[4496]),0},
+	&(lvalues[4487]),0},
+{"id-ppl-independent","Independent",NID_Independent,8,&(lvalues[4490]),0},
 {"RSA-SHA256","sha256WithRSAEncryption",NID_sha256WithRSAEncryption,9,
-	&(lvalues[4504]),0},
+	&(lvalues[4498]),0},
 {"RSA-SHA384","sha384WithRSAEncryption",NID_sha384WithRSAEncryption,9,
-	&(lvalues[4513]),0},
+	&(lvalues[4507]),0},
 {"RSA-SHA512","sha512WithRSAEncryption",NID_sha512WithRSAEncryption,9,
-	&(lvalues[4522]),0},
+	&(lvalues[4516]),0},
 {"RSA-SHA224","sha224WithRSAEncryption",NID_sha224WithRSAEncryption,9,
-	&(lvalues[4531]),0},
-{"SHA256","sha256",NID_sha256,9,&(lvalues[4540]),0},
-{"SHA384","sha384",NID_sha384,9,&(lvalues[4549]),0},
-{"SHA512","sha512",NID_sha512,9,&(lvalues[4558]),0},
-{"SHA224","sha224",NID_sha224,9,&(lvalues[4567]),0},
+	&(lvalues[4525]),0},
+{"SHA256","sha256",NID_sha256,9,&(lvalues[4534]),0},
+{"SHA384","sha384",NID_sha384,9,&(lvalues[4543]),0},
+{"SHA512","sha512",NID_sha512,9,&(lvalues[4552]),0},
+{"SHA224","sha224",NID_sha224,9,&(lvalues[4561]),0},
 {"identified-organization","identified-organization",
-	NID_identified_organization,1,&(lvalues[4576]),0},
-{"certicom-arc","certicom-arc",NID_certicom_arc,3,&(lvalues[4577]),0},
-{"wap","wap",NID_wap,2,&(lvalues[4580]),0},
-{"wap-wsg","wap-wsg",NID_wap_wsg,3,&(lvalues[4582]),0},
+	NID_identified_organization,1,&(lvalues[4570]),0},
+{"certicom-arc","certicom-arc",NID_certicom_arc,3,&(lvalues[4571]),0},
+{"wap","wap",NID_wap,2,&(lvalues[4574]),0},
+{"wap-wsg","wap-wsg",NID_wap_wsg,3,&(lvalues[4576]),0},
 {"id-characteristic-two-basis","id-characteristic-two-basis",
-	NID_X9_62_id_characteristic_two_basis,8,&(lvalues[4585]),0},
-{"onBasis","onBasis",NID_X9_62_onBasis,9,&(lvalues[4593]),0},
-{"tpBasis","tpBasis",NID_X9_62_tpBasis,9,&(lvalues[4602]),0},
-{"ppBasis","ppBasis",NID_X9_62_ppBasis,9,&(lvalues[4611]),0},
-{"c2pnb163v1","c2pnb163v1",NID_X9_62_c2pnb163v1,8,&(lvalues[4620]),0},
-{"c2pnb163v2","c2pnb163v2",NID_X9_62_c2pnb163v2,8,&(lvalues[4628]),0},
-{"c2pnb163v3","c2pnb163v3",NID_X9_62_c2pnb163v3,8,&(lvalues[4636]),0},
-{"c2pnb176v1","c2pnb176v1",NID_X9_62_c2pnb176v1,8,&(lvalues[4644]),0},
-{"c2tnb191v1","c2tnb191v1",NID_X9_62_c2tnb191v1,8,&(lvalues[4652]),0},
-{"c2tnb191v2","c2tnb191v2",NID_X9_62_c2tnb191v2,8,&(lvalues[4660]),0},
-{"c2tnb191v3","c2tnb191v3",NID_X9_62_c2tnb191v3,8,&(lvalues[4668]),0},
-{"c2onb191v4","c2onb191v4",NID_X9_62_c2onb191v4,8,&(lvalues[4676]),0},
-{"c2onb191v5","c2onb191v5",NID_X9_62_c2onb191v5,8,&(lvalues[4684]),0},
-{"c2pnb208w1","c2pnb208w1",NID_X9_62_c2pnb208w1,8,&(lvalues[4692]),0},
-{"c2tnb239v1","c2tnb239v1",NID_X9_62_c2tnb239v1,8,&(lvalues[4700]),0},
-{"c2tnb239v2","c2tnb239v2",NID_X9_62_c2tnb239v2,8,&(lvalues[4708]),0},
-{"c2tnb239v3","c2tnb239v3",NID_X9_62_c2tnb239v3,8,&(lvalues[4716]),0},
-{"c2onb239v4","c2onb239v4",NID_X9_62_c2onb239v4,8,&(lvalues[4724]),0},
-{"c2onb239v5","c2onb239v5",NID_X9_62_c2onb239v5,8,&(lvalues[4732]),0},
-{"c2pnb272w1","c2pnb272w1",NID_X9_62_c2pnb272w1,8,&(lvalues[4740]),0},
-{"c2pnb304w1","c2pnb304w1",NID_X9_62_c2pnb304w1,8,&(lvalues[4748]),0},
-{"c2tnb359v1","c2tnb359v1",NID_X9_62_c2tnb359v1,8,&(lvalues[4756]),0},
-{"c2pnb368w1","c2pnb368w1",NID_X9_62_c2pnb368w1,8,&(lvalues[4764]),0},
-{"c2tnb431r1","c2tnb431r1",NID_X9_62_c2tnb431r1,8,&(lvalues[4772]),0},
-{"secp112r1","secp112r1",NID_secp112r1,5,&(lvalues[4780]),0},
-{"secp112r2","secp112r2",NID_secp112r2,5,&(lvalues[4785]),0},
-{"secp128r1","secp128r1",NID_secp128r1,5,&(lvalues[4790]),0},
-{"secp128r2","secp128r2",NID_secp128r2,5,&(lvalues[4795]),0},
-{"secp160k1","secp160k1",NID_secp160k1,5,&(lvalues[4800]),0},
-{"secp160r1","secp160r1",NID_secp160r1,5,&(lvalues[4805]),0},
-{"secp160r2","secp160r2",NID_secp160r2,5,&(lvalues[4810]),0},
-{"secp192k1","secp192k1",NID_secp192k1,5,&(lvalues[4815]),0},
-{"secp224k1","secp224k1",NID_secp224k1,5,&(lvalues[4820]),0},
-{"secp224r1","secp224r1",NID_secp224r1,5,&(lvalues[4825]),0},
-{"secp256k1","secp256k1",NID_secp256k1,5,&(lvalues[4830]),0},
-{"secp384r1","secp384r1",NID_secp384r1,5,&(lvalues[4835]),0},
-{"secp521r1","secp521r1",NID_secp521r1,5,&(lvalues[4840]),0},
-{"sect113r1","sect113r1",NID_sect113r1,5,&(lvalues[4845]),0},
-{"sect113r2","sect113r2",NID_sect113r2,5,&(lvalues[4850]),0},
-{"sect131r1","sect131r1",NID_sect131r1,5,&(lvalues[4855]),0},
-{"sect131r2","sect131r2",NID_sect131r2,5,&(lvalues[4860]),0},
-{"sect163k1","sect163k1",NID_sect163k1,5,&(lvalues[4865]),0},
-{"sect163r1","sect163r1",NID_sect163r1,5,&(lvalues[4870]),0},
-{"sect163r2","sect163r2",NID_sect163r2,5,&(lvalues[4875]),0},
-{"sect193r1","sect193r1",NID_sect193r1,5,&(lvalues[4880]),0},
-{"sect193r2","sect193r2",NID_sect193r2,5,&(lvalues[4885]),0},
-{"sect233k1","sect233k1",NID_sect233k1,5,&(lvalues[4890]),0},
-{"sect233r1","sect233r1",NID_sect233r1,5,&(lvalues[4895]),0},
-{"sect239k1","sect239k1",NID_sect239k1,5,&(lvalues[4900]),0},
-{"sect283k1","sect283k1",NID_sect283k1,5,&(lvalues[4905]),0},
-{"sect283r1","sect283r1",NID_sect283r1,5,&(lvalues[4910]),0},
-{"sect409k1","sect409k1",NID_sect409k1,5,&(lvalues[4915]),0},
-{"sect409r1","sect409r1",NID_sect409r1,5,&(lvalues[4920]),0},
-{"sect571k1","sect571k1",NID_sect571k1,5,&(lvalues[4925]),0},
-{"sect571r1","sect571r1",NID_sect571r1,5,&(lvalues[4930]),0},
+	NID_X9_62_id_characteristic_two_basis,8,&(lvalues[4579]),0},
+{"onBasis","onBasis",NID_X9_62_onBasis,9,&(lvalues[4587]),0},
+{"tpBasis","tpBasis",NID_X9_62_tpBasis,9,&(lvalues[4596]),0},
+{"ppBasis","ppBasis",NID_X9_62_ppBasis,9,&(lvalues[4605]),0},
+{"c2pnb163v1","c2pnb163v1",NID_X9_62_c2pnb163v1,8,&(lvalues[4614]),0},
+{"c2pnb163v2","c2pnb163v2",NID_X9_62_c2pnb163v2,8,&(lvalues[4622]),0},
+{"c2pnb163v3","c2pnb163v3",NID_X9_62_c2pnb163v3,8,&(lvalues[4630]),0},
+{"c2pnb176v1","c2pnb176v1",NID_X9_62_c2pnb176v1,8,&(lvalues[4638]),0},
+{"c2tnb191v1","c2tnb191v1",NID_X9_62_c2tnb191v1,8,&(lvalues[4646]),0},
+{"c2tnb191v2","c2tnb191v2",NID_X9_62_c2tnb191v2,8,&(lvalues[4654]),0},
+{"c2tnb191v3","c2tnb191v3",NID_X9_62_c2tnb191v3,8,&(lvalues[4662]),0},
+{"c2onb191v4","c2onb191v4",NID_X9_62_c2onb191v4,8,&(lvalues[4670]),0},
+{"c2onb191v5","c2onb191v5",NID_X9_62_c2onb191v5,8,&(lvalues[4678]),0},
+{"c2pnb208w1","c2pnb208w1",NID_X9_62_c2pnb208w1,8,&(lvalues[4686]),0},
+{"c2tnb239v1","c2tnb239v1",NID_X9_62_c2tnb239v1,8,&(lvalues[4694]),0},
+{"c2tnb239v2","c2tnb239v2",NID_X9_62_c2tnb239v2,8,&(lvalues[4702]),0},
+{"c2tnb239v3","c2tnb239v3",NID_X9_62_c2tnb239v3,8,&(lvalues[4710]),0},
+{"c2onb239v4","c2onb239v4",NID_X9_62_c2onb239v4,8,&(lvalues[4718]),0},
+{"c2onb239v5","c2onb239v5",NID_X9_62_c2onb239v5,8,&(lvalues[4726]),0},
+{"c2pnb272w1","c2pnb272w1",NID_X9_62_c2pnb272w1,8,&(lvalues[4734]),0},
+{"c2pnb304w1","c2pnb304w1",NID_X9_62_c2pnb304w1,8,&(lvalues[4742]),0},
+{"c2tnb359v1","c2tnb359v1",NID_X9_62_c2tnb359v1,8,&(lvalues[4750]),0},
+{"c2pnb368w1","c2pnb368w1",NID_X9_62_c2pnb368w1,8,&(lvalues[4758]),0},
+{"c2tnb431r1","c2tnb431r1",NID_X9_62_c2tnb431r1,8,&(lvalues[4766]),0},
+{"secp112r1","secp112r1",NID_secp112r1,5,&(lvalues[4774]),0},
+{"secp112r2","secp112r2",NID_secp112r2,5,&(lvalues[4779]),0},
+{"secp128r1","secp128r1",NID_secp128r1,5,&(lvalues[4784]),0},
+{"secp128r2","secp128r2",NID_secp128r2,5,&(lvalues[4789]),0},
+{"secp160k1","secp160k1",NID_secp160k1,5,&(lvalues[4794]),0},
+{"secp160r1","secp160r1",NID_secp160r1,5,&(lvalues[4799]),0},
+{"secp160r2","secp160r2",NID_secp160r2,5,&(lvalues[4804]),0},
+{"secp192k1","secp192k1",NID_secp192k1,5,&(lvalues[4809]),0},
+{"secp224k1","secp224k1",NID_secp224k1,5,&(lvalues[4814]),0},
+{"secp224r1","secp224r1",NID_secp224r1,5,&(lvalues[4819]),0},
+{"secp256k1","secp256k1",NID_secp256k1,5,&(lvalues[4824]),0},
+{"secp384r1","secp384r1",NID_secp384r1,5,&(lvalues[4829]),0},
+{"secp521r1","secp521r1",NID_secp521r1,5,&(lvalues[4834]),0},
+{"sect113r1","sect113r1",NID_sect113r1,5,&(lvalues[4839]),0},
+{"sect113r2","sect113r2",NID_sect113r2,5,&(lvalues[4844]),0},
+{"sect131r1","sect131r1",NID_sect131r1,5,&(lvalues[4849]),0},
+{"sect131r2","sect131r2",NID_sect131r2,5,&(lvalues[4854]),0},
+{"sect163k1","sect163k1",NID_sect163k1,5,&(lvalues[4859]),0},
+{"sect163r1","sect163r1",NID_sect163r1,5,&(lvalues[4864]),0},
+{"sect163r2","sect163r2",NID_sect163r2,5,&(lvalues[4869]),0},
+{"sect193r1","sect193r1",NID_sect193r1,5,&(lvalues[4874]),0},
+{"sect193r2","sect193r2",NID_sect193r2,5,&(lvalues[4879]),0},
+{"sect233k1","sect233k1",NID_sect233k1,5,&(lvalues[4884]),0},
+{"sect233r1","sect233r1",NID_sect233r1,5,&(lvalues[4889]),0},
+{"sect239k1","sect239k1",NID_sect239k1,5,&(lvalues[4894]),0},
+{"sect283k1","sect283k1",NID_sect283k1,5,&(lvalues[4899]),0},
+{"sect283r1","sect283r1",NID_sect283r1,5,&(lvalues[4904]),0},
+{"sect409k1","sect409k1",NID_sect409k1,5,&(lvalues[4909]),0},
+{"sect409r1","sect409r1",NID_sect409r1,5,&(lvalues[4914]),0},
+{"sect571k1","sect571k1",NID_sect571k1,5,&(lvalues[4919]),0},
+{"sect571r1","sect571r1",NID_sect571r1,5,&(lvalues[4924]),0},
 {"wap-wsg-idm-ecid-wtls1","wap-wsg-idm-ecid-wtls1",
-	NID_wap_wsg_idm_ecid_wtls1,5,&(lvalues[4935]),0},
+	NID_wap_wsg_idm_ecid_wtls1,5,&(lvalues[4929]),0},
 {"wap-wsg-idm-ecid-wtls3","wap-wsg-idm-ecid-wtls3",
-	NID_wap_wsg_idm_ecid_wtls3,5,&(lvalues[4940]),0},
+	NID_wap_wsg_idm_ecid_wtls3,5,&(lvalues[4934]),0},
 {"wap-wsg-idm-ecid-wtls4","wap-wsg-idm-ecid-wtls4",
-	NID_wap_wsg_idm_ecid_wtls4,5,&(lvalues[4945]),0},
+	NID_wap_wsg_idm_ecid_wtls4,5,&(lvalues[4939]),0},
 {"wap-wsg-idm-ecid-wtls5","wap-wsg-idm-ecid-wtls5",
-	NID_wap_wsg_idm_ecid_wtls5,5,&(lvalues[4950]),0},
+	NID_wap_wsg_idm_ecid_wtls5,5,&(lvalues[4944]),0},
 {"wap-wsg-idm-ecid-wtls6","wap-wsg-idm-ecid-wtls6",
-	NID_wap_wsg_idm_ecid_wtls6,5,&(lvalues[4955]),0},
+	NID_wap_wsg_idm_ecid_wtls6,5,&(lvalues[4949]),0},
 {"wap-wsg-idm-ecid-wtls7","wap-wsg-idm-ecid-wtls7",
-	NID_wap_wsg_idm_ecid_wtls7,5,&(lvalues[4960]),0},
+	NID_wap_wsg_idm_ecid_wtls7,5,&(lvalues[4954]),0},
 {"wap-wsg-idm-ecid-wtls8","wap-wsg-idm-ecid-wtls8",
-	NID_wap_wsg_idm_ecid_wtls8,5,&(lvalues[4965]),0},
+	NID_wap_wsg_idm_ecid_wtls8,5,&(lvalues[4959]),0},
 {"wap-wsg-idm-ecid-wtls9","wap-wsg-idm-ecid-wtls9",
-	NID_wap_wsg_idm_ecid_wtls9,5,&(lvalues[4970]),0},
+	NID_wap_wsg_idm_ecid_wtls9,5,&(lvalues[4964]),0},
 {"wap-wsg-idm-ecid-wtls10","wap-wsg-idm-ecid-wtls10",
-	NID_wap_wsg_idm_ecid_wtls10,5,&(lvalues[4975]),0},
+	NID_wap_wsg_idm_ecid_wtls10,5,&(lvalues[4969]),0},
 {"wap-wsg-idm-ecid-wtls11","wap-wsg-idm-ecid-wtls11",
-	NID_wap_wsg_idm_ecid_wtls11,5,&(lvalues[4980]),0},
+	NID_wap_wsg_idm_ecid_wtls11,5,&(lvalues[4974]),0},
 {"wap-wsg-idm-ecid-wtls12","wap-wsg-idm-ecid-wtls12",
-	NID_wap_wsg_idm_ecid_wtls12,5,&(lvalues[4985]),0},
-{"anyPolicy","X509v3 Any Policy",NID_any_policy,4,&(lvalues[4990]),0},
+	NID_wap_wsg_idm_ecid_wtls12,5,&(lvalues[4979]),0},
+{"anyPolicy","X509v3 Any Policy",NID_any_policy,4,&(lvalues[4984]),0},
 {"policyMappings","X509v3 Policy Mappings",NID_policy_mappings,3,
-	&(lvalues[4994]),0},
+	&(lvalues[4988]),0},
 {"inhibitAnyPolicy","X509v3 Inhibit Any Policy",
-	NID_inhibit_any_policy,3,&(lvalues[4997]),0},
+	NID_inhibit_any_policy,3,&(lvalues[4991]),0},
 {"Oakley-EC2N-3","ipsec3",NID_ipsec3,0,NULL,0},
 {"Oakley-EC2N-4","ipsec4",NID_ipsec4,0,NULL,0},
 {"CAMELLIA-128-CBC","camellia-128-cbc",NID_camellia_128_cbc,11,
-	&(lvalues[5000]),0},
+	&(lvalues[4994]),0},
 {"CAMELLIA-192-CBC","camellia-192-cbc",NID_camellia_192_cbc,11,
-	&(lvalues[5011]),0},
+	&(lvalues[5005]),0},
 {"CAMELLIA-256-CBC","camellia-256-cbc",NID_camellia_256_cbc,11,
-	&(lvalues[5022]),0},
+	&(lvalues[5016]),0},
 {"CAMELLIA-128-ECB","camellia-128-ecb",NID_camellia_128_ecb,8,
-	&(lvalues[5033]),0},
+	&(lvalues[5027]),0},
 {"CAMELLIA-192-ECB","camellia-192-ecb",NID_camellia_192_ecb,8,
-	&(lvalues[5041]),0},
+	&(lvalues[5035]),0},
 {"CAMELLIA-256-ECB","camellia-256-ecb",NID_camellia_256_ecb,8,
-	&(lvalues[5049]),0},
+	&(lvalues[5043]),0},
 {"CAMELLIA-128-CFB","camellia-128-cfb",NID_camellia_128_cfb128,8,
-	&(lvalues[5057]),0},
+	&(lvalues[5051]),0},
 {"CAMELLIA-192-CFB","camellia-192-cfb",NID_camellia_192_cfb128,8,
-	&(lvalues[5065]),0},
+	&(lvalues[5059]),0},
 {"CAMELLIA-256-CFB","camellia-256-cfb",NID_camellia_256_cfb128,8,
-	&(lvalues[5073]),0},
+	&(lvalues[5067]),0},
 {"CAMELLIA-128-CFB1","camellia-128-cfb1",NID_camellia_128_cfb1,0,NULL,0},
 {"CAMELLIA-192-CFB1","camellia-192-cfb1",NID_camellia_192_cfb1,0,NULL,0},
 {"CAMELLIA-256-CFB1","camellia-256-cfb1",NID_camellia_256_cfb1,0,NULL,0},
@@ -2133,284 +2132,284 @@
 {"CAMELLIA-192-CFB8","camellia-192-cfb8",NID_camellia_192_cfb8,0,NULL,0},
 {"CAMELLIA-256-CFB8","camellia-256-cfb8",NID_camellia_256_cfb8,0,NULL,0},
 {"CAMELLIA-128-OFB","camellia-128-ofb",NID_camellia_128_ofb128,8,
-	&(lvalues[5081]),0},
+	&(lvalues[5075]),0},
 {"CAMELLIA-192-OFB","camellia-192-ofb",NID_camellia_192_ofb128,8,
-	&(lvalues[5089]),0},
+	&(lvalues[5083]),0},
 {"CAMELLIA-256-OFB","camellia-256-ofb",NID_camellia_256_ofb128,8,
-	&(lvalues[5097]),0},
+	&(lvalues[5091]),0},
 {"subjectDirectoryAttributes","X509v3 Subject Directory Attributes",
-	NID_subject_directory_attributes,3,&(lvalues[5105]),0},
-{"issuingDistributionPoint","X509v3 Issuing Distrubution Point",
-	NID_issuing_distribution_point,3,&(lvalues[5108]),0},
+	NID_subject_directory_attributes,3,&(lvalues[5099]),0},
+{"issuingDistributionPoint","X509v3 Issuing Distribution Point",
+	NID_issuing_distribution_point,3,&(lvalues[5102]),0},
 {"certificateIssuer","X509v3 Certificate Issuer",
-	NID_certificate_issuer,3,&(lvalues[5111]),0},
+	NID_certificate_issuer,3,&(lvalues[5105]),0},
 {NULL,NULL,NID_undef,0,NULL,0},
-{"KISA","kisa",NID_kisa,6,&(lvalues[5114]),0},
+{"KISA","kisa",NID_kisa,6,&(lvalues[5108]),0},
 {NULL,NULL,NID_undef,0,NULL,0},
 {NULL,NULL,NID_undef,0,NULL,0},
-{"SEED-ECB","seed-ecb",NID_seed_ecb,8,&(lvalues[5120]),0},
-{"SEED-CBC","seed-cbc",NID_seed_cbc,8,&(lvalues[5128]),0},
-{"SEED-OFB","seed-ofb",NID_seed_ofb128,8,&(lvalues[5136]),0},
-{"SEED-CFB","seed-cfb",NID_seed_cfb128,8,&(lvalues[5144]),0},
-{"HMAC-MD5","hmac-md5",NID_hmac_md5,8,&(lvalues[5152]),0},
-{"HMAC-SHA1","hmac-sha1",NID_hmac_sha1,8,&(lvalues[5160]),0},
+{"SEED-ECB","seed-ecb",NID_seed_ecb,8,&(lvalues[5114]),0},
+{"SEED-CBC","seed-cbc",NID_seed_cbc,8,&(lvalues[5122]),0},
+{"SEED-OFB","seed-ofb",NID_seed_ofb128,8,&(lvalues[5130]),0},
+{"SEED-CFB","seed-cfb",NID_seed_cfb128,8,&(lvalues[5138]),0},
+{"HMAC-MD5","hmac-md5",NID_hmac_md5,8,&(lvalues[5146]),0},
+{"HMAC-SHA1","hmac-sha1",NID_hmac_sha1,8,&(lvalues[5154]),0},
 {"id-PasswordBasedMAC","password based MAC",NID_id_PasswordBasedMAC,9,
-	&(lvalues[5168]),0},
+	&(lvalues[5162]),0},
 {"id-DHBasedMac","Diffie-Hellman based MAC",NID_id_DHBasedMac,9,
-	&(lvalues[5177]),0},
+	&(lvalues[5171]),0},
 {"id-it-suppLangTags","id-it-suppLangTags",NID_id_it_suppLangTags,8,
-	&(lvalues[5186]),0},
-{"caRepository","CA Repository",NID_caRepository,8,&(lvalues[5194]),0},
+	&(lvalues[5180]),0},
+{"caRepository","CA Repository",NID_caRepository,8,&(lvalues[5188]),0},
 {"id-smime-ct-compressedData","id-smime-ct-compressedData",
-	NID_id_smime_ct_compressedData,11,&(lvalues[5202]),0},
+	NID_id_smime_ct_compressedData,11,&(lvalues[5196]),0},
 {"id-ct-asciiTextWithCRLF","id-ct-asciiTextWithCRLF",
-	NID_id_ct_asciiTextWithCRLF,11,&(lvalues[5213]),0},
+	NID_id_ct_asciiTextWithCRLF,11,&(lvalues[5207]),0},
 {"id-aes128-wrap","id-aes128-wrap",NID_id_aes128_wrap,9,
-	&(lvalues[5224]),0},
+	&(lvalues[5218]),0},
 {"id-aes192-wrap","id-aes192-wrap",NID_id_aes192_wrap,9,
-	&(lvalues[5233]),0},
+	&(lvalues[5227]),0},
 {"id-aes256-wrap","id-aes256-wrap",NID_id_aes256_wrap,9,
-	&(lvalues[5242]),0},
+	&(lvalues[5236]),0},
 {"ecdsa-with-Recommended","ecdsa-with-Recommended",
-	NID_ecdsa_with_Recommended,7,&(lvalues[5251]),0},
+	NID_ecdsa_with_Recommended,7,&(lvalues[5245]),0},
 {"ecdsa-with-Specified","ecdsa-with-Specified",
-	NID_ecdsa_with_Specified,7,&(lvalues[5258]),0},
+	NID_ecdsa_with_Specified,7,&(lvalues[5252]),0},
 {"ecdsa-with-SHA224","ecdsa-with-SHA224",NID_ecdsa_with_SHA224,8,
-	&(lvalues[5265]),0},
+	&(lvalues[5259]),0},
 {"ecdsa-with-SHA256","ecdsa-with-SHA256",NID_ecdsa_with_SHA256,8,
-	&(lvalues[5273]),0},
+	&(lvalues[5267]),0},
 {"ecdsa-with-SHA384","ecdsa-with-SHA384",NID_ecdsa_with_SHA384,8,
-	&(lvalues[5281]),0},
+	&(lvalues[5275]),0},
 {"ecdsa-with-SHA512","ecdsa-with-SHA512",NID_ecdsa_with_SHA512,8,
-	&(lvalues[5289]),0},
-{"hmacWithMD5","hmacWithMD5",NID_hmacWithMD5,8,&(lvalues[5297]),0},
+	&(lvalues[5283]),0},
+{"hmacWithMD5","hmacWithMD5",NID_hmacWithMD5,8,&(lvalues[5291]),0},
 {"hmacWithSHA224","hmacWithSHA224",NID_hmacWithSHA224,8,
-	&(lvalues[5305]),0},
+	&(lvalues[5299]),0},
 {"hmacWithSHA256","hmacWithSHA256",NID_hmacWithSHA256,8,
-	&(lvalues[5313]),0},
+	&(lvalues[5307]),0},
 {"hmacWithSHA384","hmacWithSHA384",NID_hmacWithSHA384,8,
-	&(lvalues[5321]),0},
+	&(lvalues[5315]),0},
 {"hmacWithSHA512","hmacWithSHA512",NID_hmacWithSHA512,8,
-	&(lvalues[5329]),0},
+	&(lvalues[5323]),0},
 {"dsa_with_SHA224","dsa_with_SHA224",NID_dsa_with_SHA224,9,
-	&(lvalues[5337]),0},
+	&(lvalues[5331]),0},
 {"dsa_with_SHA256","dsa_with_SHA256",NID_dsa_with_SHA256,9,
-	&(lvalues[5346]),0},
-{"whirlpool","whirlpool",NID_whirlpool,6,&(lvalues[5355]),0},
-{"cryptopro","cryptopro",NID_cryptopro,5,&(lvalues[5361]),0},
-{"cryptocom","cryptocom",NID_cryptocom,5,&(lvalues[5366]),0},
+	&(lvalues[5340]),0},
+{"whirlpool","whirlpool",NID_whirlpool,6,&(lvalues[5349]),0},
+{"cryptopro","cryptopro",NID_cryptopro,5,&(lvalues[5355]),0},
+{"cryptocom","cryptocom",NID_cryptocom,5,&(lvalues[5360]),0},
 {"id-GostR3411-94-with-GostR3410-2001",
 	"GOST R 34.11-94 with GOST R 34.10-2001",
-	NID_id_GostR3411_94_with_GostR3410_2001,6,&(lvalues[5371]),0},
+	NID_id_GostR3411_94_with_GostR3410_2001,6,&(lvalues[5365]),0},
 {"id-GostR3411-94-with-GostR3410-94",
 	"GOST R 34.11-94 with GOST R 34.10-94",
-	NID_id_GostR3411_94_with_GostR3410_94,6,&(lvalues[5377]),0},
-{"md_gost94","GOST R 34.11-94",NID_id_GostR3411_94,6,&(lvalues[5383]),0},
+	NID_id_GostR3411_94_with_GostR3410_94,6,&(lvalues[5371]),0},
+{"md_gost94","GOST R 34.11-94",NID_id_GostR3411_94,6,&(lvalues[5377]),0},
 {"id-HMACGostR3411-94","HMAC GOST 34.11-94",NID_id_HMACGostR3411_94,6,
-	&(lvalues[5389]),0},
+	&(lvalues[5383]),0},
 {"gost2001","GOST R 34.10-2001",NID_id_GostR3410_2001,6,
-	&(lvalues[5395]),0},
-{"gost94","GOST R 34.10-94",NID_id_GostR3410_94,6,&(lvalues[5401]),0},
-{"gost89","GOST 28147-89",NID_id_Gost28147_89,6,&(lvalues[5407]),0},
+	&(lvalues[5389]),0},
+{"gost94","GOST R 34.10-94",NID_id_GostR3410_94,6,&(lvalues[5395]),0},
+{"gost89","GOST 28147-89",NID_id_Gost28147_89,6,&(lvalues[5401]),0},
 {"gost89-cnt","gost89-cnt",NID_gost89_cnt,0,NULL,0},
 {"gost-mac","GOST 28147-89 MAC",NID_id_Gost28147_89_MAC,6,
-	&(lvalues[5413]),0},
+	&(lvalues[5407]),0},
 {"prf-gostr3411-94","GOST R 34.11-94 PRF",NID_id_GostR3411_94_prf,6,
-	&(lvalues[5419]),0},
+	&(lvalues[5413]),0},
 {"id-GostR3410-2001DH","GOST R 34.10-2001 DH",NID_id_GostR3410_2001DH,
-	6,&(lvalues[5425]),0},
+	6,&(lvalues[5419]),0},
 {"id-GostR3410-94DH","GOST R 34.10-94 DH",NID_id_GostR3410_94DH,6,
-	&(lvalues[5431]),0},
+	&(lvalues[5425]),0},
 {"id-Gost28147-89-CryptoPro-KeyMeshing",
 	"id-Gost28147-89-CryptoPro-KeyMeshing",
-	NID_id_Gost28147_89_CryptoPro_KeyMeshing,7,&(lvalues[5437]),0},
+	NID_id_Gost28147_89_CryptoPro_KeyMeshing,7,&(lvalues[5431]),0},
 {"id-Gost28147-89-None-KeyMeshing","id-Gost28147-89-None-KeyMeshing",
-	NID_id_Gost28147_89_None_KeyMeshing,7,&(lvalues[5444]),0},
+	NID_id_Gost28147_89_None_KeyMeshing,7,&(lvalues[5438]),0},
 {"id-GostR3411-94-TestParamSet","id-GostR3411-94-TestParamSet",
-	NID_id_GostR3411_94_TestParamSet,7,&(lvalues[5451]),0},
+	NID_id_GostR3411_94_TestParamSet,7,&(lvalues[5445]),0},
 {"id-GostR3411-94-CryptoProParamSet",
 	"id-GostR3411-94-CryptoProParamSet",
-	NID_id_GostR3411_94_CryptoProParamSet,7,&(lvalues[5458]),0},
+	NID_id_GostR3411_94_CryptoProParamSet,7,&(lvalues[5452]),0},
 {"id-Gost28147-89-TestParamSet","id-Gost28147-89-TestParamSet",
-	NID_id_Gost28147_89_TestParamSet,7,&(lvalues[5465]),0},
+	NID_id_Gost28147_89_TestParamSet,7,&(lvalues[5459]),0},
 {"id-Gost28147-89-CryptoPro-A-ParamSet",
 	"id-Gost28147-89-CryptoPro-A-ParamSet",
-	NID_id_Gost28147_89_CryptoPro_A_ParamSet,7,&(lvalues[5472]),0},
+	NID_id_Gost28147_89_CryptoPro_A_ParamSet,7,&(lvalues[5466]),0},
 {"id-Gost28147-89-CryptoPro-B-ParamSet",
 	"id-Gost28147-89-CryptoPro-B-ParamSet",
-	NID_id_Gost28147_89_CryptoPro_B_ParamSet,7,&(lvalues[5479]),0},
+	NID_id_Gost28147_89_CryptoPro_B_ParamSet,7,&(lvalues[5473]),0},
 {"id-Gost28147-89-CryptoPro-C-ParamSet",
 	"id-Gost28147-89-CryptoPro-C-ParamSet",
-	NID_id_Gost28147_89_CryptoPro_C_ParamSet,7,&(lvalues[5486]),0},
+	NID_id_Gost28147_89_CryptoPro_C_ParamSet,7,&(lvalues[5480]),0},
 {"id-Gost28147-89-CryptoPro-D-ParamSet",
 	"id-Gost28147-89-CryptoPro-D-ParamSet",
-	NID_id_Gost28147_89_CryptoPro_D_ParamSet,7,&(lvalues[5493]),0},
+	NID_id_Gost28147_89_CryptoPro_D_ParamSet,7,&(lvalues[5487]),0},
 {"id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet",
 	"id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet",
-	NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet,7,&(lvalues[5500]),
+	NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet,7,&(lvalues[5494]),
 	0},
 {"id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet",
 	"id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet",
-	NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet,7,&(lvalues[5507]),
+	NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet,7,&(lvalues[5501]),
 	0},
 {"id-Gost28147-89-CryptoPro-RIC-1-ParamSet",
 	"id-Gost28147-89-CryptoPro-RIC-1-ParamSet",
-	NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet,7,&(lvalues[5514]),0},
+	NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet,7,&(lvalues[5508]),0},
 {"id-GostR3410-94-TestParamSet","id-GostR3410-94-TestParamSet",
-	NID_id_GostR3410_94_TestParamSet,7,&(lvalues[5521]),0},
+	NID_id_GostR3410_94_TestParamSet,7,&(lvalues[5515]),0},
 {"id-GostR3410-94-CryptoPro-A-ParamSet",
 	"id-GostR3410-94-CryptoPro-A-ParamSet",
-	NID_id_GostR3410_94_CryptoPro_A_ParamSet,7,&(lvalues[5528]),0},
+	NID_id_GostR3410_94_CryptoPro_A_ParamSet,7,&(lvalues[5522]),0},
 {"id-GostR3410-94-CryptoPro-B-ParamSet",
 	"id-GostR3410-94-CryptoPro-B-ParamSet",
-	NID_id_GostR3410_94_CryptoPro_B_ParamSet,7,&(lvalues[5535]),0},
+	NID_id_GostR3410_94_CryptoPro_B_ParamSet,7,&(lvalues[5529]),0},
 {"id-GostR3410-94-CryptoPro-C-ParamSet",
 	"id-GostR3410-94-CryptoPro-C-ParamSet",
-	NID_id_GostR3410_94_CryptoPro_C_ParamSet,7,&(lvalues[5542]),0},
+	NID_id_GostR3410_94_CryptoPro_C_ParamSet,7,&(lvalues[5536]),0},
 {"id-GostR3410-94-CryptoPro-D-ParamSet",
 	"id-GostR3410-94-CryptoPro-D-ParamSet",
-	NID_id_GostR3410_94_CryptoPro_D_ParamSet,7,&(lvalues[5549]),0},
+	NID_id_GostR3410_94_CryptoPro_D_ParamSet,7,&(lvalues[5543]),0},
 {"id-GostR3410-94-CryptoPro-XchA-ParamSet",
 	"id-GostR3410-94-CryptoPro-XchA-ParamSet",
-	NID_id_GostR3410_94_CryptoPro_XchA_ParamSet,7,&(lvalues[5556]),0},
+	NID_id_GostR3410_94_CryptoPro_XchA_ParamSet,7,&(lvalues[5550]),0},
 {"id-GostR3410-94-CryptoPro-XchB-ParamSet",
 	"id-GostR3410-94-CryptoPro-XchB-ParamSet",
-	NID_id_GostR3410_94_CryptoPro_XchB_ParamSet,7,&(lvalues[5563]),0},
+	NID_id_GostR3410_94_CryptoPro_XchB_ParamSet,7,&(lvalues[5557]),0},
 {"id-GostR3410-94-CryptoPro-XchC-ParamSet",
 	"id-GostR3410-94-CryptoPro-XchC-ParamSet",
-	NID_id_GostR3410_94_CryptoPro_XchC_ParamSet,7,&(lvalues[5570]),0},
+	NID_id_GostR3410_94_CryptoPro_XchC_ParamSet,7,&(lvalues[5564]),0},
 {"id-GostR3410-2001-TestParamSet","id-GostR3410-2001-TestParamSet",
-	NID_id_GostR3410_2001_TestParamSet,7,&(lvalues[5577]),0},
+	NID_id_GostR3410_2001_TestParamSet,7,&(lvalues[5571]),0},
 {"id-GostR3410-2001-CryptoPro-A-ParamSet",
 	"id-GostR3410-2001-CryptoPro-A-ParamSet",
-	NID_id_GostR3410_2001_CryptoPro_A_ParamSet,7,&(lvalues[5584]),0},
+	NID_id_GostR3410_2001_CryptoPro_A_ParamSet,7,&(lvalues[5578]),0},
 {"id-GostR3410-2001-CryptoPro-B-ParamSet",
 	"id-GostR3410-2001-CryptoPro-B-ParamSet",
-	NID_id_GostR3410_2001_CryptoPro_B_ParamSet,7,&(lvalues[5591]),0},
+	NID_id_GostR3410_2001_CryptoPro_B_ParamSet,7,&(lvalues[5585]),0},
 {"id-GostR3410-2001-CryptoPro-C-ParamSet",
 	"id-GostR3410-2001-CryptoPro-C-ParamSet",
-	NID_id_GostR3410_2001_CryptoPro_C_ParamSet,7,&(lvalues[5598]),0},
+	NID_id_GostR3410_2001_CryptoPro_C_ParamSet,7,&(lvalues[5592]),0},
 {"id-GostR3410-2001-CryptoPro-XchA-ParamSet",
 	"id-GostR3410-2001-CryptoPro-XchA-ParamSet",
-	NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet,7,&(lvalues[5605]),0},
+	NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet,7,&(lvalues[5599]),0},
 	
 {"id-GostR3410-2001-CryptoPro-XchB-ParamSet",
 	"id-GostR3410-2001-CryptoPro-XchB-ParamSet",
-	NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet,7,&(lvalues[5612]),0},
+	NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet,7,&(lvalues[5606]),0},
 	
 {"id-GostR3410-94-a","id-GostR3410-94-a",NID_id_GostR3410_94_a,7,
-	&(lvalues[5619]),0},
+	&(lvalues[5613]),0},
 {"id-GostR3410-94-aBis","id-GostR3410-94-aBis",
-	NID_id_GostR3410_94_aBis,7,&(lvalues[5626]),0},
+	NID_id_GostR3410_94_aBis,7,&(lvalues[5620]),0},
 {"id-GostR3410-94-b","id-GostR3410-94-b",NID_id_GostR3410_94_b,7,
-	&(lvalues[5633]),0},
+	&(lvalues[5627]),0},
 {"id-GostR3410-94-bBis","id-GostR3410-94-bBis",
-	NID_id_GostR3410_94_bBis,7,&(lvalues[5640]),0},
+	NID_id_GostR3410_94_bBis,7,&(lvalues[5634]),0},
 {"id-Gost28147-89-cc","GOST 28147-89 Cryptocom ParamSet",
-	NID_id_Gost28147_89_cc,8,&(lvalues[5647]),0},
+	NID_id_Gost28147_89_cc,8,&(lvalues[5641]),0},
 {"gost94cc","GOST 34.10-94 Cryptocom",NID_id_GostR3410_94_cc,8,
-	&(lvalues[5655]),0},
+	&(lvalues[5649]),0},
 {"gost2001cc","GOST 34.10-2001 Cryptocom",NID_id_GostR3410_2001_cc,8,
-	&(lvalues[5663]),0},
+	&(lvalues[5657]),0},
 {"id-GostR3411-94-with-GostR3410-94-cc",
 	"GOST R 34.11-94 with GOST R 34.10-94 Cryptocom",
-	NID_id_GostR3411_94_with_GostR3410_94_cc,8,&(lvalues[5671]),0},
+	NID_id_GostR3411_94_with_GostR3410_94_cc,8,&(lvalues[5665]),0},
 {"id-GostR3411-94-with-GostR3410-2001-cc",
 	"GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom",
-	NID_id_GostR3411_94_with_GostR3410_2001_cc,8,&(lvalues[5679]),0},
+	NID_id_GostR3411_94_with_GostR3410_2001_cc,8,&(lvalues[5673]),0},
 {"id-GostR3410-2001-ParamSet-cc",
 	"GOST R 3410-2001 Parameter Set Cryptocom",
-	NID_id_GostR3410_2001_ParamSet_cc,8,&(lvalues[5687]),0},
+	NID_id_GostR3410_2001_ParamSet_cc,8,&(lvalues[5681]),0},
 {"HMAC","hmac",NID_hmac,0,NULL,0},
 {"LocalKeySet","Microsoft Local Key set",NID_LocalKeySet,9,
-	&(lvalues[5695]),0},
+	&(lvalues[5689]),0},
 {"freshestCRL","X509v3 Freshest CRL",NID_freshest_crl,3,
-	&(lvalues[5704]),0},
+	&(lvalues[5698]),0},
 {"id-on-permanentIdentifier","Permanent Identifier",
-	NID_id_on_permanentIdentifier,8,&(lvalues[5707]),0},
-{"searchGuide","searchGuide",NID_searchGuide,3,&(lvalues[5715]),0},
+	NID_id_on_permanentIdentifier,8,&(lvalues[5701]),0},
+{"searchGuide","searchGuide",NID_searchGuide,3,&(lvalues[5709]),0},
 {"businessCategory","businessCategory",NID_businessCategory,3,
-	&(lvalues[5718]),0},
-{"postalAddress","postalAddress",NID_postalAddress,3,&(lvalues[5721]),0},
-{"postOfficeBox","postOfficeBox",NID_postOfficeBox,3,&(lvalues[5724]),0},
+	&(lvalues[5712]),0},
+{"postalAddress","postalAddress",NID_postalAddress,3,&(lvalues[5715]),0},
+{"postOfficeBox","postOfficeBox",NID_postOfficeBox,3,&(lvalues[5718]),0},
 {"physicalDeliveryOfficeName","physicalDeliveryOfficeName",
-	NID_physicalDeliveryOfficeName,3,&(lvalues[5727]),0},
+	NID_physicalDeliveryOfficeName,3,&(lvalues[5721]),0},
 {"telephoneNumber","telephoneNumber",NID_telephoneNumber,3,
-	&(lvalues[5730]),0},
-{"telexNumber","telexNumber",NID_telexNumber,3,&(lvalues[5733]),0},
+	&(lvalues[5724]),0},
+{"telexNumber","telexNumber",NID_telexNumber,3,&(lvalues[5727]),0},
 {"teletexTerminalIdentifier","teletexTerminalIdentifier",
-	NID_teletexTerminalIdentifier,3,&(lvalues[5736]),0},
+	NID_teletexTerminalIdentifier,3,&(lvalues[5730]),0},
 {"facsimileTelephoneNumber","facsimileTelephoneNumber",
-	NID_facsimileTelephoneNumber,3,&(lvalues[5739]),0},
-{"x121Address","x121Address",NID_x121Address,3,&(lvalues[5742]),0},
+	NID_facsimileTelephoneNumber,3,&(lvalues[5733]),0},
+{"x121Address","x121Address",NID_x121Address,3,&(lvalues[5736]),0},
 {"internationaliSDNNumber","internationaliSDNNumber",
-	NID_internationaliSDNNumber,3,&(lvalues[5745]),0},
+	NID_internationaliSDNNumber,3,&(lvalues[5739]),0},
 {"registeredAddress","registeredAddress",NID_registeredAddress,3,
-	&(lvalues[5748]),0},
+	&(lvalues[5742]),0},
 {"destinationIndicator","destinationIndicator",
-	NID_destinationIndicator,3,&(lvalues[5751]),0},
+	NID_destinationIndicator,3,&(lvalues[5745]),0},
 {"preferredDeliveryMethod","preferredDeliveryMethod",
-	NID_preferredDeliveryMethod,3,&(lvalues[5754]),0},
+	NID_preferredDeliveryMethod,3,&(lvalues[5748]),0},
 {"presentationAddress","presentationAddress",NID_presentationAddress,
-	3,&(lvalues[5757]),0},
+	3,&(lvalues[5751]),0},
 {"supportedApplicationContext","supportedApplicationContext",
-	NID_supportedApplicationContext,3,&(lvalues[5760]),0},
-{"member","member",NID_member,3,&(lvalues[5763]),0},
-{"owner","owner",NID_owner,3,&(lvalues[5766]),0},
-{"roleOccupant","roleOccupant",NID_roleOccupant,3,&(lvalues[5769]),0},
-{"seeAlso","seeAlso",NID_seeAlso,3,&(lvalues[5772]),0},
-{"userPassword","userPassword",NID_userPassword,3,&(lvalues[5775]),0},
+	NID_supportedApplicationContext,3,&(lvalues[5754]),0},
+{"member","member",NID_member,3,&(lvalues[5757]),0},
+{"owner","owner",NID_owner,3,&(lvalues[5760]),0},
+{"roleOccupant","roleOccupant",NID_roleOccupant,3,&(lvalues[5763]),0},
+{"seeAlso","seeAlso",NID_seeAlso,3,&(lvalues[5766]),0},
+{"userPassword","userPassword",NID_userPassword,3,&(lvalues[5769]),0},
 {"userCertificate","userCertificate",NID_userCertificate,3,
-	&(lvalues[5778]),0},
-{"cACertificate","cACertificate",NID_cACertificate,3,&(lvalues[5781]),0},
+	&(lvalues[5772]),0},
+{"cACertificate","cACertificate",NID_cACertificate,3,&(lvalues[5775]),0},
 {"authorityRevocationList","authorityRevocationList",
-	NID_authorityRevocationList,3,&(lvalues[5784]),0},
+	NID_authorityRevocationList,3,&(lvalues[5778]),0},
 {"certificateRevocationList","certificateRevocationList",
-	NID_certificateRevocationList,3,&(lvalues[5787]),0},
+	NID_certificateRevocationList,3,&(lvalues[5781]),0},
 {"crossCertificatePair","crossCertificatePair",
-	NID_crossCertificatePair,3,&(lvalues[5790]),0},
+	NID_crossCertificatePair,3,&(lvalues[5784]),0},
 {"enhancedSearchGuide","enhancedSearchGuide",NID_enhancedSearchGuide,
-	3,&(lvalues[5793]),0},
+	3,&(lvalues[5787]),0},
 {"protocolInformation","protocolInformation",NID_protocolInformation,
-	3,&(lvalues[5796]),0},
+	3,&(lvalues[5790]),0},
 {"distinguishedName","distinguishedName",NID_distinguishedName,3,
-	&(lvalues[5799]),0},
-{"uniqueMember","uniqueMember",NID_uniqueMember,3,&(lvalues[5802]),0},
+	&(lvalues[5793]),0},
+{"uniqueMember","uniqueMember",NID_uniqueMember,3,&(lvalues[5796]),0},
 {"houseIdentifier","houseIdentifier",NID_houseIdentifier,3,
-	&(lvalues[5805]),0},
+	&(lvalues[5799]),0},
 {"supportedAlgorithms","supportedAlgorithms",NID_supportedAlgorithms,
-	3,&(lvalues[5808]),0},
+	3,&(lvalues[5802]),0},
 {"deltaRevocationList","deltaRevocationList",NID_deltaRevocationList,
-	3,&(lvalues[5811]),0},
-{"dmdName","dmdName",NID_dmdName,3,&(lvalues[5814]),0},
+	3,&(lvalues[5805]),0},
+{"dmdName","dmdName",NID_dmdName,3,&(lvalues[5808]),0},
 {"id-alg-PWRI-KEK","id-alg-PWRI-KEK",NID_id_alg_PWRI_KEK,11,
-	&(lvalues[5817]),0},
+	&(lvalues[5811]),0},
 {"CMAC","cmac",NID_cmac,0,NULL,0},
-{"id-aes128-GCM","aes-128-gcm",NID_aes_128_gcm,9,&(lvalues[5828]),0},
-{"id-aes128-CCM","aes-128-ccm",NID_aes_128_ccm,9,&(lvalues[5837]),0},
+{"id-aes128-GCM","aes-128-gcm",NID_aes_128_gcm,9,&(lvalues[5822]),0},
+{"id-aes128-CCM","aes-128-ccm",NID_aes_128_ccm,9,&(lvalues[5831]),0},
 {"id-aes128-wrap-pad","id-aes128-wrap-pad",NID_id_aes128_wrap_pad,9,
-	&(lvalues[5846]),0},
-{"id-aes192-GCM","aes-192-gcm",NID_aes_192_gcm,9,&(lvalues[5855]),0},
-{"id-aes192-CCM","aes-192-ccm",NID_aes_192_ccm,9,&(lvalues[5864]),0},
+	&(lvalues[5840]),0},
+{"id-aes192-GCM","aes-192-gcm",NID_aes_192_gcm,9,&(lvalues[5849]),0},
+{"id-aes192-CCM","aes-192-ccm",NID_aes_192_ccm,9,&(lvalues[5858]),0},
 {"id-aes192-wrap-pad","id-aes192-wrap-pad",NID_id_aes192_wrap_pad,9,
-	&(lvalues[5873]),0},
-{"id-aes256-GCM","aes-256-gcm",NID_aes_256_gcm,9,&(lvalues[5882]),0},
-{"id-aes256-CCM","aes-256-ccm",NID_aes_256_ccm,9,&(lvalues[5891]),0},
+	&(lvalues[5867]),0},
+{"id-aes256-GCM","aes-256-gcm",NID_aes_256_gcm,9,&(lvalues[5876]),0},
+{"id-aes256-CCM","aes-256-ccm",NID_aes_256_ccm,9,&(lvalues[5885]),0},
 {"id-aes256-wrap-pad","id-aes256-wrap-pad",NID_id_aes256_wrap_pad,9,
-	&(lvalues[5900]),0},
+	&(lvalues[5894]),0},
 {"AES-128-CTR","aes-128-ctr",NID_aes_128_ctr,0,NULL,0},
 {"AES-192-CTR","aes-192-ctr",NID_aes_192_ctr,0,NULL,0},
 {"AES-256-CTR","aes-256-ctr",NID_aes_256_ctr,0,NULL,0},
 {"id-camellia128-wrap","id-camellia128-wrap",NID_id_camellia128_wrap,
-	11,&(lvalues[5909]),0},
+	11,&(lvalues[5903]),0},
 {"id-camellia192-wrap","id-camellia192-wrap",NID_id_camellia192_wrap,
-	11,&(lvalues[5920]),0},
+	11,&(lvalues[5914]),0},
 {"id-camellia256-wrap","id-camellia256-wrap",NID_id_camellia256_wrap,
-	11,&(lvalues[5931]),0},
+	11,&(lvalues[5925]),0},
 {"anyExtendedKeyUsage","Any Extended Key Usage",
-	NID_anyExtendedKeyUsage,4,&(lvalues[5942]),0},
-{"MGF1","mgf1",NID_mgf1,9,&(lvalues[5946]),0},
-{"RSASSA-PSS","rsassaPss",NID_rsassaPss,9,&(lvalues[5955]),0},
+	NID_anyExtendedKeyUsage,4,&(lvalues[5936]),0},
+{"MGF1","mgf1",NID_mgf1,9,&(lvalues[5940]),0},
+{"RSASSA-PSS","rsassaPss",NID_rsassaPss,9,&(lvalues[5949]),0},
 {"AES-128-XTS","aes-128-xts",NID_aes_128_xts,0,NULL,0},
 {"AES-256-XTS","aes-256-xts",NID_aes_256_xts,0,NULL,0},
 {"RC4-HMAC-MD5","rc4-hmac-md5",NID_rc4_hmac_md5,0,NULL,0},
@@ -2420,67 +2419,67 @@
 	NID_aes_192_cbc_hmac_sha1,0,NULL,0},
 {"AES-256-CBC-HMAC-SHA1","aes-256-cbc-hmac-sha1",
 	NID_aes_256_cbc_hmac_sha1,0,NULL,0},
-{"RSAES-OAEP","rsaesOaep",NID_rsaesOaep,9,&(lvalues[5964]),0},
-{"dhpublicnumber","X9.42 DH",NID_dhpublicnumber,7,&(lvalues[5973]),0},
+{"RSAES-OAEP","rsaesOaep",NID_rsaesOaep,9,&(lvalues[5958]),0},
+{"dhpublicnumber","X9.42 DH",NID_dhpublicnumber,7,&(lvalues[5967]),0},
 {"brainpoolP160r1","brainpoolP160r1",NID_brainpoolP160r1,9,
-	&(lvalues[5980]),0},
+	&(lvalues[5974]),0},
 {"brainpoolP160t1","brainpoolP160t1",NID_brainpoolP160t1,9,
-	&(lvalues[5989]),0},
+	&(lvalues[5983]),0},
 {"brainpoolP192r1","brainpoolP192r1",NID_brainpoolP192r1,9,
-	&(lvalues[5998]),0},
+	&(lvalues[5992]),0},
 {"brainpoolP192t1","brainpoolP192t1",NID_brainpoolP192t1,9,
-	&(lvalues[6007]),0},
+	&(lvalues[6001]),0},
 {"brainpoolP224r1","brainpoolP224r1",NID_brainpoolP224r1,9,
-	&(lvalues[6016]),0},
+	&(lvalues[6010]),0},
 {"brainpoolP224t1","brainpoolP224t1",NID_brainpoolP224t1,9,
-	&(lvalues[6025]),0},
+	&(lvalues[6019]),0},
 {"brainpoolP256r1","brainpoolP256r1",NID_brainpoolP256r1,9,
-	&(lvalues[6034]),0},
+	&(lvalues[6028]),0},
 {"brainpoolP256t1","brainpoolP256t1",NID_brainpoolP256t1,9,
-	&(lvalues[6043]),0},
+	&(lvalues[6037]),0},
 {"brainpoolP320r1","brainpoolP320r1",NID_brainpoolP320r1,9,
-	&(lvalues[6052]),0},
+	&(lvalues[6046]),0},
 {"brainpoolP320t1","brainpoolP320t1",NID_brainpoolP320t1,9,
-	&(lvalues[6061]),0},
+	&(lvalues[6055]),0},
 {"brainpoolP384r1","brainpoolP384r1",NID_brainpoolP384r1,9,
-	&(lvalues[6070]),0},
+	&(lvalues[6064]),0},
 {"brainpoolP384t1","brainpoolP384t1",NID_brainpoolP384t1,9,
-	&(lvalues[6079]),0},
+	&(lvalues[6073]),0},
 {"brainpoolP512r1","brainpoolP512r1",NID_brainpoolP512r1,9,
-	&(lvalues[6088]),0},
+	&(lvalues[6082]),0},
 {"brainpoolP512t1","brainpoolP512t1",NID_brainpoolP512t1,9,
-	&(lvalues[6097]),0},
-{"PSPECIFIED","pSpecified",NID_pSpecified,9,&(lvalues[6106]),0},
+	&(lvalues[6091]),0},
+{"PSPECIFIED","pSpecified",NID_pSpecified,9,&(lvalues[6100]),0},
 {"dhSinglePass-stdDH-sha1kdf-scheme",
 	"dhSinglePass-stdDH-sha1kdf-scheme",
-	NID_dhSinglePass_stdDH_sha1kdf_scheme,9,&(lvalues[6115]),0},
+	NID_dhSinglePass_stdDH_sha1kdf_scheme,9,&(lvalues[6109]),0},
 {"dhSinglePass-stdDH-sha224kdf-scheme",
 	"dhSinglePass-stdDH-sha224kdf-scheme",
-	NID_dhSinglePass_stdDH_sha224kdf_scheme,6,&(lvalues[6124]),0},
+	NID_dhSinglePass_stdDH_sha224kdf_scheme,6,&(lvalues[6118]),0},
 {"dhSinglePass-stdDH-sha256kdf-scheme",
 	"dhSinglePass-stdDH-sha256kdf-scheme",
-	NID_dhSinglePass_stdDH_sha256kdf_scheme,6,&(lvalues[6130]),0},
+	NID_dhSinglePass_stdDH_sha256kdf_scheme,6,&(lvalues[6124]),0},
 {"dhSinglePass-stdDH-sha384kdf-scheme",
 	"dhSinglePass-stdDH-sha384kdf-scheme",
-	NID_dhSinglePass_stdDH_sha384kdf_scheme,6,&(lvalues[6136]),0},
+	NID_dhSinglePass_stdDH_sha384kdf_scheme,6,&(lvalues[6130]),0},
 {"dhSinglePass-stdDH-sha512kdf-scheme",
 	"dhSinglePass-stdDH-sha512kdf-scheme",
-	NID_dhSinglePass_stdDH_sha512kdf_scheme,6,&(lvalues[6142]),0},
+	NID_dhSinglePass_stdDH_sha512kdf_scheme,6,&(lvalues[6136]),0},
 {"dhSinglePass-cofactorDH-sha1kdf-scheme",
 	"dhSinglePass-cofactorDH-sha1kdf-scheme",
-	NID_dhSinglePass_cofactorDH_sha1kdf_scheme,9,&(lvalues[6148]),0},
+	NID_dhSinglePass_cofactorDH_sha1kdf_scheme,9,&(lvalues[6142]),0},
 {"dhSinglePass-cofactorDH-sha224kdf-scheme",
 	"dhSinglePass-cofactorDH-sha224kdf-scheme",
-	NID_dhSinglePass_cofactorDH_sha224kdf_scheme,6,&(lvalues[6157]),0},
+	NID_dhSinglePass_cofactorDH_sha224kdf_scheme,6,&(lvalues[6151]),0},
 {"dhSinglePass-cofactorDH-sha256kdf-scheme",
 	"dhSinglePass-cofactorDH-sha256kdf-scheme",
-	NID_dhSinglePass_cofactorDH_sha256kdf_scheme,6,&(lvalues[6163]),0},
+	NID_dhSinglePass_cofactorDH_sha256kdf_scheme,6,&(lvalues[6157]),0},
 {"dhSinglePass-cofactorDH-sha384kdf-scheme",
 	"dhSinglePass-cofactorDH-sha384kdf-scheme",
-	NID_dhSinglePass_cofactorDH_sha384kdf_scheme,6,&(lvalues[6169]),0},
+	NID_dhSinglePass_cofactorDH_sha384kdf_scheme,6,&(lvalues[6163]),0},
 {"dhSinglePass-cofactorDH-sha512kdf-scheme",
 	"dhSinglePass-cofactorDH-sha512kdf-scheme",
-	NID_dhSinglePass_cofactorDH_sha512kdf_scheme,6,&(lvalues[6175]),0},
+	NID_dhSinglePass_cofactorDH_sha512kdf_scheme,6,&(lvalues[6169]),0},
 {"dh-std-kdf","dh-std-kdf",NID_dh_std_kdf,0,NULL,0},
 {"dh-cofactor-kdf","dh-cofactor-kdf",NID_dh_cofactor_kdf,0,NULL,0},
 };
@@ -2636,7 +2635,6 @@
 121,	/* "RC5-ECB" */
 123,	/* "RC5-OFB" */
 117,	/* "RIPEMD160" */
-124,	/* "RLE" */
 19,	/* "RSA" */
  7,	/* "RSA-MD2" */
 396,	/* "RSA-MD4" */
@@ -3553,7 +3551,7 @@
 857,	/* "X509v3 Freshest CRL" */
 748,	/* "X509v3 Inhibit Any Policy" */
 86,	/* "X509v3 Issuer Alternative Name" */
-770,	/* "X509v3 Issuing Distrubution Point" */
+770,	/* "X509v3 Issuing Distribution Point" */
 83,	/* "X509v3 Key Usage" */
 666,	/* "X509v3 Name Constraints" */
 403,	/* "X509v3 No Revocation Available" */
@@ -4147,7 +4145,6 @@
 377,	/* "rsaSignature" */
 919,	/* "rsaesOaep" */
 912,	/* "rsassaPss" */
-124,	/* "run length compression" */
 482,	/* "sOARecord" */
 155,	/* "safeContentsBag" */
 291,	/* "sbgp-autonomousSysNum" */
@@ -4681,7 +4678,6 @@
 744,	/* OBJ_wap_wsg_idm_ecid_wtls11      2 23 43 1 4 11 */
 745,	/* OBJ_wap_wsg_idm_ecid_wtls12      2 23 43 1 4 12 */
 804,	/* OBJ_whirlpool                    1 0 10118 3 0 55 */
-124,	/* OBJ_rle_compression              1 1 1 1 666 1 */
 773,	/* OBJ_kisa                         1 2 410 200004 */
 807,	/* OBJ_id_GostR3411_94_with_GostR3410_2001 1 2 643 2 2 3 */
 808,	/* OBJ_id_GostR3411_94_with_GostR3410_94 1 2 643 2 2 4 */
diff --git a/src/crypto/obj/objects.txt b/src/crypto/obj/objects.txt
index aeffc6c..2757c4f 100644
--- a/src/crypto/obj/objects.txt
+++ b/src/crypto/obj/objects.txt
@@ -748,7 +748,7 @@
 !Cname delta-crl
 id-ce 27		: deltaCRL		: X509v3 Delta CRL Indicator
 !Cname issuing-distribution-point
-id-ce 28		: issuingDistributionPoint : X509v3 Issuing Distrubution Point
+id-ce 28		: issuingDistributionPoint : X509v3 Issuing Distribution Point
 !Cname certificate-issuer
 id-ce 29		: certificateIssuer	: X509v3 Certificate Issuer
 !Cname name-constraints
@@ -838,9 +838,7 @@
 mime-mhs-headings 1	: id-hex-partial-message : id-hex-partial-message
 mime-mhs-headings 2	: id-hex-multipart-message : id-hex-multipart-message
 
-# What the hell are these OIDs, really?
-!Cname rle-compression
-1 1 1 1 666 1		: RLE			: run length compression
+# RFC 3274
 !Cname zlib-compression
 id-smime-alg 8		: ZLIB			: zlib compression
 
diff --git a/src/crypto/pem/pem_lib.c b/src/crypto/pem/pem_lib.c
index 48e3297..5201467 100644
--- a/src/crypto/pem/pem_lib.c
+++ b/src/crypto/pem/pem_lib.c
@@ -331,8 +331,9 @@
 		if (kstr == NULL)
 			{
 			klen = 0;
-			if (callback)
-				klen=(*callback)(buf,PEM_BUFSIZE,1,u);
+			if (!callback)
+				callback = PEM_def_callback;
+ 			klen=(*callback)(buf,PEM_BUFSIZE,1,u);
 			if (klen <= 0)
 				{
 				OPENSSL_PUT_ERROR(PEM, PEM_ASN1_write_bio, PEM_R_READ_KEY);
@@ -403,8 +404,8 @@
 	if (cipher->cipher == NULL) return(1);
 
 	klen = 0;
-	if (callback)
-		klen=callback(buf,PEM_BUFSIZE,0,u);
+	if (!callback) callback = PEM_def_callback;
+	klen=callback(buf,PEM_BUFSIZE,0,u);
 	if (klen <= 0)
 		{
 		OPENSSL_PUT_ERROR(PEM, PEM_do_header, PEM_R_BAD_PASSWORD_READ);
@@ -811,3 +812,17 @@
 	return p - pem_str;
 	}
 
+int PEM_def_callback(char *buf, int size, int rwflag, void *userdata)
+	{
+	if (!buf || !userdata)
+		{
+		return 0;
+		}
+	size_t len = strlen((char *) userdata);
+	if (len >= (size_t) size)
+		{
+		return 0;
+		}
+	strcpy(buf, (char *) userdata);
+	return len;
+	}
diff --git a/src/crypto/pem/pem_pk8.c b/src/crypto/pem/pem_pk8.c
index 383a524..035038e 100644
--- a/src/crypto/pem/pem_pk8.c
+++ b/src/crypto/pem/pem_pk8.c
@@ -124,8 +124,8 @@
 	if(enc || (nid != -1)) {
 		if(!kstr) {
 			klen = 0;
-			if (cb)
-				klen = cb(buf, PEM_BUFSIZE, 1, u);
+			if (!cb) cb = PEM_def_callback;
+			klen = cb(buf, PEM_BUFSIZE, 1, u);
 			if(klen <= 0) {
 				OPENSSL_PUT_ERROR(PEM, do_pk8pkey, PEM_R_READ_KEY);
 				PKCS8_PRIV_KEY_INFO_free(p8inf);
@@ -160,8 +160,8 @@
 	if(!p8) return NULL;
 
 	klen = 0;
-	if (cb)
-		klen=cb(psbuf,PEM_BUFSIZE,0,u);
+	if (!cb) cb = PEM_def_callback;
+	klen=cb(psbuf,PEM_BUFSIZE,0,u);
 	if (klen <= 0) {
 		OPENSSL_PUT_ERROR(PEM, d2i_PKCS8PrivateKey_bio, PEM_R_BAD_PASSWORD_READ);
 		X509_SIG_free(p8);
diff --git a/src/crypto/pem/pem_pkey.c b/src/crypto/pem/pem_pkey.c
index c0aba51..fe58558 100644
--- a/src/crypto/pem/pem_pkey.c
+++ b/src/crypto/pem/pem_pkey.c
@@ -106,7 +106,8 @@
 		if(!p8) goto p8err;
 
 		klen = 0;
-		if (cb) klen=cb(psbuf,PEM_BUFSIZE,0,u);
+		if (!cb) cb = PEM_def_callback;
+		klen=cb(psbuf,PEM_BUFSIZE,0,u);
 		if (klen <= 0) {
 			OPENSSL_PUT_ERROR(PEM, PEM_read_bio_PrivateKey, PEM_R_BAD_PASSWORD_READ);
 			X509_SIG_free(p8);
@@ -309,4 +310,3 @@
         return(ret);
 	}
 #endif
-
diff --git a/src/crypto/pkcs8/CMakeLists.txt b/src/crypto/pkcs8/CMakeLists.txt
index c0f2746..4426f1e 100644
--- a/src/crypto/pkcs8/CMakeLists.txt
+++ b/src/crypto/pkcs8/CMakeLists.txt
@@ -15,6 +15,8 @@
   pkcs12_test
 
   pkcs12_test.cc
+
+  $<TARGET_OBJECTS:test_support>
 )
 
 target_link_libraries(pkcs12_test crypto)
diff --git a/src/crypto/rand/rand.c b/src/crypto/rand/rand.c
index ae30edb..a647b6a 100644
--- a/src/crypto/rand/rand.c
+++ b/src/crypto/rand/rand.c
@@ -14,6 +14,7 @@
 
 #include <openssl/rand.h>
 
+#include <limits.h>
 #include <string.h>
 
 #include <openssl/mem.h>
@@ -95,6 +96,7 @@
       return 1;
     }
 
+    memset(state->partial_block, 0, sizeof(state->partial_block));
     state->calls_used = kMaxCallsPerRefresh;
   }
 
@@ -149,6 +151,16 @@
 
 void RAND_seed(const void *buf, int num) {}
 
+int RAND_load_file(const char *path, long num) {
+  if (num < 0) {  /* read the "whole file" */
+    return 1;
+  } else if (num <= INT_MAX) {
+    return (int) num;
+  } else {
+    return INT_MAX;
+  }
+}
+
 void RAND_add(const void *buf, int num, double entropy) {}
 
 int RAND_poll(void) {
diff --git a/src/crypto/rand/windows.c b/src/crypto/rand/windows.c
index 1a0cb8b..7bfcb1d 100644
--- a/src/crypto/rand/windows.c
+++ b/src/crypto/rand/windows.c
@@ -27,7 +27,7 @@
  * "Community Additions" comment on MSDN here:
  * http://msdn.microsoft.com/en-us/library/windows/desktop/aa387694.aspx */
 #define SystemFunction036 NTAPI SystemFunction036
-#include <ntsecapi.h>
+#include <NTSecAPI.h>
 #undef SystemFunction036
 
 #pragma warning(pop)
diff --git a/src/crypto/rc4/rc4.c b/src/crypto/rc4/rc4.c
index 2a98fd0..aa19dc2 100644
--- a/src/crypto/rc4/rc4.c
+++ b/src/crypto/rc4/rc4.c
@@ -141,37 +141,6 @@
         in += sizeof(RC4_CHUNK);
         out += sizeof(RC4_CHUNK);
       }
-      if (len) {
-        RC4_CHUNK mask = (RC4_CHUNK) - 1, ochunk;
-
-        ichunk = *(RC4_CHUNK *)in;
-        ochunk = *(RC4_CHUNK *)out;
-        otp = 0;
-        i = BESHFT(0);
-        mask <<= (sizeof(RC4_CHUNK) - len) << 3;
-        switch (len & (sizeof(RC4_CHUNK) - 1)) {
-          case 7:
-            otp = RC4_STEP << i, i -= 8;
-          case 6:
-            otp |= RC4_STEP << i, i -= 8;
-          case 5:
-            otp |= RC4_STEP << i, i -= 8;
-          case 4:
-            otp |= RC4_STEP << i, i -= 8;
-          case 3:
-            otp |= RC4_STEP << i, i -= 8;
-          case 2:
-            otp |= RC4_STEP << i, i -= 8;
-          case 1:
-            otp |= RC4_STEP << i, i -= 8;
-        }
-        ochunk &= ~mask;
-        ochunk |= (otp ^ ichunk) & mask;
-        *(RC4_CHUNK *)out = ochunk;
-      }
-      key->x = x;
-      key->y = y;
-      return;
     } else { /* LITTLE-ENDIAN CASE */
 #define LESHFT(c) (((c) * 8) & (sizeof(RC4_CHUNK) * 8 - 1))
       for (; len & (0 - sizeof(RC4_CHUNK)); len -= sizeof(RC4_CHUNK)) {
@@ -190,37 +159,6 @@
         in += sizeof(RC4_CHUNK);
         out += sizeof(RC4_CHUNK);
       }
-      if (len) {
-        RC4_CHUNK mask = (RC4_CHUNK) - 1, ochunk;
-
-        ichunk = *(RC4_CHUNK *)in;
-        ochunk = *(RC4_CHUNK *)out;
-        otp = 0;
-        i = 0;
-        mask >>= (sizeof(RC4_CHUNK) - len) << 3;
-        switch (len & (sizeof(RC4_CHUNK) - 1)) {
-          case 7:
-            otp = RC4_STEP, i += 8;
-          case 6:
-            otp |= RC4_STEP << i, i += 8;
-          case 5:
-            otp |= RC4_STEP << i, i += 8;
-          case 4:
-            otp |= RC4_STEP << i, i += 8;
-          case 3:
-            otp |= RC4_STEP << i, i += 8;
-          case 2:
-            otp |= RC4_STEP << i, i += 8;
-          case 1:
-            otp |= RC4_STEP << i, i += 8;
-        }
-        ochunk &= ~mask;
-        ochunk |= (otp ^ ichunk) & mask;
-        *(RC4_CHUNK *)out = ochunk;
-      }
-      key->x = x;
-      key->y = y;
-      return;
     }
   }
 #define LOOP(in, out)   \
diff --git a/src/crypto/refcount_c11.c b/src/crypto/refcount_c11.c
new file mode 100644
index 0000000..fbc0343
--- /dev/null
+++ b/src/crypto/refcount_c11.c
@@ -0,0 +1,67 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include "internal.h"
+
+
+#if defined(OPENSSL_C11_ATOMIC)
+
+#include <assert.h>
+#include <stdalign.h>
+#include <stdatomic.h>
+#include <stdlib.h>
+
+#include <openssl/type_check.h>
+
+
+/* See comment above the typedef of CRYPTO_refcount_t about these tests. */
+static_assert(alignof(CRYPTO_refcount_t) == alignof(_Atomic CRYPTO_refcount_t),
+              "_Atomic alters the needed alignment of a reference count");
+static_assert(sizeof(CRYPTO_refcount_t) == sizeof(_Atomic CRYPTO_refcount_t),
+              "_Atomic alters the size of a reference count");
+
+static_assert((CRYPTO_refcount_t)-1 == CRYPTO_REFCOUNT_MAX,
+              "CRYPTO_REFCOUNT_MAX is incorrect");
+
+void CRYPTO_refcount_inc(CRYPTO_refcount_t *in_count) {
+  _Atomic CRYPTO_refcount_t *count = (_Atomic CRYPTO_refcount_t *) in_count;
+  uint32_t expected = atomic_load(count);
+
+  while (expected != CRYPTO_REFCOUNT_MAX) {
+    uint32_t new_value = expected + 1;
+    if (atomic_compare_exchange_weak(count, &expected, new_value)) {
+      break;
+    }
+  }
+}
+
+int CRYPTO_refcount_dec_and_test_zero(CRYPTO_refcount_t *in_count) {
+  _Atomic CRYPTO_refcount_t *count = (_Atomic CRYPTO_refcount_t *)in_count;
+  uint32_t expected = atomic_load(count);
+
+  for (;;) {
+    if (expected == 0) {
+      abort();
+    } else if (expected == CRYPTO_REFCOUNT_MAX) {
+      return 0;
+    } else {
+      const uint32_t new_value = expected - 1;
+      if (atomic_compare_exchange_weak(count, &expected, new_value)) {
+        return new_value == 0;
+      }
+    }
+  }
+}
+
+#endif  /* OPENSSL_C11_ATOMIC */
diff --git a/src/crypto/refcount_lock.c b/src/crypto/refcount_lock.c
new file mode 100644
index 0000000..bb8ef86
--- /dev/null
+++ b/src/crypto/refcount_lock.c
@@ -0,0 +1,53 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include "internal.h"
+
+#include <stdlib.h>
+
+#include <openssl/type_check.h>
+
+
+#if !defined(OPENSSL_C11_ATOMIC)
+
+OPENSSL_COMPILE_ASSERT((CRYPTO_refcount_t)-1 == CRYPTO_REFCOUNT_MAX,
+                       CRYPTO_REFCOUNT_MAX_is_incorrect);
+
+static struct CRYPTO_STATIC_MUTEX g_refcount_lock = CRYPTO_STATIC_MUTEX_INIT;
+
+void CRYPTO_refcount_inc(CRYPTO_refcount_t *count) {
+  CRYPTO_STATIC_MUTEX_lock_write(&g_refcount_lock);
+  if (*count < CRYPTO_REFCOUNT_MAX) {
+    (*count)++;
+  }
+  CRYPTO_STATIC_MUTEX_unlock(&g_refcount_lock);
+}
+
+int CRYPTO_refcount_dec_and_test_zero(CRYPTO_refcount_t *count) {
+  int ret;
+
+  CRYPTO_STATIC_MUTEX_lock_write(&g_refcount_lock);
+  if (*count == 0) {
+    abort();
+  }
+  if (*count < CRYPTO_REFCOUNT_MAX) {
+    (*count)--;
+  }
+  ret = (*count == 0);
+  CRYPTO_STATIC_MUTEX_unlock(&g_refcount_lock);
+
+  return ret;
+}
+
+#endif  /* OPENSSL_C11_ATOMIC */
diff --git a/src/crypto/refcount_test.c b/src/crypto/refcount_test.c
new file mode 100644
index 0000000..97bfbd6
--- /dev/null
+++ b/src/crypto/refcount_test.c
@@ -0,0 +1,59 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include "internal.h"
+
+#include <stdio.h>
+
+#include <openssl/type_check.h>
+
+
+int main(int argc, char **argv) {
+  CRYPTO_refcount_t count = 0;
+
+  CRYPTO_refcount_inc(&count);
+  if (count != 1) {
+    fprintf(stderr, "Incrementing reference count did not work.\n");
+    return 1;
+  }
+  if (!CRYPTO_refcount_dec_and_test_zero(&count) || count != 0) {
+    fprintf(stderr, "Decrementing reference count to zero did not work.\n");
+    return 1;
+  }
+
+  count = CRYPTO_REFCOUNT_MAX;
+  CRYPTO_refcount_inc(&count);
+  if (count != CRYPTO_REFCOUNT_MAX) {
+    fprintf(stderr, "Count did not saturate correctly when incrementing.\n");
+    return 1;
+  }
+  if (CRYPTO_refcount_dec_and_test_zero(&count) ||
+      count != CRYPTO_REFCOUNT_MAX) {
+    fprintf(stderr, "Count did not saturate correctly when decrementing.\n");
+    return 1;
+  }
+
+  count = 2;
+  if (CRYPTO_refcount_dec_and_test_zero(&count)) {
+    fprintf(stderr, "Decrementing two resulted in zero!\n");
+    return 1;
+  }
+  if (count != 1) {
+    fprintf(stderr, "Decrementing two did not produce one!");
+    return 1;
+  }
+
+  printf("PASS\n");
+  return 0;
+}
diff --git a/src/crypto/rsa/CMakeLists.txt b/src/crypto/rsa/CMakeLists.txt
index c438e1d..0ea12c8 100644
--- a/src/crypto/rsa/CMakeLists.txt
+++ b/src/crypto/rsa/CMakeLists.txt
@@ -16,6 +16,8 @@
   rsa_test
 
   rsa_test.c
+
+  $<TARGET_OBJECTS:test_support>
 )
 
 target_link_libraries(rsa_test crypto)
diff --git a/src/crypto/rsa/rsa.c b/src/crypto/rsa/rsa.c
index 5cc48ed..17059b0 100644
--- a/src/crypto/rsa/rsa.c
+++ b/src/crypto/rsa/rsa.c
@@ -121,7 +121,7 @@
     return;
   }
 
-  if (CRYPTO_add(&rsa->references, -1, CRYPTO_LOCK_RSA) > 0) {
+  if (!CRYPTO_refcount_dec_and_test_zero(&rsa->references)) {
     return;
   }
 
@@ -150,7 +150,7 @@
 }
 
 int RSA_up_ref(RSA *rsa) {
-  CRYPTO_add(&rsa->references, 1, CRYPTO_LOCK_RSA);
+  CRYPTO_refcount_inc(&rsa->references);
   return 1;
 }
 
diff --git a/src/crypto/sha/asm/sha256-armv4.pl b/src/crypto/sha/asm/sha256-armv4.pl
index 778c3d9..df71676 100644
--- a/src/crypto/sha/asm/sha256-armv4.pl
+++ b/src/crypto/sha/asm/sha256-armv4.pl
@@ -479,7 +479,7 @@
 	stmdb	sp!,{r4-r12,lr}
 
 	sub	$H,sp,#16*4+16
-	adr	$Ktbl,K256
+	adrl	$Ktbl,K256
 	bic	$H,$H,#15		@ align for 128-bit stores
 	mov	$t2,sp
 	mov	sp,$H			@ alloca
diff --git a/src/crypto/sha/sha1.c b/src/crypto/sha/sha1.c
index 60d09f6..c03e608 100644
--- a/src/crypto/sha/sha1.c
+++ b/src/crypto/sha/sha1.c
@@ -101,7 +101,7 @@
 #define HASH_CBLOCK             64
 #define HASH_MAKE_STRING(c, s) \
   do {                         \
-    unsigned long ll;          \
+    uint32_t ll;               \
     ll = (c)->h0;              \
     (void) HOST_l2c(ll, (s));  \
     ll = (c)->h1;              \
@@ -188,8 +188,8 @@
 #if !defined(SHA1_ASM)
 static void HASH_BLOCK_DATA_ORDER(SHA_CTX *c, const void *p, size_t num) {
   const uint8_t *data = p;
-  register unsigned MD32_REG_T A, B, C, D, E, T, l;
-  unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, XX8, XX9, XX10,
+  register uint32_t A, B, C, D, E, T, l;
+  uint32_t XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, XX8, XX9, XX10,
       XX11, XX12, XX13, XX14, XX15;
 
   A = c->h0;
diff --git a/src/crypto/sha/sha256.c b/src/crypto/sha/sha256.c
index 8d4106e..8276bbb 100644
--- a/src/crypto/sha/sha256.c
+++ b/src/crypto/sha/sha256.c
@@ -144,10 +144,13 @@
  * to truncate to amount of bytes not divisible by 4. I bet not, but if it is,
  * then default: case shall be extended. For reference. Idea behind separate
  * cases for pre-defined lenghts is to let the compiler decide if it's
- * appropriate to unroll small loops. */
+ * appropriate to unroll small loops.
+ *
+ * TODO(davidben): The small |md_len| case is one of the few places a low-level
+ * hash 'final' function can fail. This should never happen. */
 #define HASH_MAKE_STRING(c, s)                              \
   do {                                                      \
-    unsigned long ll;                                       \
+    uint32_t ll;                                            \
     unsigned int nn;                                        \
     switch ((c)->md_len) {                                  \
       case SHA224_DIGEST_LENGTH:                            \
@@ -163,8 +166,9 @@
         }                                                   \
         break;                                              \
       default:                                              \
-        if ((c)->md_len > SHA256_DIGEST_LENGTH)             \
+        if ((c)->md_len > SHA256_DIGEST_LENGTH) {           \
           return 0;                                         \
+        }                                                   \
         for (nn = 0; nn < (c)->md_len / 4; nn++) {          \
           ll = (c)->h[nn];                                  \
           (void) HOST_l2c(ll, (s));                         \
@@ -232,7 +236,7 @@
 
 static void sha256_block_data_order(SHA256_CTX *ctx, const void *in,
                                     size_t num) {
-  unsigned MD32_REG_T a, b, c, d, e, f, g, h, s0, s1, T1;
+  uint32_t a, b, c, d, e, f, g, h, s0, s1, T1;
   HASH_LONG X[16];
   int i;
   const uint8_t *data = in;
diff --git a/src/crypto/sha/sha512.c b/src/crypto/sha/sha512.c
index 2acefb1..57c96ab 100644
--- a/src/crypto/sha/sha512.c
+++ b/src/crypto/sha/sha512.c
@@ -166,7 +166,7 @@
 void sha512_block_data_order(SHA512_CTX *ctx, const void *in, size_t num);
 
 
-int SHA384_Final(unsigned char *md, SHA512_CTX *sha) {
+int SHA384_Final(uint8_t *md, SHA512_CTX *sha) {
   return SHA512_Final(md, sha);
 }
 
@@ -174,7 +174,7 @@
   return SHA512_Update(sha, data, len);
 }
 
-void SHA512_Transform(SHA512_CTX *c, const unsigned char *data) {
+void SHA512_Transform(SHA512_CTX *c, const uint8_t *data) {
 #ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
   if ((size_t)data % sizeof(c->u.d[0]) != 0) {
     memcpy(c->u.p, data, sizeof(c->u.p));
@@ -244,7 +244,7 @@
   return 1;
 }
 
-int SHA512_Final(unsigned char *md, SHA512_CTX *sha) {
+int SHA512_Final(uint8_t *md, SHA512_CTX *sha) {
   uint8_t *p = (uint8_t *)sha->u.p;
   size_t n = sha->num;
 
@@ -276,7 +276,9 @@
 
   sha512_block_data_order(sha, p, 1);
 
-  if (md == 0) {
+  if (md == NULL) {
+    /* TODO(davidben): This NULL check is absent in other low-level hash 'final'
+     * functions and is one of the few places one can fail. */
     return 0;
   }
 
@@ -312,6 +314,8 @@
       break;
     /* ... as well as make sure md_len is not abused. */
     default:
+      /* TODO(davidben): This bad |md_len| case is one of the few places a
+       * low-level hash 'final' function can fail. This should never happen. */
       return 0;
   }
 
@@ -415,7 +419,7 @@
 
 #ifndef PULL64
 #define B(x, j) \
-  (((uint64_t)(*(((const unsigned char *)(&x)) + j))) << ((7 - j) * 8))
+  (((uint64_t)(*(((const uint8_t *)(&x)) + j))) << ((7 - j) * 8))
 #define PULL64(x)                                                        \
   (B(x, 0) | B(x, 1) | B(x, 2) | B(x, 3) | B(x, 4) | B(x, 5) | B(x, 6) | \
    B(x, 7))
diff --git a/src/crypto/test/CMakeLists.txt b/src/crypto/test/CMakeLists.txt
index 0d5ca81..84a6174 100644
--- a/src/crypto/test/CMakeLists.txt
+++ b/src/crypto/test/CMakeLists.txt
@@ -4,4 +4,5 @@
   OBJECT
 
   file_test.cc
+  malloc.cc
 )
diff --git a/src/crypto/test/file_test.cc b/src/crypto/test/file_test.cc
index 12405f2..8df6f9a 100644
--- a/src/crypto/test/file_test.cc
+++ b/src/crypto/test/file_test.cc
@@ -17,6 +17,7 @@
 #include <ctype.h>
 #include <errno.h>
 #include <stdarg.h>
+#include <stdlib.h>
 #include <string.h>
 
 #include <openssl/err.h>
diff --git a/src/ssl/test/malloc.cc b/src/crypto/test/malloc.cc
similarity index 86%
rename from src/ssl/test/malloc.cc
rename to src/crypto/test/malloc.cc
index 2ec5582..9ffdf01 100644
--- a/src/ssl/test/malloc.cc
+++ b/src/crypto/test/malloc.cc
@@ -15,17 +15,23 @@
 #include <openssl/base.h>
 
 #if defined(__has_feature)
-#if __has_feature(address_sanitizer)
+#if __has_feature(address_sanitizer) || __has_feature(memory_sanitizer)
 #define OPENSSL_ASAN
 #endif
 #endif
 
+#if defined(__GLIBC__) && !defined(__UCLIBC__)
+#define OPENSSL_GLIBC
+#endif
+
 // This file isn't built on ARM or Aarch64 because we link statically in those
-// builds and trying to override malloc in a static link doesn't work. It's also
-// disabled on ASan builds as this interferes with ASan's malloc interceptor.
+// builds and trying to override malloc in a static link doesn't work. It also
+// requires glibc. It's also disabled on ASan builds as this interferes with
+// ASan's malloc interceptor.
 //
-// TODO(davidben): See if this and ASan's interceptors can be made to coexist.
-#if defined(__linux__) && !defined(OPENSSL_ARM) && \
+// TODO(davidben): See if this and ASan's and MSan's interceptors can be made to
+// coexist.
+#if defined(__linux__) && defined(OPENSSL_GLIBC) && !defined(OPENSSL_ARM) && \
     !defined(OPENSSL_AARCH64) && !defined(OPENSSL_ASAN)
 
 #include <stdint.h>
@@ -136,4 +142,4 @@
 
 }  // extern "C"
 
-#endif  /* defined(linux) && !ARM && !AARCH64 && !ASAN */
+#endif  /* defined(linux) && GLIBC && !ARM && !AARCH64 && !ASAN */
diff --git a/src/crypto/test/scoped_types.h b/src/crypto/test/scoped_types.h
index eb04c18..c5c8cfe 100644
--- a/src/crypto/test/scoped_types.h
+++ b/src/crypto/test/scoped_types.h
@@ -16,6 +16,7 @@
 #define OPENSSL_HEADER_CRYPTO_TEST_SCOPED_TYPES_H
 
 #include <stdint.h>
+#include <stdio.h>
 
 #include <openssl/bio.h>
 #include <openssl/bn.h>
@@ -57,6 +58,12 @@
   }
 };
 
+struct FileCloser {
+  void operator()(FILE *file) {
+    fclose(file);
+  }
+};
+
 template<typename T, void (*func)(T*)>
 using ScopedOpenSSLType = bssl::unique_ptr<T, OpenSSLDeleter<T, func>>;
 
@@ -108,6 +115,9 @@
 
 using ScopedX509Stack = ScopedOpenSSLStack<STACK_OF(X509), X509, X509_free>;
 
+using ScopedEVP_CIPHER_CTX = ScopedOpenSSLContext<EVP_CIPHER_CTX, int,
+                                                  EVP_CIPHER_CTX_init,
+                                                  EVP_CIPHER_CTX_cleanup>;
 using ScopedEVP_MD_CTX = ScopedOpenSSLContext<EVP_MD_CTX, int, EVP_MD_CTX_init,
                                               EVP_MD_CTX_cleanup>;
 using ScopedHMAC_CTX = ScopedOpenSSLContext<HMAC_CTX, void, HMAC_CTX_init,
@@ -116,5 +126,6 @@
 using ScopedOpenSSLBytes = bssl::unique_ptr<uint8_t, OpenSSLFree<uint8_t>>;
 using ScopedOpenSSLString = bssl::unique_ptr<char, OpenSSLFree<char>>;
 
+using ScopedFILE = bssl::unique_ptr<FILE, FileCloser>;
 
 #endif  // OPENSSL_HEADER_CRYPTO_TEST_SCOPED_TYPES_H
diff --git a/src/crypto/thread.c b/src/crypto/thread.c
index abc8b6f..8837115 100644
--- a/src/crypto/thread.c
+++ b/src/crypto/thread.c
@@ -69,40 +69,16 @@
 #include <openssl/mem.h>
 
 
-#define CRYPTO_LOCK_ITEM(x) #x
-
-/* lock_names contains the names of all the locks defined in thread.h. */
-static const char *const lock_names[] = {
-  CRYPTO_LOCK_LIST
-};
-
-#undef CRYPTO_LOCK_ITEM
-
-#define CRYPTO_NUM_LOCKS (sizeof(lock_names) / sizeof(lock_names[0]))
-
-static void (*locking_callback)(int mode, int lock_num, const char *file,
-                                int line) = 0;
-static int (*add_lock_callback)(int *pointer, int amount, int lock_num,
-                                const char *file, int line) = 0;
-
-int CRYPTO_num_locks(void) { return CRYPTO_NUM_LOCKS; }
+int CRYPTO_num_locks(void) { return 1; }
 
 void CRYPTO_set_locking_callback(void (*func)(int mode, int lock_num,
-                                              const char *file, int line)) {
-  locking_callback = func;
-}
+                                              const char *file, int line)) {}
 
 void CRYPTO_set_add_lock_callback(int (*func)(int *num, int mount, int lock_num,
-                                              const char *file, int line)) {
-  add_lock_callback = func;
-}
+                                              const char *file, int line)) {}
 
 const char *CRYPTO_get_lock_name(int lock_num) {
-  if (lock_num >= 0 && lock_num < CRYPTO_NUM_LOCKS) {
-    return lock_names[lock_num];
-  } else {
-    return "ERROR";
-  }
+  return "No old-style OpenSSL locks anymore";
 }
 
 int CRYPTO_THREADID_set_callback(void (*func)(CRYPTO_THREADID *)) { return 1; }
@@ -113,38 +89,6 @@
 
 void CRYPTO_THREADID_current(CRYPTO_THREADID *id) {}
 
-void (*CRYPTO_get_locking_callback(void))(int mode, int lock_num,
-                                          const char *file, int line) {
-  return locking_callback;
-}
-
-int (*CRYPTO_get_add_lock_callback(void))(int *num, int mount, int lock_num,
-                                          const char *file, int line) {
-  return add_lock_callback;
-}
-
-void CRYPTO_lock(int mode, int lock_num, const char *file, int line) {
-  if (locking_callback != NULL) {
-    locking_callback(mode, lock_num, file, line);
-  }
-}
-
-int CRYPTO_add_lock(int *pointer, int amount, int lock_num, const char *file,
-                    int line) {
-  int ret = 0;
-
-  if (add_lock_callback != NULL) {
-    ret = add_lock_callback(pointer, amount, lock_num, file, line);
-  } else {
-    CRYPTO_lock(CRYPTO_LOCK | CRYPTO_WRITE, lock_num, file, line);
-    ret = *pointer + amount;
-    *pointer = ret;
-    CRYPTO_lock(CRYPTO_UNLOCK | CRYPTO_WRITE, lock_num, file, line);
-  }
-
-  return ret;
-}
-
 void CRYPTO_set_id_callback(unsigned long (*func)(void)) {}
 
 void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(
diff --git a/src/crypto/thread_test.c b/src/crypto/thread_test.c
index e028b1b..cecda88 100644
--- a/src/crypto/thread_test.c
+++ b/src/crypto/thread_test.c
@@ -22,7 +22,7 @@
 #if defined(OPENSSL_WINDOWS)
 
 #pragma warning(push, 3)
-#include <windows.h>
+#include <Windows.h>
 #pragma warning(pop)
 
 typedef HANDLE thread_t;
diff --git a/src/crypto/x509/CMakeLists.txt b/src/crypto/x509/CMakeLists.txt
index 96cf35c..3bb5704 100644
--- a/src/crypto/x509/CMakeLists.txt
+++ b/src/crypto/x509/CMakeLists.txt
@@ -59,6 +59,8 @@
   pkcs7_test
 
   pkcs7_test.c
+
+  $<TARGET_OBJECTS:test_support>
 )
 
 target_link_libraries(pkcs7_test crypto)
diff --git a/src/crypto/x509/by_dir.c b/src/crypto/x509/by_dir.c
index 098c1bd..34bb1e4 100644
--- a/src/crypto/x509/by_dir.c
+++ b/src/crypto/x509/by_dir.c
@@ -66,6 +66,8 @@
 #include <openssl/thread.h>
 #include <openssl/x509.h>
 
+#include "../internal.h"
+
 
 typedef struct lookup_dir_hashes_st
 	{
@@ -262,6 +264,10 @@
 	return 1;
 	}
 
+/* g_ent_hashes_lock protects the |hashes| member of all |BY_DIR_ENTRY|
+ * objects. */
+static struct CRYPTO_STATIC_MUTEX g_ent_hashes_lock = CRYPTO_STATIC_MUTEX_INIT;
+
 static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
 	     X509_OBJECT *ret)
 	{
@@ -337,7 +343,7 @@
 			if (type == X509_LU_CRL && ent->hashes)
 				{
 				htmp.hash = h;
-				CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE);
+				CRYPTO_STATIC_MUTEX_lock_read(&g_ent_hashes_lock);
 				if (sk_BY_DIR_HASH_find(ent->hashes, &idx, &htmp))
 					{
 					hent = sk_BY_DIR_HASH_value(ent->hashes, idx);
@@ -348,7 +354,7 @@
 					hent = NULL;
 					k=0;
 					}
-				CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE);
+				CRYPTO_STATIC_MUTEX_unlock(&g_ent_hashes_lock);
 				}
 			else
 				{
@@ -418,19 +424,19 @@
 
 			/* we have added it to the cache so now pull
 			 * it out again */
-			CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+			CRYPTO_MUTEX_lock_write(&xl->store_ctx->objs_lock);
 			tmp = NULL;
 			if (sk_X509_OBJECT_find(xl->store_ctx->objs, &idx, &stmp)) {
 				tmp=sk_X509_OBJECT_value(xl->store_ctx->objs,idx);
 			}
-			CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+			CRYPTO_MUTEX_unlock(&xl->store_ctx->objs_lock);
 
 
 			/* If a CRL, update the last file suffix added for this */
 
 			if (type == X509_LU_CRL)
 				{
-				CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+				CRYPTO_STATIC_MUTEX_lock_write(&g_ent_hashes_lock);
 				/* Look for entry again in case another thread added
 				 * an entry first.
 				 */
@@ -445,7 +451,7 @@
 					hent = OPENSSL_malloc(sizeof(BY_DIR_HASH));
 					if (hent == NULL)
 						{
-						CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+						CRYPTO_STATIC_MUTEX_unlock(&g_ent_hashes_lock);
 						ok = 0;
 						goto finish;
 						}
@@ -453,7 +459,7 @@
 					hent->suffix = k;
 					if (!sk_BY_DIR_HASH_push(ent->hashes, hent))
 						{
-						CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+						CRYPTO_STATIC_MUTEX_unlock(&g_ent_hashes_lock);
 						OPENSSL_free(hent);
 						ok = 0;
 						goto finish;
@@ -462,8 +468,7 @@
 				else if (hent->suffix < k)
 					hent->suffix = k;
 
-				CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
-
+				CRYPTO_STATIC_MUTEX_unlock(&g_ent_hashes_lock);
 				}
 
 			if (tmp != NULL)
diff --git a/src/crypto/x509/x509_lu.c b/src/crypto/x509/x509_lu.c
index 34ef26e..a662305 100644
--- a/src/crypto/x509/x509_lu.c
+++ b/src/crypto/x509/x509_lu.c
@@ -64,6 +64,8 @@
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 
+#include "../internal.h"
+
 
 X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method)
 	{
@@ -186,6 +188,7 @@
 		return NULL;
 	memset(ret, 0, sizeof(*ret));
 	ret->objs = sk_X509_OBJECT_new(x509_object_cmp);
+	CRYPTO_MUTEX_init(&ret->objs_lock);
 	ret->cache = 1;
 	ret->get_cert_methods = sk_X509_LOOKUP_new_null();
 
@@ -228,7 +231,6 @@
 
 void X509_STORE_free(X509_STORE *vfy)
 	{
-	int i;
 	size_t j;
 	STACK_OF(X509_LOOKUP) *sk;
 	X509_LOOKUP *lu;
@@ -236,18 +238,11 @@
 	if (vfy == NULL)
 	    return;
 
-	i=CRYPTO_add(&vfy->references,-1,CRYPTO_LOCK_X509_STORE);
-#ifdef REF_PRINT
-	REF_PRINT("X509_STORE",vfy);
-#endif
-	if (i > 0) return;
-#ifdef REF_CHECK
-	if (i < 0)
-		{
-		fprintf(stderr,"X509_STORE_free, bad reference count\n");
-		abort(); /* ok */
-		}
-#endif
+	if (!CRYPTO_refcount_dec_and_test_zero(&vfy->references)) {
+	  return;
+	}
+
+	CRYPTO_MUTEX_cleanup(&vfy->objs_lock);
 
 	sk=vfy->get_cert_methods;
 	for (j=0; j<sk_X509_LOOKUP_num(sk); j++)
@@ -304,9 +299,9 @@
 	X509_OBJECT stmp,*tmp;
 	int i,j;
 
-	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+	CRYPTO_MUTEX_lock_write(&ctx->objs_lock);
 	tmp=X509_OBJECT_retrieve_by_subject(ctx->objs,type,name);
-	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+	CRYPTO_MUTEX_unlock(&ctx->objs_lock);
 
 	if (tmp == NULL || type == X509_LU_CRL)
 		{
@@ -356,7 +351,7 @@
 	obj->type=X509_LU_X509;
 	obj->data.x509=x;
 
-	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+	CRYPTO_MUTEX_lock_write(&ctx->objs_lock);
 
 	X509_OBJECT_up_ref_count(obj);
 
@@ -369,7 +364,7 @@
 		} 
 	else sk_X509_OBJECT_push(ctx->objs, obj);
 
-	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+	CRYPTO_MUTEX_unlock(&ctx->objs_lock);
 
 	return ret;
 	}
@@ -389,7 +384,7 @@
 	obj->type=X509_LU_CRL;
 	obj->data.crl=x;
 
-	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+	CRYPTO_MUTEX_lock_write(&ctx->objs_lock);
 
 	X509_OBJECT_up_ref_count(obj);
 
@@ -402,7 +397,7 @@
 		}
 	else sk_X509_OBJECT_push(ctx->objs, obj);
 
-	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+	CRYPTO_MUTEX_unlock(&ctx->objs_lock);
 
 	return ret;
 	}
@@ -415,7 +410,7 @@
 		X509_up_ref(a->data.x509);
 		break;
 	case X509_LU_CRL:
-		CRYPTO_add(&a->data.crl->references,1,CRYPTO_LOCK_X509_CRL);
+		CRYPTO_refcount_inc(&a->data.crl->references);
 		break;
 		}
 	}
@@ -503,7 +498,7 @@
 	X509 *x;
 	X509_OBJECT *obj;
 	sk = sk_X509_new_null();
-	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+	CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock);
 	idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
 	if (idx < 0)
 		{
@@ -511,18 +506,18 @@
 		 * objects to cache
 		 */
 		X509_OBJECT xobj;
-		CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+		CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
 		if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj))
 			{
 			sk_X509_free(sk);
 			return NULL;
 			}
 		X509_OBJECT_free_contents(&xobj);
-		CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+		CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock);
 		idx = x509_object_idx_cnt(ctx->ctx->objs,X509_LU_X509,nm, &cnt);
 		if (idx < 0)
 			{
-			CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+			CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
 			sk_X509_free(sk);
 			return NULL;
 			}
@@ -533,13 +528,13 @@
 		x = obj->data.x509;
 		if (!sk_X509_push(sk, X509_up_ref(x)))
 			{
-			CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+			CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
 			X509_free(x);
 			sk_X509_pop_free(sk, X509_free);
 			return NULL;
 			}
 		}
-	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+	CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
 	return sk;
 
 	}
@@ -551,24 +546,24 @@
 	X509_CRL *x;
 	X509_OBJECT *obj, xobj;
 	sk = sk_X509_CRL_new_null();
-	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+	CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock);
 	/* Check cache first */
 	idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt);
 
 	/* Always do lookup to possibly add new CRLs to cache
 	 */
-	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+	CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
 	if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj))
 		{
 		sk_X509_CRL_free(sk);
 		return NULL;
 		}
 	X509_OBJECT_free_contents(&xobj);
-	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+	CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock);
 	idx = x509_object_idx_cnt(ctx->ctx->objs,X509_LU_CRL, nm, &cnt);
 	if (idx < 0)
 		{
-		CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+		CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
 		sk_X509_CRL_free(sk);
 		return NULL;
 		}
@@ -577,16 +572,16 @@
 		{
 		obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
 		x = obj->data.crl;
-		CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL);
+		CRYPTO_refcount_inc(&x->references);
 		if (!sk_X509_CRL_push(sk, x))
 			{
-			CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+			CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
 			X509_CRL_free(x);
 			sk_X509_CRL_pop_free(sk, X509_CRL_free);
 			return NULL;
 			}
 		}
-	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+	CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
 	return sk;
 	}
 
@@ -667,7 +662,7 @@
 
 	/* Else find index of first cert accepted by 'check_issued' */
 	ret = 0;
-	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+	CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock);
 	idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn);
 	if (idx != -1) /* should be true as we've had at least one match */
 		{
@@ -689,7 +684,7 @@
 				}
 			}
 		}
-	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+	CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
 	return ret;
 	}
 
diff --git a/src/crypto/x509/x509_vfy.c b/src/crypto/x509/x509_vfy.c
index a0cd9fc..2ba9c84 100644
--- a/src/crypto/x509/x509_vfy.c
+++ b/src/crypto/x509/x509_vfy.c
@@ -273,7 +273,7 @@
 					OPENSSL_PUT_ERROR(X509, X509_verify_cert, ERR_R_MALLOC_FAILURE);
 					goto end;
 					}
-				CRYPTO_add(&xtmp->references,1,CRYPTO_LOCK_X509);
+				CRYPTO_refcount_inc(&xtmp->references);
 				(void)sk_X509_delete_ptr(sktmp,xtmp);
 				ctx->last_untrusted++;
 				x=xtmp;
@@ -990,7 +990,7 @@
 		*pissuer = best_crl_issuer;
 		*pscore = best_score;
 		*preasons = best_reasons;
-		CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509_CRL);
+		CRYPTO_refcount_inc(&best_crl->references);
 		if (*pdcrl)
 			{
 			X509_CRL_free(*pdcrl);
@@ -1097,7 +1097,7 @@
 			{
 			if (check_crl_time(ctx, delta, 0))
 				*pscore |= CRL_SCORE_TIME_DELTA;
-			CRYPTO_add(&delta->references, 1, CRYPTO_LOCK_X509_CRL);
+			CRYPTO_refcount_inc(&delta->references);
 			*dcrl = delta;
 			return;
 			}
diff --git a/src/crypto/x509/x_crl.c b/src/crypto/x509/x_crl.c
index aa92fa9..2f41bb1 100644
--- a/src/crypto/x509/x_crl.c
+++ b/src/crypto/x509/x_crl.c
@@ -65,6 +65,9 @@
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 
+#include "../internal.h"
+
+
 /* Method to handle CRL access.
  * In general a CRL could be very large (several Mb) and can consume large
  * amounts of resources if stored in memory by multiple processes.
@@ -370,7 +373,7 @@
 	DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
 	}
 
-ASN1_SEQUENCE_ref(X509_CRL, crl_cb, CRYPTO_LOCK_X509_CRL) = {
+ASN1_SEQUENCE_ref(X509_CRL, crl_cb) = {
 	ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO),
 	ASN1_SIMPLE(X509_CRL, sig_alg, X509_ALGOR),
 	ASN1_SIMPLE(X509_CRL, signature, ASN1_BIT_STRING)
@@ -463,6 +466,8 @@
 
 	}
 
+static struct CRYPTO_STATIC_MUTEX g_crl_sort_lock = CRYPTO_STATIC_MUTEX_INIT;
+
 static int def_crl_lookup(X509_CRL *crl,
 		X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer)
 	{
@@ -471,13 +476,22 @@
 	rtmp.serialNumber = serial;
 	/* Sort revoked into serial number order if not already sorted.
 	 * Do this under a lock to avoid race condition.
- 	 */
-	if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked))
+	 */
+
+	CRYPTO_STATIC_MUTEX_lock_read(&g_crl_sort_lock);
+	const int is_sorted = sk_X509_REVOKED_is_sorted(crl->crl->revoked);
+	CRYPTO_STATIC_MUTEX_unlock(&g_crl_sort_lock);
+
+	if (!is_sorted)
 		{
-		CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL);
-		sk_X509_REVOKED_sort(crl->crl->revoked);
-		CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL);
+		CRYPTO_STATIC_MUTEX_lock_write(&g_crl_sort_lock);
+		if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked))
+			{
+			sk_X509_REVOKED_sort(crl->crl->revoked);
+			}
+		CRYPTO_STATIC_MUTEX_unlock(&g_crl_sort_lock);
 		}
+
 	if (!sk_X509_REVOKED_find(crl->crl->revoked, &idx, &rtmp))
 		return 0;
 	/* Need to look for matching name */
diff --git a/src/crypto/x509/x_info.c b/src/crypto/x509/x_info.c
index 6807b24..f9e9ab8 100644
--- a/src/crypto/x509/x_info.c
+++ b/src/crypto/x509/x_info.c
@@ -77,7 +77,6 @@
         ret->enc_len=0;
         ret->enc_data=NULL;
  
-	ret->references=1;
 	ret->x509=NULL;
 	ret->crl=NULL;
 	ret->x_pkey=NULL;
@@ -86,23 +85,8 @@
 
 void X509_INFO_free(X509_INFO *x)
 	{
-	int i;
-
 	if (x == NULL) return;
 
-	i=CRYPTO_add(&x->references,-1,CRYPTO_LOCK_X509_INFO);
-#ifdef REF_PRINT
-	REF_PRINT("X509_INFO",x);
-#endif
-	if (i > 0) return;
-#ifdef REF_CHECK
-	if (i < 0)
-		{
-		fprintf(stderr,"X509_INFO_free, bad reference count\n");
-		abort();
-		}
-#endif
-
 	if (x->x509 != NULL) X509_free(x->x509);
 	if (x->crl != NULL) X509_CRL_free(x->crl);
 	if (x->x_pkey != NULL) X509_PKEY_free(x->x_pkey);
diff --git a/src/crypto/x509/x_pkey.c b/src/crypto/x509/x_pkey.c
index 5acbe5b..5bc6415 100644
--- a/src/crypto/x509/x_pkey.c
+++ b/src/crypto/x509/x_pkey.c
@@ -73,7 +73,6 @@
 		goto err;
 		}
 	memset(ret, 0, sizeof(X509_PKEY));
-	ret->references=1;
 
 	ret->enc_algor = X509_ALGOR_new();
 	if (ret->enc_algor == NULL)
@@ -91,13 +90,8 @@
 
 void X509_PKEY_free(X509_PKEY *x)
 	{
-	int i;
-
 	if (x == NULL) return;
 
-	i=CRYPTO_add(&x->references,-1,CRYPTO_LOCK_X509_PKEY);
-	if (i > 0) return;
-
 	if (x->enc_algor != NULL) X509_ALGOR_free(x->enc_algor);
 	if (x->enc_pkey != NULL) M_ASN1_OCTET_STRING_free(x->enc_pkey);
 	if (x->dec_pkey != NULL)EVP_PKEY_free(x->dec_pkey);
diff --git a/src/crypto/x509/x_pubkey.c b/src/crypto/x509/x_pubkey.c
index d6512ae..c2e0863 100644
--- a/src/crypto/x509/x_pubkey.c
+++ b/src/crypto/x509/x_pubkey.c
@@ -64,6 +64,7 @@
 #include <openssl/x509.h>
 
 #include "../evp/internal.h"
+#include "../internal.h"
 
 
 /* Minor tweak to operation: free up EVP_PKEY */
@@ -126,16 +127,25 @@
 	return 0;
 	}
 
+/* g_pubkey_lock is used to protect the initialisation of the |pkey| member of
+ * |X509_PUBKEY| objects. Really |X509_PUBKEY| should have a |CRYPTO_once_t|
+ * inside it for this, but |CRYPTO_once_t| is private and |X509_PUBKEY| is
+ * not. */
+static struct CRYPTO_STATIC_MUTEX g_pubkey_lock = CRYPTO_STATIC_MUTEX_INIT;
+
 EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
 	{
 	EVP_PKEY *ret=NULL;
 
 	if (key == NULL) goto error;
 
+	CRYPTO_STATIC_MUTEX_lock_read(&g_pubkey_lock);
 	if (key->pkey != NULL)
 		{
+		CRYPTO_STATIC_MUTEX_unlock(&g_pubkey_lock);
 		return EVP_PKEY_up_ref(key->pkey);
 		}
+	CRYPTO_STATIC_MUTEX_unlock(&g_pubkey_lock);
 
 	if (key->public_key == NULL) goto error;
 
@@ -166,17 +176,17 @@
 		}
 
 	/* Check to see if another thread set key->pkey first */
-	CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY);
+	CRYPTO_STATIC_MUTEX_lock_write(&g_pubkey_lock);
 	if (key->pkey)
 		{
-		CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
+		CRYPTO_STATIC_MUTEX_unlock(&g_pubkey_lock);
 		EVP_PKEY_free(ret);
 		ret = key->pkey;
 		}
 	else
 		{
 		key->pkey = ret;
-		CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
+		CRYPTO_STATIC_MUTEX_unlock(&g_pubkey_lock);
 		}
 
 	return EVP_PKEY_up_ref(ret);
diff --git a/src/crypto/x509/x_req.c b/src/crypto/x509/x_req.c
index 8bf4613..3d30129 100644
--- a/src/crypto/x509/x_req.c
+++ b/src/crypto/x509/x_req.c
@@ -102,7 +102,7 @@
 
 IMPLEMENT_ASN1_FUNCTIONS(X509_REQ_INFO)
 
-ASN1_SEQUENCE_ref(X509_REQ, 0, CRYPTO_LOCK_X509_REQ) = {
+ASN1_SEQUENCE_ref(X509_REQ, 0) = {
 	ASN1_SIMPLE(X509_REQ, req_info, X509_REQ_INFO),
 	ASN1_SIMPLE(X509_REQ, sig_alg, X509_ALGOR),
 	ASN1_SIMPLE(X509_REQ, signature, ASN1_BIT_STRING)
diff --git a/src/crypto/x509/x_x509.c b/src/crypto/x509/x_x509.c
index 234494d..c975dd3 100644
--- a/src/crypto/x509/x_x509.c
+++ b/src/crypto/x509/x_x509.c
@@ -131,7 +131,7 @@
 
 }
 
-ASN1_SEQUENCE_ref(X509, x509_cb, CRYPTO_LOCK_X509) = {
+ASN1_SEQUENCE_ref(X509, x509_cb) = {
 	ASN1_SIMPLE(X509, cert_info, X509_CINF),
 	ASN1_SIMPLE(X509, sig_alg, X509_ALGOR),
 	ASN1_SIMPLE(X509, signature, ASN1_BIT_STRING)
@@ -142,7 +142,7 @@
 
 X509 *X509_up_ref(X509 *x)
 	{
-	CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
+	CRYPTO_refcount_inc(&x->references);
 	return x;
 	}
 
diff --git a/src/crypto/x509v3/CMakeLists.txt b/src/crypto/x509v3/CMakeLists.txt
index ffa5a4a..c7e6054 100644
--- a/src/crypto/x509v3/CMakeLists.txt
+++ b/src/crypto/x509v3/CMakeLists.txt
@@ -47,6 +47,8 @@
   v3name_test
 
   v3nametest.c
+
+  $<TARGET_OBJECTS:test_support>
 )
 
 target_link_libraries(v3name_test crypto)
@@ -55,6 +57,8 @@
   tab_test
 
   tabtest.c
+
+  $<TARGET_OBJECTS:test_support>
 )
 
 target_link_libraries(tab_test crypto)
diff --git a/src/crypto/x509v3/pcy_cache.c b/src/crypto/x509v3/pcy_cache.c
index 5d59c00..08f20aa 100644
--- a/src/crypto/x509v3/pcy_cache.c
+++ b/src/crypto/x509v3/pcy_cache.c
@@ -60,6 +60,7 @@
 #include <openssl/x509v3.h>
 
 #include "pcy_int.h"
+#include "../internal.h"
 
 
 static int policy_data_cmp(const X509_POLICY_DATA **a,
@@ -243,18 +244,30 @@
 	OPENSSL_free(cache);
 	}
 
+/* g_x509_policy_cache_lock is used to protect against concurrent calls to
+ * |policy_cache_new|. Ideally this would be done with a |CRYPTO_once_t|
+ * in the |X509| structure, but |CRYPTO_once_t| isn't public. */
+static struct CRYPTO_STATIC_MUTEX g_x509_policy_cache_lock =
+    CRYPTO_STATIC_MUTEX_INIT;
+
 const X509_POLICY_CACHE *policy_cache_set(X509 *x)
 	{
+	X509_POLICY_CACHE *cache;
 
+	CRYPTO_STATIC_MUTEX_lock_read(&g_x509_policy_cache_lock);
+	cache = x->policy_cache;
+	CRYPTO_STATIC_MUTEX_unlock(&g_x509_policy_cache_lock);
+
+	if (cache != NULL)
+		return cache;
+
+	CRYPTO_STATIC_MUTEX_lock_write(&g_x509_policy_cache_lock);
 	if (x->policy_cache == NULL)
-		{
-		CRYPTO_w_lock(CRYPTO_LOCK_X509);
-			policy_cache_new(x);
-		CRYPTO_w_unlock(CRYPTO_LOCK_X509);
-		}
+		policy_cache_new(x);
+	cache = x->policy_cache;
+	CRYPTO_STATIC_MUTEX_unlock(&g_x509_policy_cache_lock);
 
-	return x->policy_cache;
-
+	return cache;
 	}
 
 X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache,
diff --git a/src/crypto/x509v3/v3_purp.c b/src/crypto/x509v3/v3_purp.c
index 3f175c9..8ae8a06 100644
--- a/src/crypto/x509v3/v3_purp.c
+++ b/src/crypto/x509v3/v3_purp.c
@@ -67,6 +67,8 @@
 #include <openssl/x509_vfy.h>
 #include <openssl/x509v3.h>
 
+#include "../internal.h"
+
 
 static void x509v3_cache_extensions(X509 *x);
 
@@ -114,9 +116,7 @@
 	int idx;
 	const X509_PURPOSE *pt;
 	if(!(x->ex_flags & EXFLAG_SET)) {
-		CRYPTO_w_lock(CRYPTO_LOCK_X509);
 		x509v3_cache_extensions(x);
-		CRYPTO_w_unlock(CRYPTO_LOCK_X509);
 	}
 	if(id == -1) return 1;
 	idx = X509_PURPOSE_get_by_id(id);
@@ -367,6 +367,15 @@
 		setup_dp(x, sk_DIST_POINT_value(x->crldp, i));
 	}
 
+/* g_x509_cache_extensions_lock is used to protect against concurrent calls to
+ * |x509v3_cache_extensions|. Ideally this would be done with a |CRYPTO_once_t|
+ * in the |X509| structure, but |CRYPTO_once_t| isn't public.
+ *
+ * Note: it's not entirely clear whether this lock is needed. Not all paths to
+ * this function took a lock in OpenSSL. */
+static struct CRYPTO_STATIC_MUTEX g_x509_cache_extensions_lock =
+    CRYPTO_STATIC_MUTEX_INIT;
+
 static void x509v3_cache_extensions(X509 *x)
 {
 	BASIC_CONSTRAINTS *bs;
@@ -377,7 +386,15 @@
 	X509_EXTENSION *ex;
 	size_t i;
 	int j;
-	if(x->ex_flags & EXFLAG_SET) return;
+
+	CRYPTO_STATIC_MUTEX_lock_write(&g_x509_cache_extensions_lock);
+
+	if(x->ex_flags & EXFLAG_SET)
+		{
+		CRYPTO_STATIC_MUTEX_unlock(&g_x509_cache_extensions_lock);
+		return;
+		}
+
 	X509_digest(x, EVP_sha1(), x->sha1_hash, NULL);
 	/* V1 should mean no extensions ... */
 	if(!X509_get_version(x)) x->ex_flags |= EXFLAG_V1;
@@ -501,6 +518,8 @@
 			}
 		}
 	x->ex_flags |= EXFLAG_SET;
+
+	CRYPTO_STATIC_MUTEX_unlock(&g_x509_cache_extensions_lock);
 }
 
 /* CA checks common to all purposes
@@ -544,9 +563,7 @@
 int X509_check_ca(X509 *x)
 {
 	if(!(x->ex_flags & EXFLAG_SET)) {
-		CRYPTO_w_lock(CRYPTO_LOCK_X509);
 		x509v3_cache_extensions(x);
-		CRYPTO_w_unlock(CRYPTO_LOCK_X509);
 	}
 
 	return check_ca(x);
diff --git a/src/crypto/x509v3/v3_utl.c b/src/crypto/x509v3/v3_utl.c
index d79f0de..77fc65c 100644
--- a/src/crypto/x509v3/v3_utl.c
+++ b/src/crypto/x509v3/v3_utl.c
@@ -263,7 +263,10 @@
 	/* We are going to modify the line so copy it first */
 	linebuf = BUF_strdup(line);
 	if (linebuf == NULL)
+		{
+		OPENSSL_PUT_ERROR(X509V3, X509V3_parse_list, ERR_R_MALLOC_FAILURE);
 		goto err;
+		}
 	state = HDR_NAME;
 	ntmp = NULL;
 	/* Go through all characters */
@@ -751,7 +754,7 @@
 		if (p[i] == '*')
 			{
 			int atstart = (state & LABEL_START);
-			int atend = (i == len - 1 || p[i+i] == '.');
+			int atend = (i == len - 1 || p[i+1] == '.');
 			/*
 			 * At most one wildcard per pattern.
 			 * No wildcards in IDNA labels.
diff --git a/src/include/openssl/asn1t.h b/src/include/openssl/asn1t.h
index 6c91134..0f2560b 100644
--- a/src/include/openssl/asn1t.h
+++ b/src/include/openssl/asn1t.h
@@ -149,19 +149,19 @@
 	ASN1_SEQUENCE_cb(tname, cb)
 
 #define ASN1_SEQUENCE_cb(tname, cb) \
-	static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
+	static const ASN1_AUX tname##_aux = {NULL, 0, 0, cb, 0}; \
 	ASN1_SEQUENCE(tname)
 
 #define ASN1_BROKEN_SEQUENCE(tname) \
-	static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \
+	static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0}; \
 	ASN1_SEQUENCE(tname)
 
-#define ASN1_SEQUENCE_ref(tname, cb, lck) \
-	static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), lck, cb, 0}; \
+#define ASN1_SEQUENCE_ref(tname, cb) \
+	static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), cb, 0}; \
 	ASN1_SEQUENCE(tname)
 
 #define ASN1_SEQUENCE_enc(tname, enc, cb) \
-	static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \
+	static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, cb, offsetof(tname, enc)}; \
 	ASN1_SEQUENCE(tname)
 
 #define ASN1_NDEF_SEQUENCE_END(tname) \
@@ -233,7 +233,7 @@
 	static const ASN1_TEMPLATE tname##_ch_tt[] 
 
 #define ASN1_CHOICE_cb(tname, cb) \
-	static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
+	static const ASN1_AUX tname##_aux = {NULL, 0, 0, cb, 0}; \
 	ASN1_CHOICE(tname)
 
 #define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname)
@@ -670,7 +670,6 @@
 	void *app_data;
 	int flags;
 	int ref_offset;		/* Offset of reference value */
-	int ref_lock;		/* Lock type to use */
 	ASN1_aux_cb *asn1_cb;
 	int enc_offset;		/* Offset of ASN1_ENCODING structure */
 } ASN1_AUX;
@@ -894,7 +893,8 @@
 
 const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, int nullerr);
 
-int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it);
+void asn1_refcount_set_one(ASN1_VALUE **pval, const ASN1_ITEM *it);
+int asn1_refcount_dec_and_test_zero(ASN1_VALUE **pval, const ASN1_ITEM *it);
 
 void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it);
 void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
diff --git a/src/include/openssl/bio.h b/src/include/openssl/bio.h
index a37077c..8724657 100644
--- a/src/include/openssl/bio.h
+++ b/src/include/openssl/bio.h
@@ -64,6 +64,7 @@
 #include <openssl/err.h> /* for ERR_print_errors_fp */
 #include <openssl/ex_data.h>
 #include <openssl/stack.h>
+#include <openssl/thread.h>
 
 #if defined(__cplusplus)
 extern "C" {
@@ -799,7 +800,7 @@
   /* num is a BIO-specific value. For example, in fd BIOs it's used to store a
    * file descriptor. */
   int num;
-  int references;
+  CRYPTO_refcount_t references;
   void *ptr;
   /* next_bio points to the next |BIO| in a chain. This |BIO| owns a reference
    * to |next_bio|. */
@@ -887,6 +888,7 @@
 #define BIO_F_file_ctrl 115
 #define BIO_F_file_read 116
 #define BIO_F_mem_write 117
+#define BIO_F_BIO_printf 118
 #define BIO_R_BAD_FOPEN_MODE 100
 #define BIO_R_BROKEN_PIPE 101
 #define BIO_R_CONNECT_ERROR 102
diff --git a/src/include/openssl/bn.h b/src/include/openssl/bn.h
index 2cd0224..ec1c8ff 100644
--- a/src/include/openssl/bn.h
+++ b/src/include/openssl/bn.h
@@ -548,15 +548,15 @@
 
 /* Random and prime number generation. */
 
-/* BN_rand sets |rnd| to a random number of length |bits|. If |top| is zero,
- * the most-significant bit will be set. If |top| is one, the two most
- * significant bits will be set.
+/* BN_rand sets |rnd| to a random number of length |bits|. If |top| is zero, the
+ * most-significant bit, if any, will be set. If |top| is one, the two most
+ * significant bits, if any, will be set.
  *
  * If |top| is -1 then no extra action will be taken and |BN_num_bits(rnd)| may
  * not equal |bits| if the most significant bits randomly ended up as zeros.
  *
- * If |bottom| is non-zero, the least-significant bit will be set. The function
- * returns one on success or zero otherwise. */
+ * If |bottom| is non-zero, the least-significant bit, if any, will be set. The
+ * function returns one on success or zero otherwise. */
 OPENSSL_EXPORT int BN_rand(BIGNUM *rnd, int bits, int top, int bottom);
 
 /* BN_pseudo_rand is an alias for |BN_rand|. */
@@ -852,6 +852,8 @@
 #define BN_F_BN_usub 122
 #define BN_F_bn_wexpand 123
 #define BN_F_mod_exp_recp 124
+#define BN_F_BN_lshift 125
+#define BN_F_BN_rshift 126
 #define BN_R_ARG2_LT_ARG3 100
 #define BN_R_BAD_RECIPROCAL 101
 #define BN_R_BIGNUM_TOO_LONG 102
diff --git a/src/include/openssl/buffer.h b/src/include/openssl/buffer.h
new file mode 100644
index 0000000..c6b721c
--- /dev/null
+++ b/src/include/openssl/buffer.h
@@ -0,0 +1,18 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+/* This header is provided in order to make compiling against code that expects
+   OpenSSL easier. */
+
+#include "buf.h"
diff --git a/src/include/openssl/bytestring.h b/src/include/openssl/bytestring.h
index e10621a..9963426 100644
--- a/src/include/openssl/bytestring.h
+++ b/src/include/openssl/bytestring.h
@@ -150,10 +150,8 @@
 
 /* CBS_get_any_asn1_element sets |*out| to contain the next ASN.1 element from
  * |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to
- * the tag number and |*out_header_len| to the length of the ASN.1 header. If
- * the element has indefinite length then |*out| will only contain the
- * header. Each of |out|, |out_tag|, and |out_header_len| may be NULL to ignore
- * the value.
+ * the tag number and |*out_header_len| to the length of the ASN.1 header. Each
+ * of |out|, |out_tag|, and |out_header_len| may be NULL to ignore the value.
  *
  * Tag numbers greater than 30 are not supported (i.e. short form only). */
 OPENSSL_EXPORT int CBS_get_any_asn1_element(CBS *cbs, CBS *out,
diff --git a/src/include/openssl/cipher.h b/src/include/openssl/cipher.h
index f1469a0..7f5fe04 100644
--- a/src/include/openssl/cipher.h
+++ b/src/include/openssl/cipher.h
@@ -520,6 +520,9 @@
   int (*cipher)(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
                 size_t inl);
 
+  /* cleanup, if non-NULL, releases memory associated with the context. It is
+   * called if |EVP_CTRL_INIT| succeeds. Note that |init| may not have been
+   * called at this point. */
   void (*cleanup)(EVP_CIPHER_CTX *);
 
   int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr);
diff --git a/src/include/openssl/des.h b/src/include/openssl/des.h
index f3804c3..6e1b0cf 100644
--- a/src/include/openssl/des.h
+++ b/src/include/openssl/des.h
@@ -131,6 +131,16 @@
                                          const DES_key_schedule *ks3,
                                          DES_cblock *ivec, int enc);
 
+/* DES_ede2_cbc_encrypt encrypts (or decrypts, if |enc| is |DES_DECRYPT|) |len|
+ * bytes from |in| to |out| with 3DES in CBC mode. With this keying option, the
+ * first and third 3DES keys are identical. Thus, this function takes only two
+ * different |DES_key_schedule|s. */
+OPENSSL_EXPORT void DES_ede2_cbc_encrypt(const uint8_t *in, uint8_t *out,
+                                         size_t len,
+                                         const DES_key_schedule *ks1,
+                                         const DES_key_schedule *ks2,
+                                         DES_cblock *ivec, int enc);
+
 
 #if defined(__cplusplus)
 }  /* extern C */
diff --git a/src/include/openssl/dh.h b/src/include/openssl/dh.h
index 60a030d..17574d5 100644
--- a/src/include/openssl/dh.h
+++ b/src/include/openssl/dh.h
@@ -137,6 +137,10 @@
 /* DH_size returns the number of bytes in the DH group's prime. */
 OPENSSL_EXPORT int DH_size(const DH *dh);
 
+/* DH_num_bits returns the minimum number of bits needed to represent the
+ * absolute value of the DH group's prime. */
+OPENSSL_EXPORT unsigned DH_num_bits(const DH *dh);
+
 #define DH_CHECK_P_NOT_PRIME 0x01
 #define DH_CHECK_P_NOT_SAFE_PRIME 0x02
 #define DH_CHECK_UNABLE_TO_CHECK_GENERATOR 0x04
@@ -249,7 +253,7 @@
   BIGNUM *counter;
 
   int flags;
-  int references;
+  CRYPTO_refcount_t references;
   CRYPTO_EX_DATA ex_data;
 };
 
diff --git a/src/include/openssl/digest.h b/src/include/openssl/digest.h
index 8285dce..2ea4ec4 100644
--- a/src/include/openssl/digest.h
+++ b/src/include/openssl/digest.h
@@ -134,7 +134,7 @@
 OPENSSL_EXPORT int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
 
 /* EVP_DigestUpdate hashes |len| bytes from |data| into the hashing operation
- * in |ctx|. It returns one on success and zero otherwise. */
+ * in |ctx|. It returns one. */
 OPENSSL_EXPORT int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data,
                                     size_t len);
 
@@ -144,10 +144,9 @@
 
 /* EVP_DigestFinal_ex finishes the digest in |ctx| and writes the output to
  * |md_out|. At most |EVP_MAX_MD_SIZE| bytes are written. If |out_size| is not
- * NULL then |*out_size| is set to the number of bytes written. It returns one
- * on success and zero otherwise. After this call, the hash cannot be updated
- * or finished again until |EVP_DigestInit_ex| is called to start another
- * hashing operation. */
+ * NULL then |*out_size| is set to the number of bytes written. It returns one.
+ * After this call, the hash cannot be updated or finished again until
+ * |EVP_DigestInit_ex| is called to start another hashing operation. */
 OPENSSL_EXPORT int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, uint8_t *md_out,
                                       unsigned int *out_size);
 
@@ -205,6 +204,10 @@
  * compatibility with OpenSSL. */
 OPENSSL_EXPORT int EVP_add_digest(const EVP_MD *digest);
 
+/* EVP_get_cipherbyname returns an |EVP_MD| given a human readable name in
+ * |name|, or NULL if the name is unknown. */
+OPENSSL_EXPORT const EVP_MD *EVP_get_digestbyname(const char *);
+
 
 /* Digest operation accessors. */
 
@@ -225,18 +228,6 @@
  * |ctx|. */
 OPENSSL_EXPORT int EVP_MD_CTX_type(const EVP_MD_CTX *ctx);
 
-/* EVP_MD_CTX_set_flags ORs |flags| into the flags member of |ctx|. */
-OPENSSL_EXPORT void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, uint32_t flags);
-
-/* EVP_MD_CTX_clear_flags clears any bits from the flags member of |ctx| that
- * are set in |flags|. */
-OPENSSL_EXPORT void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, uint32_t flags);
-
-/* EVP_MD_CTX_test_flags returns the AND of |flags| and the flags member of
- * |ctx|. */
-OPENSSL_EXPORT uint32_t EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx,
-                                              uint32_t flags);
-
 
 struct evp_md_pctx_ops;
 
@@ -251,7 +242,7 @@
   /* update is usually copied from |digest->update| but can differ in some
    * cases, i.e. HMAC.
    * TODO(davidben): Remove this hook once |EVP_PKEY_HMAC| is gone. */
-  int (*update)(EVP_MD_CTX *ctx, const void *data, size_t count);
+  void (*update)(EVP_MD_CTX *ctx, const void *data, size_t count);
 
   /* pctx is an opaque (at this layer) pointer to additional context that
    * EVP_PKEY functions may store in this object. */
@@ -262,11 +253,6 @@
   const struct evp_md_pctx_ops *pctx_ops;
 } /* EVP_MD_CTX */;
 
-/* EVP_MD_CTX_FLAG_NO_INIT causes the |EVP_MD|'s |init| function not to be
- * called, the |update| member not to be copied from the |EVP_MD| in
- * |EVP_DigestInit_ex| and for |md_data| not to be initialised. */
-#define EVP_MD_CTX_FLAG_NO_INIT 1
-
 
 #if defined(__cplusplus)
 }  /* extern C */
diff --git a/src/include/openssl/dsa.h b/src/include/openssl/dsa.h
index 2271915..7274e4c 100644
--- a/src/include/openssl/dsa.h
+++ b/src/include/openssl/dsa.h
@@ -354,7 +354,7 @@
   /* Normally used to cache montgomery values */
   CRYPTO_MUTEX method_mont_p_lock;
   BN_MONT_CTX *method_mont_p;
-  int references;
+  CRYPTO_refcount_t references;
   CRYPTO_EX_DATA ex_data;
   DSA_METHOD *meth;
   /* functional reference if 'meth' is ENGINE-provided */
diff --git a/src/include/openssl/ec.h b/src/include/openssl/ec.h
index 617cb19..25b4551 100644
--- a/src/include/openssl/ec.h
+++ b/src/include/openssl/ec.h
@@ -288,7 +288,11 @@
 
 /* EC_GROUP_new_curve_GFp creates a new, arbitrary elliptic curve group based
  * on the equation y² = x³ + a·x + b. It returns the new group or NULL on
- * error. */
+ * error.
+ *
+ * |EC_GROUP|s returned by this function will always compare as unequal via
+ * |EC_GROUP_cmp| (even to themselves). |EC_GROUP_get_curve_name| will always
+ * return |NID_undef|. */
 OPENSSL_EXPORT EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p,
                                                 const BIGNUM *a,
                                                 const BIGNUM *b, BN_CTX *ctx);
diff --git a/src/include/openssl/engine.h b/src/include/openssl/engine.h
index da242f6..d3d278a 100644
--- a/src/include/openssl/engine.h
+++ b/src/include/openssl/engine.h
@@ -93,7 +93,7 @@
 /* openssl_method_common_st contains the common part of all method structures.
  * This must be the first member of all method structures. */
 struct openssl_method_common_st {
-  int references;
+  int references;  /* dummy – not used. */
   char is_static;
 };
 
diff --git a/src/include/openssl/err.h b/src/include/openssl/err.h
index e591534..30dc4af 100644
--- a/src/include/openssl/err.h
+++ b/src/include/openssl/err.h
@@ -269,11 +269,11 @@
 OPENSSL_EXPORT void ERR_clear_error(void);
 
 /* ERR_remove_thread_state clears the error queue for the current thread if
- * |tid| is NULL. Otherwise it does nothing because it's no longer possible to
- * delete the error queue for other threads.
+ * |tid| is NULL. Otherwise it calls |assert(0)|, because it's no longer
+ * possible to delete the error queue for other threads.
  *
  * Error queues are thread-local data and are deleted automatically. You do not
- * need to call this function. See |ERR_clear_error|. */
+ * need to call this function. Use |ERR_clear_error|. */
 OPENSSL_EXPORT void ERR_remove_thread_state(const CRYPTO_THREADID *tid);
 
 
@@ -285,6 +285,12 @@
 OPENSSL_EXPORT int ERR_get_next_error_library(void);
 
 
+/* Deprecated functions. */
+
+/* |ERR_remove_state| calls |ERR_clear_error|. */
+OPENSSL_EXPORT void ERR_remove_state(unsigned long pid);
+
+
 /* Private functions. */
 
 /* ERR_clear_system_error clears the system's error value (i.e. errno). */
@@ -496,15 +502,6 @@
 #define OPENSSL_DECLARE_ERROR_FUNCTION(lib, function_name)
 
 
-/* Android compatibility section.
- *
- * These functions are declared, temporarily, for Android because
- * wpa_supplicant will take a little time to sync with upstream. Outside of
- * Android they'll have no definition. */
-
-OPENSSL_EXPORT void ERR_remove_state(unsigned long pid);
-
-
 #if defined(__cplusplus)
 } /* extern C */
 #endif
diff --git a/src/include/openssl/evp.h b/src/include/openssl/evp.h
index 54ad4be..490a951 100644
--- a/src/include/openssl/evp.h
+++ b/src/include/openssl/evp.h
@@ -59,6 +59,8 @@
 
 #include <openssl/base.h>
 
+#include <openssl/thread.h>
+
 /* OpenSSL included digest and cipher functions in this header so we include
  * them for users that still expect that.
  *
@@ -239,8 +241,7 @@
                                       EVP_PKEY *pkey);
 
 /* EVP_DigestSignUpdate appends |len| bytes from |data| to the data which will
- * be signed in |EVP_DigestSignFinal|. It returns one on success and zero
- * otherwise. */
+ * be signed in |EVP_DigestSignFinal|. It returns one. */
 OPENSSL_EXPORT int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data,
                                         size_t len);
 
@@ -291,8 +292,7 @@
                                                      EVP_PKEY *pkey);
 
 /* 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. */
+ * will be verified by |EVP_DigestVerifyFinal|. It returns one. */
 OPENSSL_EXPORT int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data,
                                           size_t len);
 
@@ -664,6 +664,12 @@
 /* OpenSSL_add_all_algorithms does nothing. */
 OPENSSL_EXPORT void OpenSSL_add_all_algorithms(void);
 
+/* OpenSSL_add_all_ciphers does nothing. */
+OPENSSL_EXPORT void OpenSSL_add_all_ciphers(void);
+
+/* OpenSSL_add_all_digests does nothing. */
+OPENSSL_EXPORT void OpenSSL_add_all_digests(void);
+
 /* EVP_cleanup does nothing. */
 OPENSSL_EXPORT void EVP_cleanup(void);
 
@@ -678,7 +684,7 @@
     ENGINE **pengine, const char *name, size_t len);
 
 struct evp_pkey_st {
-  int references;
+  CRYPTO_refcount_t references;
 
   /* type contains one of the EVP_PKEY_* values or NID_undef and determines
    * which element (if any) of the |pkey| union is valid. */
diff --git a/src/include/openssl/hmac.h b/src/include/openssl/hmac.h
index 89cdf8f..e521212 100644
--- a/src/include/openssl/hmac.h
+++ b/src/include/openssl/hmac.h
@@ -106,7 +106,7 @@
                                 const EVP_MD *md, ENGINE *impl);
 
 /* HMAC_Update hashes |data_len| bytes from |data| into the current HMAC
- * operation in |ctx|. It returns one on success and zero on error. */
+ * operation in |ctx|. It returns one. */
 OPENSSL_EXPORT int HMAC_Update(HMAC_CTX *ctx, const uint8_t *data,
                                size_t data_len);
 
@@ -129,13 +129,6 @@
  * on error. */
 OPENSSL_EXPORT int HMAC_CTX_copy_ex(HMAC_CTX *dest, const HMAC_CTX *src);
 
-/* HMAC_CTX_set_flags ORs |flags| into the flags of the underlying digests of
- * |ctx|, which must have been setup by a call to |HMAC_Init_ex|. See
- * |EVP_MD_CTX_set_flags|.
- *
- * TODO(fork): remove? */
-OPENSSL_EXPORT void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags);
-
 
 /* Deprecated functions. */
 
diff --git a/src/include/openssl/obj_mac.h b/src/include/openssl/obj_mac.h
index b028c00..55e1cba 100644
--- a/src/include/openssl/obj_mac.h
+++ b/src/include/openssl/obj_mac.h
@@ -2351,7 +2351,7 @@
 #define OBJ_delta_crl		OBJ_id_ce,27L
 
 #define SN_issuing_distribution_point		"issuingDistributionPoint"
-#define LN_issuing_distribution_point		"X509v3 Issuing Distrubution Point"
+#define LN_issuing_distribution_point		"X509v3 Issuing Distribution Point"
 #define NID_issuing_distribution_point		770
 #define OBJ_issuing_distribution_point		OBJ_id_ce,28L
 
@@ -2576,11 +2576,6 @@
 #define NID_id_hex_multipart_message		508
 #define OBJ_id_hex_multipart_message		OBJ_mime_mhs_headings,2L
 
-#define SN_rle_compression		"RLE"
-#define LN_rle_compression		"run length compression"
-#define NID_rle_compression		124
-#define OBJ_rle_compression		1L,1L,1L,1L,666L,1L
-
 #define SN_zlib_compression		"ZLIB"
 #define LN_zlib_compression		"zlib compression"
 #define NID_zlib_compression		125
diff --git a/src/include/openssl/opensslv.h b/src/include/openssl/opensslv.h
index 22f7e25..a3555d4 100644
--- a/src/include/openssl/opensslv.h
+++ b/src/include/openssl/opensslv.h
@@ -15,4 +15,4 @@
 /* This header is provided in order to make compiling against code that expects
    OpenSSL easier. */
 
-#include "ssl.h"
+#include "crypto.h"
diff --git a/src/include/openssl/pem.h b/src/include/openssl/pem.h
index adc8d86..7756e45 100644
--- a/src/include/openssl/pem.h
+++ b/src/include/openssl/pem.h
@@ -381,13 +381,8 @@
 	DECLARE_PEM_read(name, type) \
 	DECLARE_PEM_write_cb(name, type)
 
-#if 1
 /* "userdata": new with OpenSSL 0.9.4 */
 typedef int pem_password_cb(char *buf, int size, int rwflag, void *userdata);
-#else
-/* OpenSSL 0.9.3, 0.9.3a */
-typedef int pem_password_cb(char *buf, int size, int rwflag);
-#endif
 
 OPENSSL_EXPORT int	PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher);
 OPENSSL_EXPORT int	PEM_do_header (EVP_CIPHER_INFO *cipher, unsigned char *data,long *len, pem_password_cb *callback,void *u);
@@ -415,7 +410,12 @@
 OPENSSL_EXPORT void    PEM_SignUpdate(EVP_MD_CTX *ctx,unsigned char *d,unsigned int cnt);
 OPENSSL_EXPORT int	PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen, EVP_PKEY *pkey);
 
-OPENSSL_EXPORT int	PEM_def_callback(char *buf, int num, int w, void *key);
+/* |PEM_def_callback| treats |userdata| as a string and copies it into |buf|,
+ * assuming its |size| is sufficient. Returns the length of the string, or 0
+ * if there is not enough room. If either |buf| or |userdata| is NULL, 0 is
+ * returned. Note that this is different from OpenSSL, which prompts for a
+ * password. */
+OPENSSL_EXPORT int	PEM_def_callback(char *buf, int size, int rwflag, void *userdata);
 OPENSSL_EXPORT void	PEM_proc_type(char *buf, int type);
 OPENSSL_EXPORT void	PEM_dek_info(char *buf, const char *type, int len, char *str);
 
diff --git a/src/include/openssl/rand.h b/src/include/openssl/rand.h
index 01ef4f8..300bf42 100644
--- a/src/include/openssl/rand.h
+++ b/src/include/openssl/rand.h
@@ -41,6 +41,9 @@
 /* RAND_seed does nothing. */
 OPENSSL_EXPORT void RAND_seed(const void *buf, int num);
 
+/* RAND_load_file returns a nonnegative number. */
+OPENSSL_EXPORT int RAND_load_file(const char *path, long num);
+
 /* RAND_add does nothing. */
 OPENSSL_EXPORT void RAND_add(const void *buf, int num, double entropy);
 
diff --git a/src/include/openssl/rsa.h b/src/include/openssl/rsa.h
index 2e24231..9b415d7 100644
--- a/src/include/openssl/rsa.h
+++ b/src/include/openssl/rsa.h
@@ -475,7 +475,7 @@
   BIGNUM *iqmp;
   /* be careful using this if the RSA structure is shared */
   CRYPTO_EX_DATA ex_data;
-  int references;
+  CRYPTO_refcount_t references;
   int flags;
 
   CRYPTO_MUTEX lock;
diff --git a/src/include/openssl/sha.h b/src/include/openssl/sha.h
index 0e37c45..ac2ab75 100644
--- a/src/include/openssl/sha.h
+++ b/src/include/openssl/sha.h
@@ -120,7 +120,8 @@
 OPENSSL_EXPORT int SHA224_Update(SHA256_CTX *sha, const void *data, size_t len);
 
 /* SHA224_Final adds the final padding to |sha| and writes the resulting digest
- * to |md|, which must have at least |SHA224_DIGEST_LENGTH| bytes of space. */
+ * to |md|, which must have at least |SHA224_DIGEST_LENGTH| bytes of space. It
+ * returns one on success and zero on programmer error. */
 OPENSSL_EXPORT int SHA224_Final(uint8_t *md, SHA256_CTX *sha);
 
 /* SHA224 writes the digest of |len| bytes from |data| to |out| and returns
@@ -144,7 +145,8 @@
 OPENSSL_EXPORT int SHA256_Update(SHA256_CTX *sha, const void *data, size_t len);
 
 /* SHA256_Final adds the final padding to |sha| and writes the resulting digest
- * to |md|, which must have at least |SHA256_DIGEST_LENGTH| bytes of space. */
+ * to |md|, which must have at least |SHA256_DIGEST_LENGTH| bytes of space. It
+ * returns one on success and zero on programmer error. */
 OPENSSL_EXPORT int SHA256_Final(uint8_t *md, SHA256_CTX *sha);
 
 /* SHA256 writes the digest of |len| bytes from |data| to |out| and returns
@@ -179,7 +181,8 @@
 OPENSSL_EXPORT int SHA384_Update(SHA512_CTX *sha, const void *data, size_t len);
 
 /* SHA384_Final adds the final padding to |sha| and writes the resulting digest
- * to |md|, which must have at least |SHA384_DIGEST_LENGTH| bytes of space. */
+ * to |md|, which must have at least |SHA384_DIGEST_LENGTH| bytes of space. It
+ * returns one on success and zero on programmer error. */
 OPENSSL_EXPORT int SHA384_Final(uint8_t *md, SHA512_CTX *sha);
 
 /* SHA384 writes the digest of |len| bytes from |data| to |out| and returns
@@ -207,7 +210,8 @@
 OPENSSL_EXPORT int SHA512_Update(SHA512_CTX *sha, const void *data, size_t len);
 
 /* SHA512_Final adds the final padding to |sha| and writes the resulting digest
- * to |md|, which must have at least |SHA512_DIGEST_LENGTH| bytes of space. */
+ * to |md|, which must have at least |SHA512_DIGEST_LENGTH| bytes of space. It
+ * returns one on success and zero on programmer error. */
 OPENSSL_EXPORT int SHA512_Final(uint8_t *md, SHA512_CTX *sha);
 
 /* SHA512 writes the digest of |len| bytes from |data| to |out| and returns
diff --git a/src/include/openssl/ssl.h b/src/include/openssl/ssl.h
index b746007..217dbaf 100644
--- a/src/include/openssl/ssl.h
+++ b/src/include/openssl/ssl.h
@@ -150,15 +150,13 @@
 #include <openssl/hmac.h>
 #include <openssl/lhash.h>
 #include <openssl/pem.h>
+#include <openssl/thread.h>
 #include <openssl/x509.h>
 
 #if !defined(OPENSSL_WINDOWS)
 #include <sys/time.h>
 #endif
 
-/* Some code expected to get the threading functions by including ssl.h. */
-#include <openssl/thread.h>
-
 /* wpa_supplicant expects to get the version functions from ssl.h */
 #include <openssl/crypto.h>
 
@@ -181,28 +179,6 @@
 OPENSSL_EXPORT int SSL_library_init(void);
 
 
-/* Protocol version constants */
-
-#define SSL3_VERSION 0x0300
-#define SSL3_VERSION_MAJOR 0x03
-#define SSL3_VERSION_MINOR 0x00
-
-#define TLS1_2_VERSION 0x0303
-#define TLS1_2_VERSION_MAJOR 0x03
-#define TLS1_2_VERSION_MINOR 0x03
-
-#define TLS1_1_VERSION 0x0302
-#define TLS1_1_VERSION_MAJOR 0x03
-#define TLS1_1_VERSION_MINOR 0x02
-
-#define TLS1_VERSION 0x0301
-#define TLS1_VERSION_MAJOR 0x03
-#define TLS1_VERSION_MINOR 0x01
-
-#define DTLS1_VERSION 0xFEFF
-#define DTLS1_2_VERSION 0xFEFD
-
-
 /* Cipher suites. */
 
 /* An SSL_CIPHER represents a cipher suite. */
@@ -263,8 +239,9 @@
 OPENSSL_EXPORT const char *SSL_CIPHER_get_kx_name(const SSL_CIPHER *cipher);
 
 /* SSL_CIPHER_get_rfc_name returns a newly-allocated string with the standard
- * name for |cipher|. For example, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256". The
- * caller is responsible for calling |OPENSSL_free| on the result. */
+ * name for |cipher| or NULL on error. For example,
+ * "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256". The caller is responsible for
+ * calling |OPENSSL_free| on the result. */
 OPENSSL_EXPORT char *SSL_CIPHER_get_rfc_name(const SSL_CIPHER *cipher);
 
 /* SSL_CIPHER_get_bits returns the strength, in bits, of |cipher|. If
@@ -274,6 +251,273 @@
                                        int *out_alg_bits);
 
 
+/* SSL contexts. */
+
+/* An SSL_METHOD selects whether to use TLS or DTLS. */
+typedef struct ssl_method_st SSL_METHOD;
+
+/* TLS_method is the |SSL_METHOD| used for TLS (and SSLv3) connections. */
+OPENSSL_EXPORT const SSL_METHOD *TLS_method(void);
+
+/* DTLS_method is the |SSL_METHOD| used for DTLS connections. */
+OPENSSL_EXPORT const SSL_METHOD *DTLS_method(void);
+
+/* SSL_CTX_new returns a newly-allocated |SSL_CTX| with default settings or NULL
+ * on error. An |SSL_CTX| manages shared state and configuration between
+ * multiple TLS or DTLS connections. */
+OPENSSL_EXPORT SSL_CTX *SSL_CTX_new(const SSL_METHOD *method);
+
+/* SSL_CTX_free releases memory associated with |ctx|. */
+OPENSSL_EXPORT void SSL_CTX_free(SSL_CTX *ctx);
+
+
+/* SSL connections. */
+
+/* SSL_new returns a newly-allocated |SSL| using |ctx| or NULL on error. An
+ * |SSL| object represents a single TLS or DTLS connection. It inherits settings
+ * from |ctx| at the time of creation. Settings may also be individually
+ * configured on the connection.
+ *
+ * On creation, an |SSL| is not configured to be either a client or server. Call
+ * |SSL_set_connect_state| or |SSL_set_accept_state| to set this. */
+OPENSSL_EXPORT SSL *SSL_new(SSL_CTX *ctx);
+
+/* SSL_free releases memory associated with |ssl|. */
+OPENSSL_EXPORT void SSL_free(SSL *ssl);
+
+/* SSL_set_connect_state configures |ssl| to be a client. */
+OPENSSL_EXPORT void SSL_set_connect_state(SSL *ssl);
+
+/* SSL_set_accept_state configures |ssl| to be a server. */
+OPENSSL_EXPORT void SSL_set_accept_state(SSL *ssl);
+
+
+/* Protocol versions. */
+
+#define SSL3_VERSION_MAJOR 0x03
+
+#define SSL3_VERSION 0x0300
+#define TLS1_VERSION 0x0301
+#define TLS1_1_VERSION 0x0302
+#define TLS1_2_VERSION 0x0303
+
+#define DTLS1_VERSION 0xfeff
+#define DTLS1_2_VERSION 0xfefd
+
+/* SSL_CTX_set_min_version sets the minimum protocol version for |ctx| to
+ * |version|. */
+OPENSSL_EXPORT void SSL_CTX_set_min_version(SSL_CTX *ctx, uint16_t version);
+
+/* SSL_CTX_set_max_version sets the maximum protocol version for |ctx| to
+ * |version|. */
+OPENSSL_EXPORT void SSL_CTX_set_max_version(SSL_CTX *ctx, uint16_t version);
+
+/* SSL_set_min_version sets the minimum protocol version for |ssl| to
+ * |version|. */
+OPENSSL_EXPORT void SSL_set_min_version(SSL *ssl, uint16_t version);
+
+/* SSL_set_max_version sets the maximum protocol version for |ssl| to
+ * |version|. */
+OPENSSL_EXPORT void SSL_set_max_version(SSL *ssl, uint16_t version);
+
+
+/* Options.
+ *
+ * Options configure protocol behavior. */
+
+/* SSL_OP_LEGACY_SERVER_CONNECT allows initial connections to servers that don't
+ * support the renegotiation_info extension (RFC 5746). It is on by default. */
+#define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004L
+
+/* SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER allows for record sizes |SSL3_RT_MAX_EXTRA|
+ * bytes above the maximum record size. */
+#define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x00000020L
+
+/* SSL_OP_TLS_D5_BUG accepts an RSAClientKeyExchange in TLS encoded as in SSL3
+ * (i.e. without a length prefix). */
+#define SSL_OP_TLS_D5_BUG 0x00000100L
+
+/* SSL_OP_ALL enables the above bug workarounds that are enabled by many
+ * consumers.
+ * TODO(davidben): Determine which of the remaining may be removed now. */
+#define SSL_OP_ALL 0x00000BFFL
+
+/* SSL_OP_NO_QUERY_MTU, in DTLS, disables querying the MTU from the underlying
+ * |BIO|. Instead, the MTU is configured with |SSL_set_mtu|. */
+#define SSL_OP_NO_QUERY_MTU 0x00001000L
+
+/* SSL_OP_NO_TICKET disables session ticket support (RFC 4507). */
+#define SSL_OP_NO_TICKET 0x00004000L
+
+/* SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION permits unsafe legacy renegotiation
+ * without renegotiation_info (RFC 5746) support. */
+#define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x00040000L
+
+/* SSL_OP_CIPHER_SERVER_PREFERENCE configures servers to select ciphers and
+ * ECDHE curves according to the server's preferences instead of the
+ * client's. */
+#define SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000L
+
+/* The following flags toggle individual protocol versions. This is deprecated.
+ * Use |SSL_CTX_set_min_version| and |SSL_CTX_set_max_version| instead. */
+#define SSL_OP_NO_SSLv3 0x02000000L
+#define SSL_OP_NO_TLSv1 0x04000000L
+#define SSL_OP_NO_TLSv1_2 0x08000000L
+#define SSL_OP_NO_TLSv1_1 0x10000000L
+#define SSL_OP_NO_DTLSv1 SSL_OP_NO_TLSv1
+#define SSL_OP_NO_DTLSv1_2 SSL_OP_NO_TLSv1_2
+
+/* The following flags do nothing and are included only to make it easier to
+ * compile code with BoringSSL. */
+#define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0
+#define SSL_OP_MICROSOFT_SESS_ID_BUG 0
+#define SSL_OP_NETSCAPE_CHALLENGE_BUG 0
+#define SSL_OP_NO_COMPRESSION 0
+#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
+#define SSL_OP_NO_SSLv2 0
+#define SSL_OP_SINGLE_DH_USE 0
+#define SSL_OP_SINGLE_ECDH_USE 0
+#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0
+#define SSL_OP_TLS_BLOCK_PADDING_BUG 0
+#define SSL_OP_TLS_ROLLBACK_BUG 0
+
+/* SSL_CTX_set_options enables all options set in |options| (which should be one
+ * or more of the |SSL_OP_*| values, ORed together) in |ctx|. It returns a
+ * bitmask representing the resulting enabled options. */
+OPENSSL_EXPORT uint32_t SSL_CTX_set_options(SSL_CTX *ctx, uint32_t options);
+
+/* SSL_CTX_clear_options disables all options set in |options| (which should be
+ * one or more of the |SSL_OP_*| values, ORed together) in |ctx|. It returns a
+ * bitmask representing the resulting enabled options. */
+OPENSSL_EXPORT uint32_t SSL_CTX_clear_options(SSL_CTX *ctx, uint32_t options);
+
+/* SSL_CTX_get_options returns a bitmask of |SSL_OP_*| values that represent all
+ * the options enabled for |ctx|. */
+OPENSSL_EXPORT uint32_t SSL_CTX_get_options(const SSL_CTX *ctx);
+
+/* SSL_set_options enables all options set in |options| (which should be one or
+ * more of the |SSL_OP_*| values, ORed together) in |ssl|. It returns a bitmask
+ * representing the resulting enabled options. */
+OPENSSL_EXPORT uint32_t SSL_set_options(SSL *ssl, uint32_t options);
+
+/* SSL_clear_options disables all options set in |options| (which should be one
+ * or more of the |SSL_OP_*| values, ORed together) in |ssl|. It returns a
+ * bitmask representing the resulting enabled options. */
+OPENSSL_EXPORT uint32_t SSL_clear_options(SSL *ssl, uint32_t options);
+
+/* SSL_get_options returns a bitmask of |SSL_OP_*| values that represent all the
+ * options enabled for |ssl|. */
+OPENSSL_EXPORT uint32_t SSL_get_options(const SSL *ssl);
+
+
+/* Modes.
+ *
+ * Modes configure API behavior. */
+
+/* SSL_MODE_ENABLE_PARTIAL_WRITE allows |SSL_write| to complete with a partial
+ * result when the only part of the input was written in a single record. */
+#define SSL_MODE_ENABLE_PARTIAL_WRITE 0x00000001L
+
+/* SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER allows retrying an incomplete |SSL_write|
+ * with a different buffer. However, |SSL_write| still assumes the buffer
+ * contents are unchanged. This is not the default to avoid the misconception
+ * that non-blocking |SSL_write| behaves like non-blocking |write|. */
+#define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002L
+
+/* SSL_MODE_NO_AUTO_CHAIN disables automatically building a certificate chain
+ * before sending certificates to the peer.
+ * TODO(davidben): Remove this behavior. https://crbug.com/486295. */
+#define SSL_MODE_NO_AUTO_CHAIN 0x00000008L
+
+/* SSL_MODE_ENABLE_FALSE_START allows clients to send application data before
+ * receipt of CCS and Finished. This mode enables full-handshakes to 'complete'
+ * in one RTT. See draft-bmoeller-tls-falsestart-01. */
+#define SSL_MODE_ENABLE_FALSE_START 0x00000080L
+
+/* Deprecated: SSL_MODE_HANDSHAKE_CUTTHROUGH is the same as
+ * SSL_MODE_ENABLE_FALSE_START. */
+#define SSL_MODE_HANDSHAKE_CUTTHROUGH SSL_MODE_ENABLE_FALSE_START
+
+/* SSL_MODE_CBC_RECORD_SPLITTING causes multi-byte CBC records in SSL 3.0 and
+ * TLS 1.0 to be split in two: the first record will contain a single byte and
+ * the second will contain the remainder. This effectively randomises the IV and
+ * prevents BEAST attacks. */
+#define SSL_MODE_CBC_RECORD_SPLITTING 0x00000100L
+
+/* SSL_MODE_NO_SESSION_CREATION will cause any attempts to create a session to
+ * fail with SSL_R_SESSION_MAY_NOT_BE_CREATED. This can be used to enforce that
+ * session resumption is used for a given SSL*. */
+#define SSL_MODE_NO_SESSION_CREATION 0x00000200L
+
+/* SSL_MODE_SEND_FALLBACK_SCSV sends TLS_FALLBACK_SCSV in the ClientHello.
+ * To be set only by applications that reconnect with a downgraded protocol
+ * version; see https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-05
+ * for details.
+ *
+ * DO NOT ENABLE THIS if your application attempts a normal handshake. Only use
+ * this in explicit fallback retries, following the guidance in
+ * draft-ietf-tls-downgrade-scsv-05. */
+#define SSL_MODE_SEND_FALLBACK_SCSV 0x00000400L
+
+/* The following flags do nothing and are included only to make it easier to
+ * compile code with BoringSSL. */
+#define SSL_MODE_AUTO_RETRY 0
+#define SSL_MODE_RELEASE_BUFFERS 0
+#define SSL_MODE_SEND_CLIENTHELLO_TIME 0
+#define SSL_MODE_SEND_SERVERHELLO_TIME 0
+
+/* SSL_CTX_set_mode enables all modes set in |mode| (which should be one or more
+ * of the |SSL_MODE_*| values, ORed together) in |ctx|. It returns a bitmask
+ * representing the resulting enabled modes. */
+OPENSSL_EXPORT uint32_t SSL_CTX_set_mode(SSL_CTX *ctx, uint32_t mode);
+
+/* SSL_CTX_clear_mode disables all modes set in |mode| (which should be one or
+ * more of the |SSL_MODE_*| values, ORed together) in |ctx|. It returns a
+ * bitmask representing the resulting enabled modes. */
+OPENSSL_EXPORT uint32_t SSL_CTX_clear_mode(SSL_CTX *ctx, uint32_t mode);
+
+/* SSL_CTX_get_mode returns a bitmask of |SSL_MODE_*| values that represent all
+ * the modes enabled for |ssl|. */
+OPENSSL_EXPORT uint32_t SSL_CTX_get_mode(const SSL_CTX *ctx);
+
+/* SSL_set_mode enables all modes set in |mode| (which should be one or more of
+ * the |SSL_MODE_*| values, ORed together) in |ssl|. It returns a bitmask
+ * representing the resulting enabled modes. */
+OPENSSL_EXPORT uint32_t SSL_set_mode(SSL *ssl, uint32_t mode);
+
+/* SSL_clear_mode disables all modes set in |mode| (which should be one or more
+ * of the |SSL_MODE_*| values, ORed together) in |ssl|. It returns a bitmask
+ * representing the resulting enabled modes. */
+OPENSSL_EXPORT uint32_t SSL_clear_mode(SSL *ssl, uint32_t mode);
+
+/* SSL_get_mode returns a bitmask of |SSL_MODE_*| values that represent all the
+ * modes enabled for |ssl|. */
+OPENSSL_EXPORT uint32_t SSL_get_mode(const SSL *ssl);
+
+
+/* Connection information. */
+
+/* SSL_get_tls_unique writes at most |max_out| bytes of the tls-unique value
+ * for |ssl| to |out| and sets |*out_len| to the number of bytes written. It
+ * returns one on success or zero on error. In general |max_out| should be at
+ * least 12.
+ *
+ * This function will always fail if the initial handshake has not completed.
+ * The tls-unique value will change after a renegotiation but, since
+ * renegotiations can be initiated by the server at any point, the higher-level
+ * protocol must either leave them disabled or define states in which the
+ * tls-unique value can be read.
+ *
+ * The tls-unique value is defined by
+ * https://tools.ietf.org/html/rfc5929#section-3.1. Due to a weakness in the
+ * TLS protocol, tls-unique is broken for resumed connections unless the
+ * Extended Master Secret extension is negotiated. Thus this function will
+ * return zero if |ssl| performed session resumption unless EMS was used when
+ * negotiating the original session. */
+OPENSSL_EXPORT int SSL_get_tls_unique(const SSL *ssl, uint8_t *out,
+                                      size_t *out_len, size_t max_out);
+
+
 /* Underdocumented functions.
  *
  * Functions below here haven't been touched up and may be underdocumented. */
@@ -366,7 +610,6 @@
 #define SSL_FILETYPE_ASN1 X509_FILETYPE_ASN1
 #define SSL_FILETYPE_PEM X509_FILETYPE_PEM
 
-typedef struct ssl_method_st SSL_METHOD;
 typedef struct ssl_protocol_method_st SSL_PROTOCOL_METHOD;
 typedef struct ssl_session_st SSL_SESSION;
 typedef struct tls_sigalgs_st TLS_SIGALGS;
@@ -414,7 +657,7 @@
    * not ok, we must remember the error for session reuse: */
   long verify_result; /* only for servers */
 
-  int references;
+  CRYPTO_refcount_t references;
   long timeout;
   long time;
 
@@ -424,7 +667,7 @@
 
   /* These are used to make removal of session-ids more efficient and to
    * implement a maximum cache size. */
-  struct ssl_session_st *prev, *next;
+  SSL_SESSION *prev, *next;
   char *tlsext_hostname;
   /* RFC4507 info */
   uint8_t *tlsext_tick;               /* Session ticket */
@@ -454,86 +697,6 @@
   char extended_master_secret;
 };
 
-/* SSL_OP_LEGACY_SERVER_CONNECT allows initial connection to servers that don't
- * support RI */
-#define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004L
-
-/* SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER allows for record sizes SSL3_RT_MAX_EXTRA
- * bytes above the maximum record size. */
-#define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x00000020L
-
-/* SSL_OP_TLS_D5_BUG accepts an RSAClientKeyExchange in TLS encoded as SSL3,
- * without a length prefix. */
-#define SSL_OP_TLS_D5_BUG 0x00000100L
-
-/* SSL_OP_ALL enables the above bug workarounds that should be rather harmless.
- * */
-#define SSL_OP_ALL 0x00000BFFL
-
-/* DTLS options */
-#define SSL_OP_NO_QUERY_MTU 0x00001000L
-/* Don't use RFC4507 ticket extension */
-#define SSL_OP_NO_TICKET 0x00004000L
-
-/* As server, disallow session resumption on renegotiation */
-#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0x00010000L
-/* Don't use compression even if supported */
-#define SSL_OP_NO_COMPRESSION 0x00020000L
-/* Permit unsafe legacy renegotiation */
-#define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x00040000L
-/* SSL_OP_SINGLE_ECDH_USE does nothing. */
-#define SSL_OP_SINGLE_ECDH_USE 0x00080000L
-/* SSL_OP_SINGLE_DH_USE does nothing. */
-#define SSL_OP_SINGLE_DH_USE 0x00100000L
-/* Set on servers to choose the cipher according to the server's preferences */
-#define SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000L
-/* SSL_OP_TLS_ROLLBACK_BUG does nothing. */
-#define SSL_OP_TLS_ROLLBACK_BUG 0x00800000L
-
-/* Deprecated: Use SSL_CTX_set_min_version and SSL_CTX_set_max_version
- * instead. */
-#define SSL_OP_NO_SSLv2 0x01000000L
-#define SSL_OP_NO_SSLv3 0x02000000L
-#define SSL_OP_NO_TLSv1 0x04000000L
-#define SSL_OP_NO_TLSv1_2 0x08000000L
-#define SSL_OP_NO_TLSv1_1 0x10000000L
-
-#define SSL_OP_NO_DTLSv1 SSL_OP_NO_TLSv1
-#define SSL_OP_NO_DTLSv1_2 SSL_OP_NO_TLSv1_2
-
-#define SSL_OP_NO_SSL_MASK                                                   \
-  (SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | \
-   SSL_OP_NO_TLSv1_2)
-
-/* The following flags do nothing and are included only to make it easier to
- * compile code with BoringSSL. */
-#define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0
-#define SSL_OP_MICROSOFT_SESS_ID_BUG 0
-#define SSL_OP_NETSCAPE_CHALLENGE_BUG 0
-#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0
-#define SSL_OP_TLS_BLOCK_PADDING_BUG 0
-
-/* Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success when
- * just a single record has been written): */
-#define SSL_MODE_ENABLE_PARTIAL_WRITE 0x00000001L
-/* Make it possible to retry SSL_write() with changed buffer location (buffer
- * contents must stay the same!); this is not the default to avoid the
- * misconception that non-blocking SSL_write() behaves like non-blocking
- * write(): */
-#define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002L
-/* Don't attempt to automatically build certificate chain */
-#define SSL_MODE_NO_AUTO_CHAIN 0x00000008L
-
-/* The following flags do nothing and are included only to make it easier to
- * compile code with BoringSSL. */
-#define SSL_MODE_AUTO_RETRY 0
-#define SSL_MODE_RELEASE_BUFFERS 0
-
-/* Send the current time in the Random fields of the ClientHello and
- * ServerHello records for compatibility with hypothetical implementations that
- * require it. */
-#define SSL_MODE_SEND_CLIENTHELLO_TIME 0x00000020L
-#define SSL_MODE_SEND_SERVERHELLO_TIME 0x00000040L
 
 /* Cert related flags */
 /* Many implementations ignore some aspects of the TLS standards such as
@@ -552,92 +715,6 @@
 /* Clear verification errors from queue */
 #define SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR 0x10
 
-/* SSL_MODE_ENABLE_FALSE_START allows clients to send application data before
- * receipt of CCS and Finished. This mode enables full-handshakes to 'complete'
- * in one RTT. See draft-bmoeller-tls-falsestart-01. */
-#define SSL_MODE_ENABLE_FALSE_START 0x00000080L
-
-/* Deprecated: SSL_MODE_HANDSHAKE_CUTTHROUGH is the same as
- * SSL_MODE_ENABLE_FALSE_START. */
-#define SSL_MODE_HANDSHAKE_CUTTHROUGH SSL_MODE_ENABLE_FALSE_START
-
-/* When set, TLS 1.0 and SSLv3, multi-byte, CBC records will be split in two:
- * the first record will contain a single byte and the second will contain the
- * rest of the bytes. This effectively randomises the IV and prevents BEAST
- * attacks. */
-#define SSL_MODE_CBC_RECORD_SPLITTING 0x00000100L
-
-/* SSL_MODE_NO_SESSION_CREATION will cause any attempts to create a session to
- * fail with SSL_R_SESSION_MAY_NOT_BE_CREATED. This can be used to enforce that
- * session resumption is used for a given SSL*. */
-#define SSL_MODE_NO_SESSION_CREATION 0x00000200L
-
-/* SSL_MODE_SEND_FALLBACK_SCSV sends TLS_FALLBACK_SCSV in the ClientHello.
- * To be set only by applications that reconnect with a downgraded protocol
- * version; see https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-05
- * for details.
- *
- * DO NOT ENABLE THIS if your application attempts a normal handshake. Only use
- * this in explicit fallback retries, following the guidance in
- * draft-ietf-tls-downgrade-scsv-05. */
-#define SSL_MODE_SEND_FALLBACK_SCSV 0x00000400L
-
-/* SSL_CTX_set_options enables all options set in |options| (which should be one
- * or more of the |SSL_OP_*| values, ORed together) in |ctx|. It returns a
- * bitmask representing the resulting enabled options. */
-OPENSSL_EXPORT uint32_t SSL_CTX_set_options(SSL_CTX *ctx, uint32_t options);
-
-/* SSL_CTX_clear_options disables all options set in |options| (which should be
- * one or more of the |SSL_OP_*| values, ORed together) in |ctx|. It returns a
- * bitmask representing the resulting enabled options. */
-OPENSSL_EXPORT uint32_t SSL_CTX_clear_options(SSL_CTX *ctx, uint32_t options);
-
-/* SSL_CTX_get_options returns a bitmask of |SSL_OP_*| values that represent all
- * the options enabled for |ctx|. */
-OPENSSL_EXPORT uint32_t SSL_CTX_get_options(const SSL_CTX *ctx);
-
-/* SSL_set_options enables all options set in |options| (which should be one or
- * more of the |SSL_OP_*| values, ORed together) in |ssl|. It returns a bitmask
- * representing the resulting enabled options. */
-OPENSSL_EXPORT uint32_t SSL_set_options(SSL *ssl, uint32_t options);
-
-/* SSL_clear_options disables all options set in |options| (which should be one
- * or more of the |SSL_OP_*| values, ORed together) in |ssl|. It returns a
- * bitmask representing the resulting enabled options. */
-OPENSSL_EXPORT uint32_t SSL_clear_options(SSL *ssl, uint32_t options);
-
-/* SSL_get_options returns a bitmask of |SSL_OP_*| values that represent all the
- * options enabled for |ssl|. */
-OPENSSL_EXPORT uint32_t SSL_get_options(const SSL *ssl);
-
-/* SSL_CTX_set_mode enables all modes set in |mode| (which should be one or more
- * of the |SSL_MODE_*| values, ORed together) in |ctx|. It returns a bitmask
- * representing the resulting enabled modes. */
-OPENSSL_EXPORT uint32_t SSL_CTX_set_mode(SSL_CTX *ctx, uint32_t mode);
-
-/* SSL_CTX_clear_mode disables all modes set in |mode| (which should be one or
- * more of the |SSL_MODE_*| values, ORed together) in |ctx|. It returns a
- * bitmask representing the resulting enabled modes. */
-OPENSSL_EXPORT uint32_t SSL_CTX_clear_mode(SSL_CTX *ctx, uint32_t mode);
-
-/* SSL_CTX_get_mode returns a bitmask of |SSL_MODE_*| values that represent all
- * the modes enabled for |ssl|. */
-OPENSSL_EXPORT uint32_t SSL_CTX_get_mode(const SSL_CTX *ctx);
-
-/* SSL_set_mode enables all modes set in |mode| (which should be one or more of
- * the |SSL_MODE_*| values, ORed together) in |ssl|. It returns a bitmask
- * representing the resulting enabled modes. */
-OPENSSL_EXPORT uint32_t SSL_set_mode(SSL *ssl, uint32_t mode);
-
-/* SSL_clear_mode disables all modes set in |mode| (which should be one or more
- * of the |SSL_MODE_*| values, ORed together) in |ssl|. It returns a bitmask
- * representing the resulting enabled modes. */
-OPENSSL_EXPORT uint32_t SSL_clear_mode(SSL *ssl, uint32_t mode);
-
-/* SSL_get_mode returns a bitmask of |SSL_MODE_*| values that represent all the
- * modes enabled for |ssl|. */
-OPENSSL_EXPORT uint32_t SSL_get_mode(const SSL *ssl);
-
 /* SSL_set_mtu sets the |ssl|'s MTU in DTLS to |mtu|. It returns one on success
  * and zero on failure. */
 OPENSSL_EXPORT int SSL_set_mtu(SSL *ssl, unsigned mtu);
@@ -646,22 +723,6 @@
  * renegotiation (RFC 5746) and zero otherwise. */
 OPENSSL_EXPORT int SSL_get_secure_renegotiation_support(const SSL *ssl);
 
-/* SSL_CTX_set_min_version sets the minimum protocol version for |ctx| to
- * |version|. */
-OPENSSL_EXPORT void SSL_CTX_set_min_version(SSL_CTX *ctx, uint16_t version);
-
-/* SSL_CTX_set_max_version sets the maximum protocol version for |ctx| to
- * |version|. */
-OPENSSL_EXPORT void SSL_CTX_set_max_version(SSL_CTX *ctx, uint16_t version);
-
-/* SSL_set_min_version sets the minimum protocol version for |ssl| to
- * |version|. */
-OPENSSL_EXPORT void SSL_set_min_version(SSL *ssl, uint16_t version);
-
-/* SSL_set_max_version sets the maximum protocol version for |ssl| to
- * |version|. */
-OPENSSL_EXPORT void SSL_set_max_version(SSL *ssl, uint16_t version);
-
 /* SSL_CTX_set_msg_callback installs |cb| as the message callback for |ctx|.
  * This callback will be called when sending or receiving low-level record
  * headers, complete handshake messages, ChangeCipherSpec, and alerts.
@@ -690,7 +751,7 @@
     SSL *ssl, void (*cb)(int write_p, int version, int content_type,
                          const void *buf, size_t len, SSL *ssl, void *arg));
 
-/* set_msg_callback_arg sets the |arg| parameter of the message callback. */
+/* SSL_set_msg_callback_arg sets the |arg| parameter of the message callback. */
 OPENSSL_EXPORT void SSL_set_msg_callback_arg(SSL *ssl, void *arg);
 
 /* SSL_CTX_set_keylog_bio sets configures all SSL objects attached to |ctx| to
@@ -762,7 +823,7 @@
 };
 
 DECLARE_STACK_OF(SSL_COMP)
-DECLARE_LHASH_OF(SSL_SESSION);
+DECLARE_LHASH_OF(SSL_SESSION)
 
 /* ssl_cipher_preference_list_st contains a list of SSL_CIPHERs with
  * equal-preference groups. For TLS clients, the groups are moot because the
@@ -803,6 +864,9 @@
 struct ssl_ctx_st {
   const SSL_PROTOCOL_METHOD *method;
 
+  /* lock is used to protect various operations on this object. */
+  CRYPTO_MUTEX lock;
+
   /* max_version is the maximum acceptable protocol version. If zero, the
    * maximum supported version, currently (D)TLS 1.2, is used. */
   uint16_t max_version;
@@ -819,13 +883,13 @@
    * number is known at connect time and so the cipher list can be set then. */
   struct ssl_cipher_preference_list_st *cipher_list_tls11;
 
-  struct x509_store_st /* X509_STORE */ *cert_store;
+  X509_STORE *cert_store;
   LHASH_OF(SSL_SESSION) *sessions;
   /* Most session-ids that will be cached, default is
    * SSL_SESSION_CACHE_MAX_SIZE_DEFAULT. 0 is unlimited. */
   unsigned long session_cache_size;
-  struct ssl_session_st *session_cache_head;
-  struct ssl_session_st *session_cache_tail;
+  SSL_SESSION *session_cache_head;
+  SSL_SESSION *session_cache_tail;
 
   /* handshakes_since_cache_flush is the number of successful handshakes since
    * the last cache flush. */
@@ -849,12 +913,12 @@
    * remove_session_cb is not null, it will be called when a session-id is
    * removed from the cache.  After the call, OpenSSL will SSL_SESSION_free()
    * it. */
-  int (*new_session_cb)(struct ssl_st *ssl, SSL_SESSION *sess);
-  void (*remove_session_cb)(struct ssl_ctx_st *ctx, SSL_SESSION *sess);
-  SSL_SESSION *(*get_session_cb)(struct ssl_st *ssl, uint8_t *data, int len,
+  int (*new_session_cb)(SSL *ssl, SSL_SESSION *sess);
+  void (*remove_session_cb)(SSL_CTX *ctx, SSL_SESSION *sess);
+  SSL_SESSION *(*get_session_cb)(SSL *ssl, uint8_t *data, int len,
                                  int *copy);
 
-  int references;
+  CRYPTO_refcount_t references;
 
   /* if defined, these override the X509_verify_cert() calls */
   int (*app_verify_callback)(X509_STORE_CTX *, void *);
@@ -896,7 +960,6 @@
   uint32_t max_cert_list;
 
   struct cert_st /* CERT */ *cert;
-  int read_ahead;
 
   /* callback that allows applications to peek at protocol messages */
   void (*msg_callback)(int write_p, int version, int content_type,
@@ -1038,20 +1101,20 @@
 OPENSSL_EXPORT size_t SSL_CTX_sess_number(const SSL_CTX *ctx);
 
 OPENSSL_EXPORT void SSL_CTX_sess_set_new_cb(
-    SSL_CTX *ctx, int (*new_session_cb)(struct ssl_st *ssl, SSL_SESSION *sess));
-OPENSSL_EXPORT int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(struct ssl_st *ssl,
+    SSL_CTX *ctx, int (*new_session_cb)(SSL *ssl, SSL_SESSION *sess));
+OPENSSL_EXPORT int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(SSL *ssl,
                                                             SSL_SESSION *sess);
 OPENSSL_EXPORT void SSL_CTX_sess_set_remove_cb(
     SSL_CTX *ctx,
-    void (*remove_session_cb)(struct ssl_ctx_st *ctx, SSL_SESSION *sess));
+    void (*remove_session_cb)(SSL_CTX *ctx, SSL_SESSION *sess));
 OPENSSL_EXPORT void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(
-    struct ssl_ctx_st *ctx, SSL_SESSION *sess);
+    SSL_CTX *ctx, SSL_SESSION *sess);
 OPENSSL_EXPORT void SSL_CTX_sess_set_get_cb(
     SSL_CTX *ctx,
-    SSL_SESSION *(*get_session_cb)(struct ssl_st *ssl, uint8_t *data, int len,
+    SSL_SESSION *(*get_session_cb)(SSL *ssl, uint8_t *data, int len,
                                    int *copy));
 OPENSSL_EXPORT SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(
-    struct ssl_st *ssl, uint8_t *Data, int len, int *copy);
+    SSL *ssl, uint8_t *data, int len, int *copy);
 /* SSL_magic_pending_session_ptr returns a magic SSL_SESSION* which indicates
  * that the session isn't currently unavailable. SSL_get_error will then return
  * SSL_ERROR_PENDING_SESSION and the handshake can be retried later when the
@@ -1076,16 +1139,16 @@
 
 /* SSL_enable_signed_cert_timestamps causes |ssl| (which must be the client end
  * of a connection) to request SCTs from the server. See
- * https://tools.ietf.org/html/rfc6962. Returns 1 on success. */
+ * https://tools.ietf.org/html/rfc6962. It returns one. */
 OPENSSL_EXPORT int SSL_enable_signed_cert_timestamps(SSL *ssl);
 
 /* SSL_CTX_enable_signed_cert_timestamps enables SCT requests on all client SSL
  * objects created from |ctx|. */
 OPENSSL_EXPORT void SSL_CTX_enable_signed_cert_timestamps(SSL_CTX *ctx);
 
-/* SSL_enable_signed_cert_timestamps causes |ssl| (which must be the client end
- * of a connection) to request a stapled OCSP response from the server. Returns
- * 1 on success. */
+/* SSL_enable_ocsp_stapling causes |ssl| (which must be the client end of a
+ * connection) to request a stapled OCSP response from the server. It returns
+ * one. */
 OPENSSL_EXPORT int SSL_enable_ocsp_stapling(SSL *ssl);
 
 /* SSL_CTX_enable_ocsp_stapling enables OCSP stapling on all client SSL objects
@@ -1165,7 +1228,8 @@
 
 /* SSL_set_reject_peer_renegotiations controls whether renegotiation attempts by
  * the peer are rejected. It may be set at any point in a connection's lifetime
- * to disallow future renegotiations programmatically. */
+ * to control future renegotiations programmatically. By default, renegotiations
+ * are rejected. (Renegotiations requested by a client are always rejected.) */
 OPENSSL_EXPORT void SSL_set_reject_peer_renegotiations(SSL *ssl, int reject);
 
 /* the maximum length of the buffer given to callbacks containing the resulting
@@ -1198,8 +1262,6 @@
 OPENSSL_EXPORT int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint);
 OPENSSL_EXPORT const char *SSL_get_psk_identity_hint(const SSL *s);
 OPENSSL_EXPORT const char *SSL_get_psk_identity(const SSL *s);
-OPENSSL_EXPORT void ssl_update_cache(SSL *s, int mode);
-OPENSSL_EXPORT int ssl_get_new_session(SSL *s, int session);
 
 #define SSL_NOTHING 1
 #define SSL_WRITING 2
@@ -1267,12 +1329,6 @@
    * the side is not determined. In this state, server is always false. */
   int server;
 
-
-  /* Generate a new session or reuse an old one. NB: For servers, the 'new'
-   * session may actually be a previously cached session or even the previous
-   * session unless SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set */
-  int new_session;
-
   /* quiet_shutdown is true if the connection should not send a close_notify on
    * shutdown. */
   int quiet_shutdown;
@@ -1295,9 +1351,6 @@
   struct ssl3_state_st *s3;  /* SSLv3 variables */
   struct dtls1_state_st *d1; /* DTLSv1 variables */
 
-  int read_ahead; /* Read as many input bytes as possible
-                   * (for non-blocking reads) */
-
   /* callback that allows applications to peek at protocol messages */
   void (*msg_callback)(int write_p, int version, int content_type,
                        const void *buf, size_t len, SSL *ssl, void *arg);
@@ -1415,18 +1468,14 @@
   uint8_t *alpn_client_proto_list;
   unsigned alpn_client_proto_list_len;
 
-  int renegotiate; /* 1 if we are renegotiating.
-                    * 2 if we are a server and are inside a handshake
-                    * (i.e. not just sending a HelloRequest) */
-
   /* fastradio_padding, if true, causes ClientHellos to be padded to 1024
    * bytes. This ensures that the cellular radio is fast forwarded to DCH (high
    * data rate) state in 3G networks. */
   char fastradio_padding;
 
-  /* reject_peer_renegotiations, if one, causes causes renegotiation attempts
-   * from the peer to be rejected with a fatal error. */
-  char reject_peer_renegotiations;
+  /* accept_peer_renegotiations, if one, accepts renegotiation attempts from the
+   * peer. Otherwise, they will be rejected with a fatal error. */
+  char accept_peer_renegotiations;
 
   /* These fields are always NULL and exist only to keep wpa_supplicant happy
    * about the change to EVP_AEAD. They are only needed for EAP-FAST, which we
@@ -1455,7 +1504,6 @@
 #define SSL_ST_ACCEPT 0x2000
 #define SSL_ST_MASK 0x0FFF
 #define SSL_ST_INIT (SSL_ST_CONNECT | SSL_ST_ACCEPT)
-#define SSL_ST_BEFORE 0x4000
 #define SSL_ST_OK 0x03
 #define SSL_ST_RENEGOTIATE (0x04 | SSL_ST_INIT)
 
@@ -1477,7 +1525,6 @@
 #define SSL_get_state(a) SSL_state(a)
 #define SSL_is_init_finished(a) (SSL_state(a) == SSL_ST_OK)
 #define SSL_in_init(a) (SSL_state(a) & SSL_ST_INIT)
-#define SSL_in_before(a) (SSL_state(a) & SSL_ST_BEFORE)
 #define SSL_in_connect_init(a) (SSL_state(a) & SSL_ST_CONNECT)
 #define SSL_in_accept_init(a) (SSL_state(a) & SSL_ST_ACCEPT)
 
@@ -1504,6 +1551,7 @@
 #define SSL_VERIFY_NONE 0x00
 #define SSL_VERIFY_PEER 0x01
 #define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02
+/* SSL_VERIFY_CLIENT_ONCE does nothing. */
 #define SSL_VERIFY_CLIENT_ONCE 0x04
 #define SSL_VERIFY_PEER_IF_NO_OBC 0x08
 
@@ -1804,24 +1852,22 @@
 
 OPENSSL_EXPORT int SSL_CTX_set_cipher_list(SSL_CTX *, const char *str);
 OPENSSL_EXPORT int SSL_CTX_set_cipher_list_tls11(SSL_CTX *, const char *str);
-OPENSSL_EXPORT SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth);
-OPENSSL_EXPORT void SSL_CTX_free(SSL_CTX *);
 OPENSSL_EXPORT long SSL_CTX_set_timeout(SSL_CTX *ctx, long t);
 OPENSSL_EXPORT long SSL_CTX_get_timeout(const SSL_CTX *ctx);
 OPENSSL_EXPORT X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *);
 OPENSSL_EXPORT void SSL_CTX_set_cert_store(SSL_CTX *, X509_STORE *);
 OPENSSL_EXPORT int SSL_want(const SSL *s);
-OPENSSL_EXPORT int SSL_clear(SSL *s);
 
 OPENSSL_EXPORT void SSL_CTX_flush_sessions(SSL_CTX *ctx, long tm);
 
+/* SSL_get_current_cipher returns the cipher used in the current outgoing
+ * connection state, or NULL if the null cipher is active. */
 OPENSSL_EXPORT const SSL_CIPHER *SSL_get_current_cipher(const SSL *s);
 
 OPENSSL_EXPORT int SSL_get_fd(const SSL *s);
 OPENSSL_EXPORT int SSL_get_rfd(const SSL *s);
 OPENSSL_EXPORT int SSL_get_wfd(const SSL *s);
 OPENSSL_EXPORT const char *SSL_get_cipher_list(const SSL *s, int n);
-OPENSSL_EXPORT int SSL_get_read_ahead(const SSL *s);
 OPENSSL_EXPORT int SSL_pending(const SSL *s);
 OPENSSL_EXPORT int SSL_set_fd(SSL *s, int fd);
 OPENSSL_EXPORT int SSL_set_rfd(SSL *s, int fd);
@@ -1830,7 +1876,6 @@
 OPENSSL_EXPORT BIO *SSL_get_rbio(const SSL *s);
 OPENSSL_EXPORT BIO *SSL_get_wbio(const SSL *s);
 OPENSSL_EXPORT int SSL_set_cipher_list(SSL *s, const char *str);
-OPENSSL_EXPORT void SSL_set_read_ahead(SSL *s, int yes);
 OPENSSL_EXPORT int SSL_get_verify_mode(const SSL *s);
 OPENSSL_EXPORT int SSL_get_verify_depth(const SSL *s);
 OPENSSL_EXPORT int (*SSL_get_verify_callback(const SSL *s))(int,
@@ -1984,7 +2029,6 @@
                                                   const uint8_t *sid_ctx,
                                                   unsigned int sid_ctx_len);
 
-OPENSSL_EXPORT SSL *SSL_new(SSL_CTX *ctx);
 OPENSSL_EXPORT int SSL_set_session_id_context(SSL *ssl, const uint8_t *sid_ctx,
                                               unsigned int sid_ctx_len);
 
@@ -2000,7 +2044,6 @@
 OPENSSL_EXPORT X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl);
 
 OPENSSL_EXPORT void SSL_certs_clear(SSL *s);
-OPENSSL_EXPORT void SSL_free(SSL *ssl);
 OPENSSL_EXPORT int SSL_accept(SSL *ssl);
 OPENSSL_EXPORT int SSL_connect(SSL *ssl);
 OPENSSL_EXPORT int SSL_read(SSL *ssl, void *buf, int num);
@@ -2017,17 +2060,14 @@
  * |sess|. For example, "TLSv1.2" or "SSLv3". */
 OPENSSL_EXPORT const char *SSL_SESSION_get_version(const SSL_SESSION *sess);
 
-/* TLS_method is the SSL_METHOD used for TLS (and SSLv3) connections. */
-OPENSSL_EXPORT const SSL_METHOD *TLS_method(void);
-
-/* DTLS_method is the SSL_METHOD used for DTLS connections. */
-OPENSSL_EXPORT const SSL_METHOD *DTLS_method(void);
-
 OPENSSL_EXPORT STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s);
 
 OPENSSL_EXPORT int SSL_do_handshake(SSL *s);
-OPENSSL_EXPORT int SSL_renegotiate(SSL *s);
-OPENSSL_EXPORT int SSL_renegotiate_pending(SSL *s);
+
+/* SSL_renegotiate_pending returns one if |ssl| is in the middle of a
+ * renegotiation. */
+OPENSSL_EXPORT int SSL_renegotiate_pending(SSL *ssl);
+
 OPENSSL_EXPORT int SSL_shutdown(SSL *s);
 
 OPENSSL_EXPORT const char *SSL_alert_type_string_long(int value);
@@ -2045,16 +2085,12 @@
 OPENSSL_EXPORT int SSL_add_client_CA(SSL *ssl, X509 *x);
 OPENSSL_EXPORT int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x);
 
-OPENSSL_EXPORT void SSL_set_connect_state(SSL *s);
-OPENSSL_EXPORT void SSL_set_accept_state(SSL *s);
-
 OPENSSL_EXPORT long SSL_get_default_timeout(const SSL *s);
 
 OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk);
 
 OPENSSL_EXPORT X509 *SSL_get_certificate(const SSL *ssl);
-OPENSSL_EXPORT /* EVP_PKEY */ struct evp_pkey_st *SSL_get_privatekey(
-    const SSL *ssl);
+OPENSSL_EXPORT EVP_PKEY *SSL_get_privatekey(const SSL *ssl);
 
 OPENSSL_EXPORT X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx);
 OPENSSL_EXPORT EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx);
@@ -2082,7 +2118,6 @@
 OPENSSL_EXPORT void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl,
                                                              int type, int val);
 OPENSSL_EXPORT int SSL_state(const SSL *ssl);
-OPENSSL_EXPORT void SSL_set_state(SSL *ssl, int state);
 
 OPENSSL_EXPORT void SSL_set_verify_result(SSL *ssl, long v);
 OPENSSL_EXPORT long SSL_get_verify_result(const SSL *ssl);
@@ -2116,7 +2151,7 @@
 OPENSSL_EXPORT unsigned long SSL_CTX_sess_set_cache_size(SSL_CTX *ctx,
                                                          unsigned long size);
 
-/* SSL_CTX_sess_set_cache_size returns the maximum size of |ctx|'s session
+/* SSL_CTX_sess_get_cache_size returns the maximum size of |ctx|'s session
  * cache. */
 OPENSSL_EXPORT unsigned long SSL_CTX_sess_get_cache_size(const SSL_CTX *ctx);
 
@@ -2140,11 +2175,6 @@
  * |ctx| */
 OPENSSL_EXPORT int SSL_CTX_get_session_cache_mode(const SSL_CTX *ctx);
 
-/* TODO(davidben): Deprecate read_ahead functions after https://crbug.com/447431
- * is resolved. */
-OPENSSL_EXPORT int SSL_CTX_get_read_ahead(const SSL_CTX *ctx);
-OPENSSL_EXPORT void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes);
-
 /* SSL_CTX_get_max_cert_list returns the maximum length, in bytes, of a peer
  * certificate chain accepted by |ctx|. */
 OPENSSL_EXPORT size_t SSL_CTX_get_max_cert_list(const SSL_CTX *ctx);
@@ -2310,6 +2340,13 @@
 OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_server_method(void);
 OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_client_method(void);
 
+/* SSL_clear resets |ssl| to allow another connection and returns one on success
+ * or zero on failure. It returns most configuration state but releases memory
+ * associated with the current connection.
+ *
+ * Free |ssl| and create a new one instead. */
+OPENSSL_EXPORT int SSL_clear(SSL *ssl);
+
 /* SSL_CTX_set_tmp_rsa_callback does nothing. */
 OPENSSL_EXPORT void SSL_CTX_set_tmp_rsa_callback(
     SSL_CTX *ctx, RSA *(*cb)(SSL *ssl, int is_export, int keylength));
@@ -2370,6 +2407,24 @@
 /* SSL_set_tmp_rsa returns one. */
 OPENSSL_EXPORT int SSL_set_tmp_rsa(SSL *ssl, const RSA *rsa);
 
+/* SSL_CTX_get_read_head returns zero. */
+OPENSSL_EXPORT int SSL_CTX_get_read_ahead(const SSL_CTX *ctx);
+
+/* SSL_CTX_set_read_ahead does nothing. */
+OPENSSL_EXPORT void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes);
+
+/* SSL_get_read_head returns zero. */
+OPENSSL_EXPORT int SSL_get_read_ahead(const SSL *s);
+
+/* SSL_set_read_ahead does nothing. */
+OPENSSL_EXPORT void SSL_set_read_ahead(SSL *s, int yes);
+
+/* SSL_renegotiate put an error on the error queue and returns zero. */
+OPENSSL_EXPORT int SSL_renegotiate(SSL *ssl);
+
+/* SSL_set_state does nothing. */
+OPENSSL_EXPORT void SSL_set_state(SSL *ssl, int state);
+
 
 /* Android compatibility section.
  *
@@ -2581,7 +2636,7 @@
 #define SSL_F_dtls1_process_record 162
 #define SSL_F_dtls1_read_bytes 163
 #define SSL_F_dtls1_send_hello_verify_request 164
-#define SSL_F_dtls1_write_app_data_bytes 165
+#define SSL_F_dtls1_write_app_data 165
 #define SSL_F_i2d_SSL_SESSION 166
 #define SSL_F_ssl3_accept 167
 #define SSL_F_ssl3_cert_verify_hash 169
@@ -2688,6 +2743,10 @@
 #define SSL_F_SSL_set1_tls_channel_id 273
 #define SSL_F_SSL_set_tlsext_host_name 274
 #define SSL_F_ssl3_output_cert_chain 275
+#define SSL_F_SSL_AEAD_CTX_new 276
+#define SSL_F_SSL_AEAD_CTX_open 277
+#define SSL_F_SSL_AEAD_CTX_seal 278
+#define SSL_F_dtls1_seal_record 279
 #define SSL_R_APP_DATA_IN_HANDSHAKE 100
 #define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 101
 #define SSL_R_BAD_ALERT 102
@@ -2862,6 +2921,10 @@
 #define SSL_R_FRAGMENT_MISMATCH 271
 #define SSL_R_BUFFER_TOO_SMALL 272
 #define SSL_R_OLD_SESSION_VERSION_NOT_RETURNED 273
+#define SSL_R_OUTPUT_ALIASES_INPUT 274
+#define SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION 275
+#define SSL_R_EMS_STATE_INCONSISTENT 276
+#define SSL_R_RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION 277
 #define SSL_R_SSLV3_ALERT_CLOSE_NOTIFY 1000
 #define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010
 #define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020
diff --git a/src/include/openssl/ssl3.h b/src/include/openssl/ssl3.h
index 96f00cf..640a228 100644
--- a/src/include/openssl/ssl3.h
+++ b/src/include/openssl/ssl3.h
@@ -313,13 +313,23 @@
 #define SSL3_AD_INAPPROPRIATE_FALLBACK 86 /* fatal */
 
 typedef struct ssl3_record_st {
-  /*r */ int type;            /* type of record */
-  /*rw*/ unsigned int length; /* How many bytes available */
-  /*r */ unsigned int off;    /* read/write offset into 'buf' */
-  /*rw*/ uint8_t *data;       /* pointer to the record data */
-  /*rw*/ uint8_t *input;      /* where the decode bytes are */
-  /*r */ unsigned long epoch; /* epoch number, needed by DTLS1 */
-  /*r */ uint8_t seq_num[8];  /* sequence number, needed by DTLS1 */
+  /* type is the record type. */
+  uint8_t type;
+  /* length is the number of unconsumed bytes of |data|. */
+  uint16_t length;
+  /* off is the number of consumed bytes of |data|. */
+  uint16_t off;
+  /* data is a non-owning pointer to the record contents. The total length of
+   * the buffer is |off| + |length|. */
+  uint8_t *data;
+  /* epoch, in DTLS, is the epoch number of the record. */
+  uint16_t epoch;
+  /* seq_num, in DTLS, is the sequence number of the record. The top two bytes
+   * are always zero.
+   *
+   * TODO(davidben): This is confusing. They should include the epoch or the
+   * field should be six bytes. */
+  uint8_t seq_num[8];
 } SSL3_RECORD;
 
 typedef struct ssl3_buffer_st {
@@ -366,6 +376,10 @@
    * the version has not been negotiated yet. */
   char have_version;
 
+  /* initial_handshake_complete is true if the initial handshake has
+   * completed. */
+  char initial_handshake_complete;
+
   /* sniff_buffer is used by the server in the initial handshake to read a
    * V2ClientHello before the record layer is initialized. */
   BUF_MEM *sniff_buffer;
@@ -375,7 +389,6 @@
   SSL3_BUFFER wbuf; /* write IO goes into here */
 
   SSL3_RECORD rrec; /* each decoded record goes in here */
-  SSL3_RECORD wrec; /* goes out from here */
 
   /* storage for Handshake protocol data received but not yet processed by
    * ssl3_read_bytes: */
@@ -405,9 +418,6 @@
   int alert_dispatch;
   uint8_t send_alert[2];
 
-  /* This flag is set when we should renegotiate ASAP, basically when there is
-   * no more data in the read or write buffers */
-  int renegotiate;
   int total_renegotiations;
 
   /* State pertaining to the pending handshake.
diff --git a/src/include/openssl/thread.h b/src/include/openssl/thread.h
index f6e7529..568a858 100644
--- a/src/include/openssl/thread.h
+++ b/src/include/openssl/thread.h
@@ -90,56 +90,42 @@
 } CRYPTO_MUTEX;
 #endif
 
-
-/* Functions to support multithreading.
+/* CRYPTO_refcount_t is the type of a reference count.
  *
- * OpenSSL can safely be used in multi-threaded applications provided that at
- * least |CRYPTO_set_locking_callback| is set.
- *
- * The locking callback performs mutual exclusion. Rather than using a single
- * lock for all, shared data-structures, OpenSSL requires that the locking
- * callback support a fixed (at run-time) number of different locks, given by
- * |CRYPTO_num_locks|. */
-
-
-/* CRYPTO_num_locks returns the number of static locks that the callback
- * function passed to |CRYPTO_set_locking_callback| must be able to handle. */
-OPENSSL_EXPORT int CRYPTO_num_locks(void);
-
-/* CRYPTO_set_locking_callback sets a callback function that implements locking
- * on behalf of OpenSSL. The callback is called whenever OpenSSL needs to lock
- * or unlock a lock, and locks are specified as a number between zero and
- * |CRYPTO_num_locks()-1|.
- *
- * The mode argument to the callback is a bitwise-OR of either CRYPTO_LOCK or
- * CRYPTO_UNLOCK, to denote the action, and CRYPTO_READ or CRYPTO_WRITE, to
- * indicate the type of lock. The |file| and |line| arguments give the location
- * in the OpenSSL source where the locking action originated. */
-OPENSSL_EXPORT void CRYPTO_set_locking_callback(
-    void (*func)(int mode, int lock_num, const char *file, int line));
-
-/* CRYPTO_set_add_lock_callback sets an optional callback which is used when
- * OpenSSL needs to add a fixed amount to an integer. For example, this is used
- * when maintaining reference counts. Normally the reference counts are
- * maintained by performing the addition under a lock but, if this callback
- * has been set, the application is free to implement the operation using
- * faster methods (i.e. atomic operations).
- *
- * The callback is given a pointer to the integer to be altered (|num|), the
- * amount to add to the integer (|amount|, which may be negative), the number
- * of the lock which would have been taken to protect the operation and the
- * position in the OpenSSL code where the operation originated. */
-OPENSSL_EXPORT void CRYPTO_set_add_lock_callback(int (*func)(
-    int *num, int amount, int lock_num, const char *file, int line));
-
-/* CRYPTO_get_lock_name returns the name of the lock given by |lock_num|. This
- * can be used in a locking callback for debugging purposes. */
-OPENSSL_EXPORT const char *CRYPTO_get_lock_name(int lock_num);
+ * Since some platforms use C11 atomics to access this, it should have the
+ * _Atomic qualifier. However, this header is included by C++ programs as well
+ * as C code that might not set -std=c11. So, in practice, it's not possible to
+ * do that. Instead we statically assert that the size and native alignment of
+ * a plain uint32_t and an _Atomic uint32_t are equal in refcount_c11.c. */
+typedef uint32_t CRYPTO_refcount_t;
 
 
 /* Deprecated functions */
 
-/* CRYPTO_THREADID_set_callback does nothing. */
+/* These defines do nothing but are provided to make old code easier to
+ * compile. */
+#define CRYPTO_LOCK 1
+#define CRYPTO_UNLOCK 2
+#define CRYPTO_READ 4
+#define CRYPTO_WRITE 8
+
+/* CRYPTO_num_locks returns one. (This is non-zero that callers who allocate
+ * sizeof(lock) times this value don't get zero and then fail because malloc(0)
+ * returned NULL.) */
+OPENSSL_EXPORT int CRYPTO_num_locks(void);
+
+/* CRYPTO_set_locking_callback does nothing. */
+OPENSSL_EXPORT void CRYPTO_set_locking_callback(
+    void (*func)(int mode, int lock_num, const char *file, int line));
+
+/* CRYPTO_set_add_lock_callback does nothing. */
+OPENSSL_EXPORT void CRYPTO_set_add_lock_callback(int (*func)(
+    int *num, int amount, int lock_num, const char *file, int line));
+
+/* CRYPTO_get_lock_name returns a fixed, dummy string. */
+OPENSSL_EXPORT const char *CRYPTO_get_lock_name(int lock_num);
+
+/* CRYPTO_THREADID_set_callback returns one. */
 OPENSSL_EXPORT int CRYPTO_THREADID_set_callback(
     void (*threadid_func)(CRYPTO_THREADID *threadid));
 
@@ -154,81 +140,6 @@
 OPENSSL_EXPORT void CRYPTO_THREADID_current(CRYPTO_THREADID *id);
 
 
-/* Private functions: */
-
-/* CRYPTO_get_locking_callback returns the callback, if any, that was most
- * recently set using |CRYPTO_set_locking_callback|. */
-void (*CRYPTO_get_locking_callback(void))(int mode, int lock_num,
-                                          const char *file, int line);
-
-/* CRYPTO_get_add_lock_callback returns the callback, if any, that was most
- * recently set using |CRYPTO_set_add_lock_callback|. */
-int (*CRYPTO_get_add_lock_callback(void))(int *num, int amount, int lock_num,
-                                          const char *file, int line);
-
-/* CRYPTO_lock locks or unlocks the lock specified by |lock_num| (one of
- * |CRYPTO_LOCK_*|). Don't call this directly, rather use one of the
- * CRYPTO_[rw]_(un)lock macros. */
-OPENSSL_EXPORT void CRYPTO_lock(int mode, int lock_num, const char *file,
-                                int line);
-
-/* CRYPTO_add_lock adds |amount| to |*pointer|, protected by the lock specified
- * by |lock_num|. It returns the new value of |*pointer|. Don't call this
- * function directly, rather use the |CRYPTO_add| macro. */
-OPENSSL_EXPORT int CRYPTO_add_lock(int *pointer, int amount, int lock_num,
-                                   const char *file, int line);
-
-/* Lock IDs start from 1. CRYPTO_LOCK_INVALID_LOCK is an unused placeholder
- * used to ensure no lock has ID 0. */
-#define CRYPTO_LOCK_LIST \
-  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_INVALID_LOCK), \
-  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_BIO), \
-  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_DH), \
-  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_DSA), \
-  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_EC), \
-  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_EC_PRE_COMP), \
-  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_ERR), \
-  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_EVP_PKEY), \
-  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_EX_DATA), \
-  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_OBJ), \
-  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_RAND), \
-  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_READDIR), \
-  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_RSA), \
-  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_RSA_BLINDING), \
-  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_SSL_CTX), \
-  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_SSL_SESSION), \
-  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_X509), \
-  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_X509_INFO), \
-  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_X509_PKEY), \
-  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_X509_CRL), \
-  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_X509_REQ), \
-  CRYPTO_LOCK_ITEM(CRYPTO_LOCK_X509_STORE), \
-
-#define CRYPTO_LOCK_ITEM(x) x
-
-enum {
-  CRYPTO_LOCK_LIST
-};
-
-#undef CRYPTO_LOCK_ITEM
-
-#define CRYPTO_LOCK 1
-#define CRYPTO_UNLOCK 2
-#define CRYPTO_READ 4
-#define CRYPTO_WRITE 8
-
-#define CRYPTO_w_lock(lock_num) \
-  CRYPTO_lock(CRYPTO_LOCK | CRYPTO_WRITE, lock_num, __FILE__, __LINE__)
-#define CRYPTO_w_unlock(lock_num) \
-  CRYPTO_lock(CRYPTO_UNLOCK | CRYPTO_WRITE, lock_num, __FILE__, __LINE__)
-#define CRYPTO_r_lock(lock_num) \
-  CRYPTO_lock(CRYPTO_LOCK | CRYPTO_READ, lock_num, __FILE__, __LINE__)
-#define CRYPTO_r_unlock(lock_num) \
-  CRYPTO_lock(CRYPTO_UNLOCK | CRYPTO_READ, lock_num, __FILE__, __LINE__)
-#define CRYPTO_add(addr, amount, lock_num) \
-  CRYPTO_add_lock(addr, amount, lock_num, __FILE__, __LINE__)
-
-
 /* Private functions.
  *
  * Some old code calls these functions and so no-op implementations are
diff --git a/src/include/openssl/type_check.h b/src/include/openssl/type_check.h
index dd59151..674913a 100644
--- a/src/include/openssl/type_check.h
+++ b/src/include/openssl/type_check.h
@@ -76,8 +76,12 @@
  * was a pointer to |type|. */
 #define CHECKED_PTR_OF(type, p) CHECKED_CAST(void*, type*, (p))
 
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
+#define OPENSSL_COMPILE_ASSERT(cond, msg) _Static_assert(cond, #msg)
+#else
 #define OPENSSL_COMPILE_ASSERT(cond, msg) \
   typedef char OPENSSL_COMPILE_ASSERT_##msg[((cond) ? 1 : -1)]
+#endif
 
 
 #if defined(__cplusplus)
diff --git a/src/include/openssl/x509.h b/src/include/openssl/x509.h
index ef1d7fb..69c7da6 100644
--- a/src/include/openssl/x509.h
+++ b/src/include/openssl/x509.h
@@ -73,13 +73,14 @@
 #include <openssl/cipher.h>
 #include <openssl/dh.h>
 #include <openssl/dsa.h>
-#include <openssl/ec.h>
 #include <openssl/ecdh.h>
 #include <openssl/ecdsa.h>
+#include <openssl/ec.h>
 #include <openssl/evp.h>
 #include <openssl/rsa.h>
 #include <openssl/sha.h>
 #include <openssl/stack.h>
+#include <openssl/thread.h>
 
 #ifdef  __cplusplus
 extern "C" {
@@ -204,7 +205,7 @@
 	X509_REQ_INFO *req_info;
 	X509_ALGOR *sig_alg;
 	ASN1_BIT_STRING *signature;
-	int references;
+	CRYPTO_refcount_t references;
 	} X509_REQ;
 
 typedef struct x509_cinf_st
@@ -243,7 +244,7 @@
 	X509_ALGOR *sig_alg;
 	ASN1_BIT_STRING *signature;
 	int valid;
-	int references;
+	CRYPTO_refcount_t references;
 	char *name;
 	CRYPTO_EX_DATA ex_data;
 	/* These contain copies of various extension values */
@@ -420,7 +421,7 @@
 	X509_CRL_INFO *crl;
 	X509_ALGOR *sig_alg;
 	ASN1_BIT_STRING *signature;
-	int references;
+	CRYPTO_refcount_t references;
 	int flags;
 	/* Copies of various extensions */
 	AUTHORITY_KEYID *akid;
@@ -457,8 +458,6 @@
 
 	/* expanded version of 'enc_algor' */
 	EVP_CIPHER_INFO cipher;
-
-	int references;
 	} X509_PKEY;
 
 #ifndef OPENSSL_NO_EVP
@@ -472,7 +471,6 @@
 	int enc_len;
 	char *enc_data;
 
-	int references;
 	} X509_INFO;
 
 DECLARE_STACK_OF(X509_INFO)
diff --git a/src/include/openssl/x509_vfy.h b/src/include/openssl/x509_vfy.h
index 299cad7..146e047 100644
--- a/src/include/openssl/x509_vfy.h
+++ b/src/include/openssl/x509_vfy.h
@@ -67,6 +67,7 @@
 
 #include <openssl/bio.h>
 #include <openssl/lhash.h>
+#include <openssl/thread.h>
 
 #ifdef  __cplusplus
 extern "C" {
@@ -183,6 +184,7 @@
 	/* The following is a cache of trusted certs */
 	int cache; 	/* if true, stash any hits */
 	STACK_OF(X509_OBJECT) *objs;	/* Cache of all objects */
+	CRYPTO_MUTEX objs_lock;
 
 	/* These are external lookup methods */
 	STACK_OF(X509_LOOKUP) *get_cert_methods;
@@ -202,7 +204,7 @@
 	STACK_OF(X509_CRL) * (*lookup_crls)(X509_STORE_CTX *ctx, X509_NAME *nm);
 	int (*cleanup)(X509_STORE_CTX *ctx);
 
-	int references;
+	CRYPTO_refcount_t references;
 	} /* X509_STORE */;
 
 OPENSSL_EXPORT int X509_STORE_set_depth(X509_STORE *store, int depth);
diff --git a/src/ssl/CMakeLists.txt b/src/ssl/CMakeLists.txt
index 9cc6de4..cf5a29d 100644
--- a/src/ssl/CMakeLists.txt
+++ b/src/ssl/CMakeLists.txt
@@ -19,6 +19,7 @@
   s3_meth.c
   s3_pkt.c
   s3_srvr.c
+  ssl_aead_ctx.c
   ssl_algs.c
   ssl_asn1.c
   ssl_cert.c
@@ -39,6 +40,8 @@
   ssl_test
 
   ssl_test.cc
+
+  $<TARGET_OBJECTS:test_support>
 )
 
 target_link_libraries(ssl_test ssl crypto)
diff --git a/src/ssl/d1_both.c b/src/ssl/d1_both.c
index 662f518..ac35a66 100644
--- a/src/ssl/d1_both.c
+++ b/src/ssl/d1_both.c
@@ -259,11 +259,10 @@
 
 /* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or
  * SSL3_RT_CHANGE_CIPHER_SPEC) */
-int dtls1_do_write(SSL *s, int type) {
+int dtls1_do_write(SSL *s, int type, enum dtls1_use_epoch_t use_epoch) {
   int ret;
   int curr_mtu;
   unsigned int len, frag_off;
-  size_t max_overhead = 0;
 
   /* AHA!  Figure out the MTU, and stick to the right size */
   if (s->d1->mtu < dtls1_min_mtu() &&
@@ -286,12 +285,7 @@
   }
 
   /* Determine the maximum overhead of the current cipher. */
-  if (s->aead_write_ctx != NULL) {
-    max_overhead = EVP_AEAD_max_overhead(s->aead_write_ctx->ctx.aead);
-    if (s->aead_write_ctx->variable_nonce_included_in_record) {
-      max_overhead += s->aead_write_ctx->variable_nonce_len;
-    }
-  }
+  size_t max_overhead = SSL_AEAD_CTX_max_overhead(s->aead_write_ctx);
 
   frag_off = 0;
   while (s->init_num) {
@@ -356,7 +350,8 @@
       len = s->init_num;
     }
 
-    ret = dtls1_write_bytes(s, type, &s->init_buf->data[s->init_off], len);
+    ret = dtls1_write_bytes(s, type, &s->init_buf->data[s->init_off], len,
+                            use_epoch);
     if (ret < 0) {
       return -1;
     }
@@ -409,8 +404,7 @@
   uint8_t discard[256];
   while (frag_len > 0) {
     size_t chunk = frag_len < sizeof(discard) ? frag_len : sizeof(discard);
-    int ret = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, discard, chunk,
-                                        0);
+    int ret = dtls1_read_bytes(s, SSL3_RT_HANDSHAKE, discard, chunk, 0);
     if (ret != chunk) {
       return 0;
     }
@@ -485,8 +479,8 @@
    * body across two records. Change this interface to consume the fragment in
    * one pass. */
   uint8_t header[DTLS1_HM_HEADER_LENGTH];
-  int ret = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, header,
-                                      DTLS1_HM_HEADER_LENGTH, 0);
+  int ret = dtls1_read_bytes(s, SSL3_RT_HANDSHAKE, header,
+                             DTLS1_HM_HEADER_LENGTH, 0);
   if (ret <= 0) {
     return ret;
   }
@@ -538,8 +532,8 @@
   assert(msg_len > 0);
 
   /* Read the body of the fragment. */
-  ret = s->method->ssl_read_bytes(
-      s, SSL3_RT_HANDSHAKE, frag->fragment + frag_off, frag_len, 0);
+  ret = dtls1_read_bytes(s, SSL3_RT_HANDSHAKE, frag->fragment + frag_off,
+                         frag_len, 0);
   if (ret != frag_len) {
     OPENSSL_PUT_ERROR(SSL, dtls1_process_fragment, SSL_R_UNEXPECTED_MESSAGE);
     ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
@@ -690,7 +684,7 @@
   }
 
   /* SSL3_ST_CW_CHANGE_B */
-  return dtls1_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC);
+  return dtls1_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC, dtls1_use_current_epoch);
 }
 
 int dtls1_read_failed(SSL *s, int code) {
@@ -730,7 +724,6 @@
   int ret;
   /* XDTLS: for now assuming that read/writes are blocking */
   unsigned long header_length;
-  uint8_t save_write_sequence[8];
 
   /* assert(s->init_num == 0);
      assert(s->init_off == 0); */
@@ -749,45 +742,18 @@
                            frag->msg_header.msg_len, frag->msg_header.seq,
                            0, frag->msg_header.frag_len);
 
-  /* Save current state. */
-  SSL_AEAD_CTX *aead_write_ctx = s->aead_write_ctx;
-  uint16_t epoch = s->d1->w_epoch;
-
   /* DTLS renegotiation is unsupported, so only epochs 0 (NULL cipher) and 1
    * (negotiated cipher) exist. */
-  assert(epoch == 0 || epoch == 1);
-  assert(frag->msg_header.epoch <= epoch);
-  const int fragment_from_previous_epoch = (epoch == 1 &&
-                                            frag->msg_header.epoch == 0);
-  if (fragment_from_previous_epoch) {
-    /* Rewind to the previous epoch.
-     *
-     * TODO(davidben): Instead of swapping out connection-global state, this
-     * logic should pass a "use previous epoch" parameter down to lower-level
-     * functions. */
-    s->d1->w_epoch = frag->msg_header.epoch;
-    s->aead_write_ctx = NULL;
-    memcpy(save_write_sequence, s->s3->write_sequence,
-           sizeof(s->s3->write_sequence));
-    memcpy(s->s3->write_sequence, s->d1->last_write_sequence,
-           sizeof(s->s3->write_sequence));
-  } else {
-    /* Otherwise the messages must be from the same epoch. */
-    assert(frag->msg_header.epoch == epoch);
+  assert(s->d1->w_epoch == 0 || s->d1->w_epoch == 1);
+  assert(frag->msg_header.epoch <= s->d1->w_epoch);
+  enum dtls1_use_epoch_t use_epoch = dtls1_use_current_epoch;
+  if (s->d1->w_epoch == 1 && frag->msg_header.epoch == 0) {
+    use_epoch = dtls1_use_previous_epoch;
   }
 
   ret = dtls1_do_write(s, frag->msg_header.is_ccs ? SSL3_RT_CHANGE_CIPHER_SPEC
-                                                  : SSL3_RT_HANDSHAKE);
-
-  if (fragment_from_previous_epoch) {
-    /* Restore the current epoch. */
-    s->aead_write_ctx = aead_write_ctx;
-    s->d1->w_epoch = epoch;
-    memcpy(s->d1->last_write_sequence, s->s3->write_sequence,
-           sizeof(s->s3->write_sequence));
-    memcpy(s->s3->write_sequence, save_write_sequence,
-           sizeof(s->s3->write_sequence));
-  }
+                                                  : SSL3_RT_HANDSHAKE,
+                       use_epoch);
 
   (void)BIO_flush(SSL_get_wbio(s));
   return ret;
@@ -917,9 +883,3 @@
   n2l3(data, msg_hdr->frag_off);
   n2l3(data, msg_hdr->frag_len);
 }
-
-int dtls1_shutdown(SSL *s) {
-  int ret;
-  ret = ssl3_shutdown(s);
-  return ret;
-}
diff --git a/src/ssl/d1_clnt.c b/src/ssl/d1_clnt.c
index 1827a67..92fb8f6 100644
--- a/src/ssl/d1_clnt.c
+++ b/src/ssl/d1_clnt.c
@@ -155,12 +155,7 @@
     state = s->state;
 
     switch (s->state) {
-      case SSL_ST_RENEGOTIATE:
-        s->renegotiate = 1;
-        s->state = SSL_ST_CONNECT;
-      /* break */
       case SSL_ST_CONNECT:
-      case SSL_ST_BEFORE | SSL_ST_CONNECT:
         if (cb != NULL) {
           cb(s, SSL_CB_HANDSHAKE_START, 1);
         }
@@ -472,8 +467,7 @@
         ssl_free_wbio_buffer(s);
 
         s->init_num = 0;
-        s->renegotiate = 0;
-        s->new_session = 0;
+        s->s3->initial_handshake_complete = 1;
 
         ssl_update_cache(s, SSL_SESS_CACHE_CLIENT);
 
diff --git a/src/ssl/d1_lib.c b/src/ssl/d1_lib.c
index e53156f..ef7a9c9 100644
--- a/src/ssl/d1_lib.c
+++ b/src/ssl/d1_lib.c
@@ -151,14 +151,9 @@
   s->d1 = NULL;
 }
 
-const SSL_CIPHER *dtls1_get_cipher(size_t i) {
-  const SSL_CIPHER *ciph = ssl3_get_cipher(i);
+int dtls1_supports_cipher(const SSL_CIPHER *cipher) {
   /* DTLS does not support stream ciphers. */
-  if (ciph == NULL || ciph->algorithm_enc == SSL_RC4) {
-    return NULL;
-  }
-
-  return ciph;
+  return cipher->algorithm_enc != SSL_RC4;
 }
 
 void dtls1_start_timer(SSL *s) {
@@ -338,5 +333,5 @@
 }
 
 int dtls1_handshake_write(SSL *s) {
-  return dtls1_do_write(s, SSL3_RT_HANDSHAKE);
+  return dtls1_do_write(s, SSL3_RT_HANDSHAKE, dtls1_use_current_epoch);
 }
diff --git a/src/ssl/d1_meth.c b/src/ssl/d1_meth.c
index a11fbdd..d90f75b 100644
--- a/src/ssl/d1_meth.c
+++ b/src/ssl/d1_meth.c
@@ -64,21 +64,14 @@
     dtls1_free,
     dtls1_accept,
     dtls1_connect,
-    ssl3_read,
-    ssl3_peek,
-    ssl3_write,
-    dtls1_shutdown,
-    ssl3_renegotiate,
-    ssl3_renegotiate_check,
     dtls1_get_message,
-    dtls1_read_bytes,
-    dtls1_write_app_data_bytes,
+    dtls1_read_app_data,
+    dtls1_read_close_notify,
+    dtls1_write_app_data,
     dtls1_dispatch_alert,
     ssl3_ctrl,
     ssl3_ctx_ctrl,
-    ssl3_pending,
-    ssl3_num_ciphers,
-    dtls1_get_cipher,
+    dtls1_supports_cipher,
     DTLS1_HM_HEADER_LENGTH,
     dtls1_set_handshake_header,
     dtls1_handshake_write,
diff --git a/src/ssl/d1_pkt.c b/src/ssl/d1_pkt.c
index 9e056ac..553499f 100644
--- a/src/ssl/d1_pkt.c
+++ b/src/ssl/d1_pkt.c
@@ -185,25 +185,11 @@
 static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap);
 static int dtls1_process_record(SSL *s);
 static int do_dtls1_write(SSL *s, int type, const uint8_t *buf,
-                          unsigned int len);
+                          unsigned int len, enum dtls1_use_epoch_t use_epoch);
 
 static int dtls1_process_record(SSL *s) {
   int al;
-  SSL3_RECORD *rr;
-
-  rr = &(s->s3->rrec);
-
-  /* At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length, and
-   * we have that many bytes in s->packet. */
-  rr->input = &(s->packet[DTLS1_RT_HEADER_LENGTH]);
-
-  /* ok, we can now read from 's->packet' data into 'rr' rr->input points at
-   * rr->length bytes, which need to be copied into rr->data by either the
-   * decryption or by the decompression When the data is 'copied' into the
-   * rr->data buffer, rr->input will be pointed at the new buffer */
-
-  /* We now have - encrypted [ MAC [ compressed [ plain ] ] ] rr->length bytes
-   * of encrypted compressed stuff. */
+  SSL3_RECORD *rr = &s->s3->rrec;
 
   /* check is not needed I believe */
   if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) {
@@ -213,10 +199,23 @@
     goto f_err;
   }
 
-  /* decrypt in place in 'rr->input' */
-  rr->data = rr->input;
+  /* |rr->data| points to |rr->length| bytes of ciphertext in |s->packet|. */
+  rr->data = &s->packet[DTLS1_RT_HEADER_LENGTH];
 
-  if (!s->enc_method->enc(s, 0)) {
+  uint8_t seq[8];
+  seq[0] = rr->epoch >> 8;
+  seq[1] = rr->epoch & 0xff;
+  memcpy(&seq[2], &rr->seq_num[2], 6);
+
+  /* Decrypt the packet in-place. Note it is important that |SSL_AEAD_CTX_open|
+   * not write beyond |rr->length|. There may be another record in the packet.
+   *
+   * TODO(davidben): This assumes |s->version| is the same as the record-layer
+   * version which isn't always true, but it only differs with the NULL cipher
+   * which ignores the parameter. */
+  size_t plaintext_len;
+  if (!SSL_AEAD_CTX_open(s->aead_read_ctx, rr->data, &plaintext_len, rr->length,
+                         rr->type, s->version, seq, rr->data, rr->length)) {
     /* Bad packets are silently dropped in DTLS. Clear the error queue of any
      * errors decryption may have added. */
     ERR_clear_error();
@@ -225,19 +224,20 @@
     goto err;
   }
 
-  if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH) {
+  if (plaintext_len > SSL3_RT_MAX_PLAIN_LENGTH) {
     al = SSL_AD_RECORD_OVERFLOW;
     OPENSSL_PUT_ERROR(SSL, dtls1_process_record, SSL_R_DATA_LENGTH_TOO_LONG);
     goto f_err;
   }
+  assert(plaintext_len < (1u << 16));
+  rr->length = plaintext_len;
 
   rr->off = 0;
   /* So at this point the following is true
    * ssl->s3->rrec.type 	is the type of record
    * ssl->s3->rrec.length	== number of bytes in record
    * ssl->s3->rrec.off	== offset to first valid byte
-   * ssl->s3->rrec.data	== where to take bytes from, increment
-   *			   after use :-). */
+   * ssl->s3->rrec.data	== the first byte of the record body. */
 
   /* we have pulled in a full packet so zero things */
   s->packet_length = 0;
@@ -260,11 +260,11 @@
  *
  * used only by dtls1_read_bytes */
 int dtls1_get_record(SSL *s) {
-  int ssl_major, ssl_minor;
-  int i, n;
+  uint8_t ssl_major, ssl_minor;
+  int n;
   SSL3_RECORD *rr;
-  unsigned char *p = NULL;
-  unsigned short version;
+  uint8_t *p = NULL;
+  uint16_t version;
 
   rr = &(s->s3->rrec);
 
@@ -298,7 +298,7 @@
     rr->type = *(p++);
     ssl_major = *(p++);
     ssl_minor = *(p++);
-    version = (ssl_major << 8) | ssl_minor;
+    version = (((uint16_t)ssl_major) << 8) | ssl_minor;
 
     /* sequence number is 64 bits, with top 2 bytes = epoch */
     n2s(p, rr->epoch);
@@ -344,14 +344,9 @@
 
   if (rr->length > s->packet_length - DTLS1_RT_HEADER_LENGTH) {
     /* now s->packet_length == DTLS1_RT_HEADER_LENGTH */
-    i = rr->length;
-    n = ssl3_read_n(s, i, 1);
-    if (n <= 0) {
-      return n; /* error or non-blocking io */
-    }
-
-    /* this packet contained a partial record, dump it */
-    if (n != i) {
+    n = ssl3_read_n(s, rr->length, 1);
+    /* This packet contained a partial record, dump it. */
+    if (n != rr->length) {
       rr->length = 0;
       s->packet_length = 0;
       goto again;
@@ -393,6 +388,14 @@
   return 1;
 }
 
+int dtls1_read_app_data(SSL *ssl, uint8_t *buf, int len, int peek) {
+  return dtls1_read_bytes(ssl, SSL3_RT_APPLICATION_DATA, buf, len, peek);
+}
+
+void dtls1_read_close_notify(SSL *ssl) {
+  dtls1_read_bytes(ssl, 0, NULL, 0, 0);
+}
+
 /* Return up to 'len' payload bytes received in 'type' records.
  * 'type' is one of the following:
  *
@@ -674,7 +677,7 @@
   return -1;
 }
 
-int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len) {
+int dtls1_write_app_data(SSL *s, const void *buf_, int len) {
   int i;
 
   if (SSL_in_init(s) && !s->in_handshake) {
@@ -683,41 +686,96 @@
       return i;
     }
     if (i == 0) {
-      OPENSSL_PUT_ERROR(SSL, dtls1_write_app_data_bytes,
-                        SSL_R_SSL_HANDSHAKE_FAILURE);
+      OPENSSL_PUT_ERROR(SSL, dtls1_write_app_data, SSL_R_SSL_HANDSHAKE_FAILURE);
       return -1;
     }
   }
 
   if (len > SSL3_RT_MAX_PLAIN_LENGTH) {
-    OPENSSL_PUT_ERROR(SSL, dtls1_write_app_data_bytes,
-                      SSL_R_DTLS_MESSAGE_TOO_BIG);
+    OPENSSL_PUT_ERROR(SSL, dtls1_write_app_data, SSL_R_DTLS_MESSAGE_TOO_BIG);
     return -1;
   }
 
-  i = dtls1_write_bytes(s, type, buf_, len);
+  i = dtls1_write_bytes(s, SSL3_RT_APPLICATION_DATA, buf_, len,
+                        dtls1_use_current_epoch);
   return i;
 }
 
 /* Call this to write data in records of type 'type' It will return <= 0 if not
  * all data has been sent or non-blocking IO. */
-int dtls1_write_bytes(SSL *s, int type, const void *buf, int len) {
+int dtls1_write_bytes(SSL *s, int type, const void *buf, int len,
+                      enum dtls1_use_epoch_t use_epoch) {
   int i;
 
   assert(len <= SSL3_RT_MAX_PLAIN_LENGTH);
   s->rwstate = SSL_NOTHING;
-  i = do_dtls1_write(s, type, buf, len);
+  i = do_dtls1_write(s, type, buf, len, use_epoch);
   return i;
 }
 
+/* dtls1_seal_record seals a new record of type |type| and plaintext |in| and
+ * writes it to |out|. At most |max_out| bytes will be written. It returns one
+ * on success and zero on error. On success, it updates the write sequence
+ * number. */
+static int dtls1_seal_record(SSL *s, uint8_t *out, size_t *out_len,
+                             size_t max_out, uint8_t type, const uint8_t *in,
+                             size_t in_len, enum dtls1_use_epoch_t use_epoch) {
+  if (max_out < DTLS1_RT_HEADER_LENGTH) {
+    OPENSSL_PUT_ERROR(SSL, dtls1_seal_record, SSL_R_BUFFER_TOO_SMALL);
+    return 0;
+  }
+
+  /* Determine the parameters for the current epoch. */
+  uint16_t epoch = s->d1->w_epoch;
+  SSL_AEAD_CTX *aead = s->aead_write_ctx;
+  uint8_t *seq = s->s3->write_sequence;
+  if (use_epoch == dtls1_use_previous_epoch) {
+    /* DTLS renegotiation is unsupported, so only epochs 0 (NULL cipher) and 1
+     * (negotiated cipher) exist. */
+    assert(s->d1->w_epoch == 1);
+    epoch = s->d1->w_epoch - 1;
+    aead = NULL;
+    seq = s->d1->last_write_sequence;
+  }
+
+  out[0] = type;
+
+  uint16_t wire_version = s->s3->have_version ? s->version : DTLS1_VERSION;
+  out[1] = wire_version >> 8;
+  out[2] = wire_version & 0xff;
+
+  out[3] = epoch >> 8;
+  out[4] = epoch & 0xff;
+  memcpy(&out[5], &seq[2], 6);
+
+  size_t ciphertext_len;
+  if (!SSL_AEAD_CTX_seal(aead, out + DTLS1_RT_HEADER_LENGTH, &ciphertext_len,
+                         max_out - DTLS1_RT_HEADER_LENGTH, type, wire_version,
+                         &out[3] /* seq */, in, in_len) ||
+      !ssl3_record_sequence_update(&seq[2], 6)) {
+    return 0;
+  }
+
+  if (ciphertext_len >= 1 << 16) {
+    OPENSSL_PUT_ERROR(SSL, dtls1_seal_record, ERR_R_OVERFLOW);
+    return 0;
+  }
+  out[11] = ciphertext_len >> 8;
+  out[12] = ciphertext_len & 0xff;
+
+  *out_len = DTLS1_RT_HEADER_LENGTH + ciphertext_len;
+
+  if (s->msg_callback) {
+    s->msg_callback(1 /* write */, 0, SSL3_RT_HEADER, out,
+                    DTLS1_RT_HEADER_LENGTH, s, s->msg_callback_arg);
+  }
+
+  return 1;
+}
+
 static int do_dtls1_write(SSL *s, int type, const uint8_t *buf,
-                          unsigned int len) {
-  uint8_t *p, *pseq;
-  int i;
-  int prefix_len = 0;
-  int eivlen = 0;
-  SSL3_RECORD *wr;
-  SSL3_BUFFER *wb;
+                          unsigned int len, enum dtls1_use_epoch_t use_epoch) {
+  SSL3_BUFFER *wb = &s->s3->wbuf;
 
   /* ssl3_write_pending drops the write if |BIO_write| fails in DTLS, so there
    * is never pending data. */
@@ -725,88 +783,36 @@
 
   /* If we have an alert to send, lets send it */
   if (s->s3->alert_dispatch) {
-    i = s->method->ssl_dispatch_alert(s);
-    if (i <= 0) {
-      return i;
+    int ret = s->method->ssl_dispatch_alert(s);
+    if (ret <= 0) {
+      return ret;
     }
     /* if it went, fall through and send more stuff */
   }
 
+  if (wb->buf == NULL && !ssl3_setup_write_buffer(s)) {
+    return -1;
+  }
+
   if (len == 0) {
     return 0;
   }
 
-  wr = &(s->s3->wrec);
-  wb = &(s->s3->wbuf);
+  /* Align the output so the ciphertext is aligned to |SSL3_ALIGN_PAYLOAD|. */
+  uintptr_t align = (uintptr_t)wb->buf + DTLS1_RT_HEADER_LENGTH;
+  align = (0 - align) & (SSL3_ALIGN_PAYLOAD - 1);
+  uint8_t *out = wb->buf + align;
+  wb->offset = align;
+  size_t max_out = wb->len - wb->offset;
 
-  if (wb->buf == NULL && !ssl3_setup_write_buffer(s)) {
+  size_t ciphertext_len;
+  if (!dtls1_seal_record(s, out, &ciphertext_len, max_out, type, buf, len,
+                         use_epoch)) {
     return -1;
   }
-  p = wb->buf + prefix_len;
-
-  /* write the header */
-
-  *(p++) = type & 0xff;
-  wr->type = type;
-  /* Special case: for hello verify request, client version 1.0 and
-   * we haven't decided which version to use yet send back using
-   * version 1.0 header: otherwise some clients will ignore it.
-   */
-  if (!s->s3->have_version) {
-    *(p++) = DTLS1_VERSION >> 8;
-    *(p++) = DTLS1_VERSION & 0xff;
-  } else {
-    *(p++) = s->version >> 8;
-    *(p++) = s->version & 0xff;
-  }
-
-  /* field where we are to write out packet epoch, seq num and len */
-  pseq = p;
-  p += 10;
-
-  /* Leave room for the variable nonce for AEADs which specify it explicitly. */
-  if (s->aead_write_ctx != NULL &&
-      s->aead_write_ctx->variable_nonce_included_in_record) {
-    eivlen = s->aead_write_ctx->variable_nonce_len;
-  }
-
-  /* Assemble the input for |s->enc_method->enc|. The input is the plaintext
-   * with |eivlen| bytes of space prepended for the explicit nonce. */
-  wr->input = p;
-  wr->length = eivlen + len;
-  memcpy(p + eivlen, buf, len);
-
-  /* Encrypt in-place, so the output also goes into |p|. */
-  wr->data = p;
-
-  if (!s->enc_method->enc(s, 1)) {
-    goto err;
-  }
-
-  /* there's only one epoch between handshake and app data */
-  s2n(s->d1->w_epoch, pseq);
-
-  memcpy(pseq, &(s->s3->write_sequence[2]), 6);
-  pseq += 6;
-  s2n(wr->length, pseq);
-
-  if (s->msg_callback) {
-    s->msg_callback(1, 0, SSL3_RT_HEADER, pseq - DTLS1_RT_HEADER_LENGTH,
-                    DTLS1_RT_HEADER_LENGTH, s, s->msg_callback_arg);
-  }
-
-  /* we should now have wr->data pointing to the encrypted data, which is
-   * wr->length long */
-  wr->type = type; /* not needed but helps for debugging */
-  wr->length += DTLS1_RT_HEADER_LENGTH;
-
-  if (!ssl3_record_sequence_update(&s->s3->write_sequence[2], 6)) {
-    goto err;
-  }
 
   /* now let's set up wb */
-  wb->left = prefix_len + wr->length;
-  wb->offset = 0;
+  wb->left = ciphertext_len;
 
   /* memorize arguments so that ssl3_write_pending can detect bad write retries
    * later */
@@ -817,9 +823,6 @@
 
   /* we now just need to write the buffer */
   return ssl3_write_pending(s, type, buf, len);
-
-err:
-  return -1;
 }
 
 static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap) {
@@ -877,7 +880,8 @@
   *ptr++ = s->s3->send_alert[0];
   *ptr++ = s->s3->send_alert[1];
 
-  i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf));
+  i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf),
+                     dtls1_use_current_epoch);
   if (i <= 0) {
     s->s3->alert_dispatch = 1;
   } else {
diff --git a/src/ssl/d1_srvr.c b/src/ssl/d1_srvr.c
index e314910..e49a3f0 100644
--- a/src/ssl/d1_srvr.c
+++ b/src/ssl/d1_srvr.c
@@ -159,12 +159,7 @@
     state = s->state;
 
     switch (s->state) {
-      case SSL_ST_RENEGOTIATE:
-        s->renegotiate = 1;
-        /* s->state=SSL_ST_ACCEPT; */
-
       case SSL_ST_ACCEPT:
-      case SSL_ST_BEFORE | SSL_ST_ACCEPT:
         if (cb != NULL) {
           cb(s, SSL_CB_HANDSHAKE_START, 1);
         }
@@ -181,49 +176,18 @@
 
         s->init_num = 0;
 
-        if (s->state != SSL_ST_RENEGOTIATE) {
-          if (!ssl_init_wbio_buffer(s, 1)) {
-            ret = -1;
-            goto end;
-          }
-
-          if (!ssl3_init_finished_mac(s)) {
-            OPENSSL_PUT_ERROR(SSL, dtls1_accept, ERR_R_INTERNAL_ERROR);
-            ret = -1;
-            goto end;
-          }
-
-          s->state = SSL3_ST_SR_CLNT_HELLO_A;
-        } else {
-          /* s->state == SSL_ST_RENEGOTIATE, * we will just send a
-           * HelloRequest */
-          s->state = SSL3_ST_SW_HELLO_REQ_A;
-        }
-
-        break;
-
-      case SSL3_ST_SW_HELLO_REQ_A:
-      case SSL3_ST_SW_HELLO_REQ_B:
-        s->shutdown = 0;
-        dtls1_clear_record_buffer(s);
-        dtls1_start_timer(s);
-        ret = ssl3_send_hello_request(s);
-        if (ret <= 0) {
+        if (!ssl_init_wbio_buffer(s, 1)) {
+          ret = -1;
           goto end;
         }
-        s->s3->tmp.next_state = SSL3_ST_SR_CLNT_HELLO_A;
-        s->state = SSL3_ST_SW_FLUSH;
-        s->init_num = 0;
 
         if (!ssl3_init_finished_mac(s)) {
           OPENSSL_PUT_ERROR(SSL, dtls1_accept, ERR_R_INTERNAL_ERROR);
           ret = -1;
           goto end;
         }
-        break;
 
-      case SSL3_ST_SW_HELLO_REQ_C:
-        s->state = SSL_ST_OK;
+        s->state = SSL3_ST_SR_CLNT_HELLO_A;
         break;
 
       case SSL3_ST_SR_CLNT_HELLO_A:
@@ -242,7 +206,6 @@
 
       case SSL3_ST_SW_SRVR_HELLO_A:
       case SSL3_ST_SW_SRVR_HELLO_B:
-        s->renegotiate = 2;
         dtls1_start_timer(s);
         ret = ssl3_send_server_hello(s);
         if (ret <= 0) {
@@ -310,29 +273,17 @@
 
       case SSL3_ST_SW_CERT_REQ_A:
       case SSL3_ST_SW_CERT_REQ_B:
-        if (/* don't request cert unless asked for it: */
-            !(s->verify_mode & SSL_VERIFY_PEER) ||
-            /* if SSL_VERIFY_CLIENT_ONCE is set,
-             * don't request cert during re-negotiation: */
-            ((s->session->peer != NULL) &&
-             (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) ||
-            /* With normal PSK Certificates and
-             * Certificate Requests are omitted */
-            (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) {
-          /* no cert request */
-          skip = 1;
-          s->s3->tmp.cert_request = 0;
-          s->state = SSL3_ST_SW_SRVR_DONE_A;
-        } else {
-          s->s3->tmp.cert_request = 1;
+        if (s->s3->tmp.cert_request) {
           dtls1_start_timer(s);
           ret = ssl3_send_certificate_request(s);
           if (ret <= 0) {
             goto end;
           }
-          s->state = SSL3_ST_SW_SRVR_DONE_A;
-          s->init_num = 0;
+        } else {
+          skip = 1;
         }
+        s->state = SSL3_ST_SW_SRVR_DONE_A;
+        s->init_num = 0;
         break;
 
       case SSL3_ST_SW_SRVR_DONE_A:
@@ -470,17 +421,12 @@
         ssl_free_wbio_buffer(s);
 
         s->init_num = 0;
+        s->s3->initial_handshake_complete = 1;
 
-        if (s->renegotiate == 2) {
-          /* skipped if we just sent a HelloRequest */
-          s->renegotiate = 0;
-          s->new_session = 0;
+        ssl_update_cache(s, SSL_SESS_CACHE_SERVER);
 
-          ssl_update_cache(s, SSL_SESS_CACHE_SERVER);
-
-          if (cb != NULL) {
-            cb(s, SSL_CB_HANDSHAKE_DONE, 1);
-          }
+        if (cb != NULL) {
+          cb(s, SSL_CB_HANDSHAKE_DONE, 1);
         }
 
         ret = 1;
diff --git a/src/ssl/internal.h b/src/ssl/internal.h
index 3bd749d..7d9a5ad 100644
--- a/src/ssl/internal.h
+++ b/src/ssl/internal.h
@@ -215,19 +215,6 @@
  * one, update the table in ssl_cipher.c. */
 #define SSL_MAX_DIGEST 4
 
-#define TLS1_PRF_DGST_MASK (0xff << TLS1_PRF_DGST_SHIFT)
-
-#define TLS1_PRF_DGST_SHIFT 10
-#define TLS1_PRF_MD5 (SSL_HANDSHAKE_MAC_MD5 << TLS1_PRF_DGST_SHIFT)
-#define TLS1_PRF_SHA1 (SSL_HANDSHAKE_MAC_SHA << TLS1_PRF_DGST_SHIFT)
-#define TLS1_PRF_SHA256 (SSL_HANDSHAKE_MAC_SHA256 << TLS1_PRF_DGST_SHIFT)
-#define TLS1_PRF_SHA384 (SSL_HANDSHAKE_MAC_SHA384 << TLS1_PRF_DGST_SHIFT)
-#define TLS1_PRF (TLS1_PRF_MD5 | TLS1_PRF_SHA1)
-
-/* SSL_CIPHER_ALGORITHM2_AEAD is a flag in SSL_CIPHER.algorithm2 which
- * indicates that the cipher is implemented via an EVP_AEAD. */
-#define SSL_CIPHER_ALGORITHM2_AEAD (1 << 23)
-
 /* SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD is a flag in
  * SSL_CIPHER.algorithm2 which indicates that the variable part of the nonce is
  * included as a prefix of the record. (AES-GCM, for example, does with with an
@@ -273,6 +260,9 @@
 #define SSL_PKEY_ECC 2
 #define SSL_PKEY_NUM 3
 
+/* ssl_cipher_get_value returns the cipher suite id of |cipher|. */
+uint16_t ssl_cipher_get_value(const SSL_CIPHER *cipher);
+
 /* ssl_cipher_get_cert_index returns the |SSL_PKEY_*| value corresponding to the
  * certificate type of |cipher| or -1 if there is none. */
 int ssl_cipher_get_cert_index(const SSL_CIPHER *cipher);
@@ -291,6 +281,75 @@
 int ssl_cipher_requires_server_key_exchange(const SSL_CIPHER *cipher);
 
 
+/* Encryption layer. */
+
+/* SSL_AEAD_CTX contains information about an AEAD that is being used to encrypt
+ * an SSL connection. */
+struct ssl_aead_ctx_st {
+  const SSL_CIPHER *cipher;
+  EVP_AEAD_CTX ctx;
+  /* fixed_nonce contains any bytes of the nonce that are fixed for all
+   * records. */
+  uint8_t fixed_nonce[8];
+  uint8_t fixed_nonce_len, variable_nonce_len;
+  /* variable_nonce_included_in_record is non-zero if the variable nonce
+   * for a record is included as a prefix before the ciphertext. */
+  char variable_nonce_included_in_record;
+  /* random_variable_nonce is non-zero if the variable nonce is
+   * randomly generated, rather than derived from the sequence
+   * number. */
+  char random_variable_nonce;
+  /* omit_length_in_ad is non-zero if the length should be omitted in the
+   * AEAD's ad parameter. */
+  char omit_length_in_ad;
+  /* omit_version_in_ad is non-zero if the version should be omitted
+   * in the AEAD's ad parameter. */
+  char omit_version_in_ad;
+} /* SSL_AEAD_CTX */;
+
+/* SSL_AEAD_CTX_new creates a newly-allocated |SSL_AEAD_CTX| using the supplied
+ * key material. It returns NULL on error. Only one of |SSL_AEAD_CTX_open| or
+ * |SSL_AEAD_CTX_seal| may be used with the resulting object, depending on
+ * |direction|. |version| is the normalized protocol version, so DTLS 1.0 is
+ * represented as 0x0301, not 0xffef. */
+SSL_AEAD_CTX *SSL_AEAD_CTX_new(enum evp_aead_direction_t direction,
+                               uint16_t version, const SSL_CIPHER *cipher,
+                               const uint8_t *enc_key, size_t enc_key_len,
+                               const uint8_t *mac_key, size_t mac_key_len,
+                               const uint8_t *fixed_iv, size_t fixed_iv_len);
+
+/* SSL_AEAD_CTX_free frees |ctx|. */
+void SSL_AEAD_CTX_free(SSL_AEAD_CTX *ctx);
+
+/* SSL_AEAD_CTX_explicit_nonce_len returns the length of the explicit nonce for
+ * |ctx|, if any. |ctx| may be NULL to denote the null cipher. */
+size_t SSL_AEAD_CTX_explicit_nonce_len(SSL_AEAD_CTX *ctx);
+
+/* SSL_AEAD_CTX_max_overhead returns the maximum overhead of calling
+ * |SSL_AEAD_CTX_seal|. |ctx| may be NULL to denote the null cipher. */
+size_t SSL_AEAD_CTX_max_overhead(SSL_AEAD_CTX *ctx);
+
+/* SSL_AEAD_CTX_open authenticates and decrypts |in_len| bytes from |in| and
+ * writes the result to |out|. It returns one on success and zero on
+ * error. |ctx| may be NULL to denote the null cipher.
+ *
+ * If |in| and |out| alias then |out| must be <= |in| + |explicit_nonce_len|. */
+int SSL_AEAD_CTX_open(SSL_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
+                      size_t max_out, uint8_t type, uint16_t wire_version,
+                      const uint8_t seqnum[8], const uint8_t *in,
+                      size_t in_len);
+
+/* SSL_AEAD_CTX_seal encrypts and authenticates |in_len| bytes from |in| and
+ * writes the result to |out|. It returns one on success and zero on
+ * error. |ctx| may be NULL to denote the null cipher.
+ *
+ * If |in| and |out| alias then |out| + |explicit_nonce_len| must be <= |in| */
+int SSL_AEAD_CTX_seal(SSL_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
+                      size_t max_out, uint8_t type, uint16_t wire_version,
+                      const uint8_t seqnum[8], const uint8_t *in,
+                      size_t in_len);
+
+
 /* Underdocumented functions.
  *
  * Functions below here haven't been touched up and may be underdocumented. */
@@ -568,23 +627,18 @@
   void (*ssl_free)(SSL *s);
   int (*ssl_accept)(SSL *s);
   int (*ssl_connect)(SSL *s);
-  int (*ssl_read)(SSL *s, void *buf, int len);
-  int (*ssl_peek)(SSL *s, void *buf, int len);
-  int (*ssl_write)(SSL *s, const void *buf, int len);
-  int (*ssl_shutdown)(SSL *s);
-  int (*ssl_renegotiate)(SSL *s);
-  int (*ssl_renegotiate_check)(SSL *s);
   long (*ssl_get_message)(SSL *s, int header_state, int body_state,
                           int msg_type, long max,
                           enum ssl_hash_message_t hash_message, int *ok);
-  int (*ssl_read_bytes)(SSL *s, int type, uint8_t *buf, int len, int peek);
-  int (*ssl_write_bytes)(SSL *s, int type, const void *buf_, int len);
+  int (*ssl_read_app_data)(SSL *s, uint8_t *buf, int len, int peek);
+  void (*ssl_read_close_notify)(SSL *s);
+  int (*ssl_write_app_data)(SSL *s, const void *buf_, int len);
   int (*ssl_dispatch_alert)(SSL *s);
   long (*ssl_ctrl)(SSL *s, int cmd, long larg, void *parg);
   long (*ssl_ctx_ctrl)(SSL_CTX *ctx, int cmd, long larg, void *parg);
-  int (*ssl_pending)(const SSL *s);
-  size_t (*num_ciphers)(void);
-  const SSL_CIPHER *(*get_cipher)(size_t i);
+  /* supports_cipher returns one if |cipher| is supported by this protocol and
+   * zero otherwise. */
+  int (*supports_cipher)(const SSL_CIPHER *cipher);
   /* Handshake header length */
   unsigned int hhlen;
   /* Set the handshake header */
@@ -596,7 +650,6 @@
 /* This is for the SSLv3/TLSv1.0 differences in crypto/hash stuff It is a bit
  * of a mess of functions, but hell, think of it as an opaque structure. */
 struct ssl3_enc_method {
-  int (*enc)(SSL *, int);
   int (*prf)(SSL *, uint8_t *, size_t, const uint8_t *, size_t, const char *,
              size_t, const uint8_t *, size_t, const uint8_t *, size_t);
   int (*setup_key_block)(SSL *);
@@ -634,29 +687,6 @@
  * may apply to others in future. */
 #define SSL_ENC_FLAG_TLS1_2_CIPHERS 0x8
 
-/* ssl_aead_ctx_st contains information about an AEAD that is being used to
- * encrypt an SSL connection. */
-struct ssl_aead_ctx_st {
-  EVP_AEAD_CTX ctx;
-  /* fixed_nonce contains any bytes of the nonce that are fixed for all
-   * records. */
-  uint8_t fixed_nonce[8];
-  uint8_t fixed_nonce_len, variable_nonce_len, tag_len;
-  /* variable_nonce_included_in_record is non-zero if the variable nonce
-   * for a record is included as a prefix before the ciphertext. */
-  char variable_nonce_included_in_record;
-  /* random_variable_nonce is non-zero if the variable nonce is
-   * randomly generated, rather than derived from the sequence
-   * number. */
-  char random_variable_nonce;
-  /* omit_length_in_ad is non-zero if the length should be omitted in the
-   * AEAD's ad parameter. */
-  char omit_length_in_ad;
-  /* omit_version_in_ad is non-zero if the version should be omitted
-   * in the AEAD's ad parameter. */
-  char omit_version_in_ad;
-};
-
 /* lengths of messages */
 #define DTLS1_COOKIE_LENGTH 256
 
@@ -757,8 +787,6 @@
   unsigned int change_cipher_spec_ok;
 } DTLS1_STATE;
 
-extern const SSL_CIPHER ssl3_ciphers[];
-
 extern const SSL3_ENC_METHOD TLSv1_enc_data;
 extern const SSL3_ENC_METHOD TLSv1_1_enc_data;
 extern const SSL3_ENC_METHOD TLSv1_2_enc_data;
@@ -773,9 +801,8 @@
 SESS_CERT *ssl_sess_cert_new(void);
 void ssl_sess_cert_free(SESS_CERT *sc);
 int ssl_set_peer_cert_type(SESS_CERT *c, int type);
+int ssl_get_new_session(SSL *s, int session);
 int ssl_get_prev_session(SSL *s, const struct ssl_early_callback_ctx *ctx);
-int ssl_cipher_id_cmp(const void *in_a, const void *in_b);
-int ssl_cipher_ptr_id_cmp(const SSL_CIPHER **ap, const SSL_CIPHER **bp);
 STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, const CBS *cbs);
 int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, uint8_t *p);
 struct ssl_cipher_preference_list_st *ssl_cipher_preference_list_dup(
@@ -799,6 +826,7 @@
 int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref);
 CERT_PKEY *ssl_get_server_send_pkey(const SSL *s);
 EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *c);
+void ssl_update_cache(SSL *s, int mode);
 int ssl_cert_type(EVP_PKEY *pkey);
 
 /* ssl_get_compatible_server_ciphers determines the key exchange and
@@ -810,10 +838,11 @@
 
 STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s);
 int ssl_verify_alarm_type(long type);
-int ssl_fill_hello_random(SSL *s, int server, uint8_t *field, size_t len);
 
-const SSL_CIPHER *ssl3_get_cipher_by_value(uint16_t value);
-uint16_t ssl3_get_cipher_value(const SSL_CIPHER *c);
+/* ssl_fill_hello_random fills a client_random or server_random field of length
+ * |len|. It returns one on success and zero on failure. */
+int ssl_fill_hello_random(uint8_t *out, size_t len, int is_server);
+
 int ssl3_init_finished_mac(SSL *s);
 int ssl3_send_server_certificate(SSL *s);
 int ssl3_send_new_session_ticket(SSL *s);
@@ -845,13 +874,13 @@
                           const EVP_MD **out_md, EVP_PKEY *pkey);
 
 int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen);
-size_t ssl3_num_ciphers(void);
-const SSL_CIPHER *ssl3_get_cipher(size_t i);
-int ssl3_renegotiate(SSL *ssl);
-int ssl3_renegotiate_check(SSL *ssl);
+int ssl3_supports_cipher(const SSL_CIPHER *cipher);
 int ssl3_dispatch_alert(SSL *s);
 int ssl3_expect_change_cipher_spec(SSL *s);
+int ssl3_read_app_data(SSL *ssl, uint8_t *buf, int len, int peek);
+void ssl3_read_close_notify(SSL *ssl);
 int ssl3_read_bytes(SSL *s, int type, uint8_t *buf, int len, int peek);
+int ssl3_write_app_data(SSL *ssl, const void *buf, int len);
 int ssl3_write_bytes(SSL *s, int type, const void *buf, int len);
 int ssl3_final_finish_mac(SSL *s, const char *sender, int slen, uint8_t *p);
 int ssl3_cert_verify_mac(SSL *s, int md_nid, uint8_t *p);
@@ -876,13 +905,8 @@
 void ssl3_free(SSL *s);
 int ssl3_accept(SSL *s);
 int ssl3_connect(SSL *s);
-int ssl3_read(SSL *s, void *buf, int len);
-int ssl3_peek(SSL *s, void *buf, int len);
-int ssl3_write(SSL *s, const void *buf, int len);
-int ssl3_shutdown(SSL *s);
 long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg);
 long ssl3_ctx_ctrl(SSL_CTX *s, int cmd, long larg, void *parg);
-int ssl3_pending(const SSL *s);
 
 /* ssl3_record_sequence_update increments the sequence number in |seq|. It
  * returns one on success and zero on wraparound. */
@@ -893,16 +917,24 @@
 int ssl3_set_handshake_header(SSL *s, int htype, unsigned long len);
 int ssl3_handshake_write(SSL *s);
 
-int dtls1_do_write(SSL *s, int type);
+enum dtls1_use_epoch_t {
+  dtls1_use_previous_epoch,
+  dtls1_use_current_epoch,
+};
+
+int dtls1_do_write(SSL *s, int type, enum dtls1_use_epoch_t use_epoch);
 int ssl3_read_n(SSL *s, int n, int extend);
+int dtls1_read_app_data(SSL *ssl, uint8_t *buf, int len, int peek);
+void dtls1_read_close_notify(SSL *ssl);
 int dtls1_read_bytes(SSL *s, int type, uint8_t *buf, int len, int peek);
 int ssl3_write_pending(SSL *s, int type, const uint8_t *buf, unsigned int len);
 void dtls1_set_message_header(SSL *s, uint8_t mt, unsigned long len,
                               unsigned short seq_num, unsigned long frag_off,
                               unsigned long frag_len);
 
-int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf, int len);
-int dtls1_write_bytes(SSL *s, int type, const void *buf, int len);
+int dtls1_write_app_data(SSL *s, const void *buf, int len);
+int dtls1_write_bytes(SSL *s, int type, const void *buf, int len,
+                      enum dtls1_use_epoch_t use_epoch);
 
 int dtls1_send_change_cipher_spec(SSL *s, int a, int b);
 int dtls1_send_finished(SSL *s, int a, int b, const char *sender, int slen);
@@ -917,7 +949,7 @@
 int dtls1_set_handshake_header(SSL *s, int type, unsigned long len);
 int dtls1_handshake_write(SSL *s);
 
-const SSL_CIPHER *dtls1_get_cipher(size_t i);
+int dtls1_supports_cipher(const SSL_CIPHER *cipher);
 void dtls1_start_timer(SSL *s);
 void dtls1_stop_timer(SSL *s);
 int dtls1_is_timer_expired(SSL *s);
@@ -949,7 +981,6 @@
 int ssl3_get_v2_client_hello(SSL *s);
 int ssl3_get_client_hello(SSL *s);
 int ssl3_send_server_hello(SSL *s);
-int ssl3_send_hello_request(SSL *s);
 int ssl3_send_server_key_exchange(SSL *s);
 int ssl3_send_certificate_request(SSL *s);
 int ssl3_send_server_done(SSL *s);
@@ -963,7 +994,6 @@
 int dtls1_accept(SSL *s);
 int dtls1_connect(SSL *s);
 void dtls1_free(SSL *s);
-int dtls1_shutdown(SSL *s);
 
 long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max,
                        enum ssl_hash_message_t hash_message, int *ok);
@@ -985,7 +1015,6 @@
 
 int tls1_change_cipher_state(SSL *s, int which);
 int tls1_setup_key_block(SSL *s);
-int tls1_enc(SSL *s, int snd);
 int tls1_handshake_digest(SSL *s, uint8_t *out, size_t out_len);
 int tls1_final_finish_mac(SSL *s, const char *str, int slen, uint8_t *p);
 int tls1_cert_verify_mac(SSL *s, int md_nid, uint8_t *p);
@@ -997,7 +1026,6 @@
                                 int use_context);
 int tls1_alert_code(int code);
 int ssl3_alert_code(int code);
-int ssl_ok(SSL *s);
 
 int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s);
 
diff --git a/src/ssl/pqueue/CMakeLists.txt b/src/ssl/pqueue/CMakeLists.txt
index 9f14020..53d2a8b 100644
--- a/src/ssl/pqueue/CMakeLists.txt
+++ b/src/ssl/pqueue/CMakeLists.txt
@@ -12,6 +12,8 @@
   pqueue_test
 
   pqueue_test.c
+
+  $<TARGET_OBJECTS:test_support>
 )
 
 target_link_libraries(pqueue_test ssl crypto)
diff --git a/src/ssl/pqueue/pqueue_test.c b/src/ssl/pqueue/pqueue_test.c
index cb688f7..5a68fc4 100644
--- a/src/ssl/pqueue/pqueue_test.c
+++ b/src/ssl/pqueue/pqueue_test.c
@@ -72,7 +72,7 @@
   for (i = 0; i < NUM_ITEMS; i++) {
     priority[7] = ordering[i];
     item = pitem_new(priority, &ordering[i]);
-    if (pqueue_insert(q, item) != item) {
+    if (item == NULL || pqueue_insert(q, item) != item) {
       return 0;
     }
   }
@@ -82,7 +82,7 @@
   for (i = 0; i < NUM_ITEMS; i++) {
     priority[7] = ordering[i];
     item = pitem_new(priority, &ordering[i]);
-    if (pqueue_insert(q, item) != NULL) {
+    if (item == NULL || pqueue_insert(q, item) != NULL) {
       return 0;
     }
     pitem_free(item);
diff --git a/src/ssl/s3_both.c b/src/ssl/s3_both.c
index b78f6d3..06338b7 100644
--- a/src/ssl/s3_both.c
+++ b/src/ssl/s3_both.c
@@ -195,8 +195,8 @@
   return ssl_do_write(s);
 }
 
-/* ssl3_take_mac calculates the Finished MAC for the handshakes messages seen to
- * far. */
+/* ssl3_take_mac calculates the Finished MAC for the handshakes messages seen
+ * so far. */
 static void ssl3_take_mac(SSL *s) {
   const char *sender;
   int slen;
@@ -357,8 +357,8 @@
 
     for (;;) {
       while (s->init_num < 4) {
-        int bytes_read = s->method->ssl_read_bytes(
-            s, SSL3_RT_HANDSHAKE, &p[s->init_num], 4 - s->init_num, 0);
+        int bytes_read = ssl3_read_bytes(s, SSL3_RT_HANDSHAKE, &p[s->init_num],
+                                         4 - s->init_num, 0);
         if (bytes_read <= 0) {
           *ok = 0;
           return bytes_read;
@@ -413,8 +413,8 @@
   p = s->init_msg;
   n = s->s3->tmp.message_size - s->init_num;
   while (n > 0) {
-    int bytes_read =
-        s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, &p[s->init_num], n, 0);
+    int bytes_read = ssl3_read_bytes(s, SSL3_RT_HANDSHAKE, &p[s->init_num], n,
+                                     0);
     if (bytes_read <= 0) {
       s->rwstate = SSL_READING;
       *ok = 0;
@@ -667,20 +667,10 @@
   return 1;
 }
 
-/* ssl_fill_hello_random fills a client_random or server_random field of length
- * |len|. Returns 0 on failure or 1 on success. */
-int ssl_fill_hello_random(SSL *s, int server, uint8_t *result, size_t len) {
-  int send_time = 0;
-
-  if (server) {
-    send_time = (s->mode & SSL_MODE_SEND_SERVERHELLO_TIME) != 0;
-  } else {
-    send_time = (s->mode & SSL_MODE_SEND_CLIENTHELLO_TIME) != 0;
-  }
-
-  if (send_time) {
+int ssl_fill_hello_random(uint8_t *out, size_t len, int is_server) {
+  if (is_server) {
     const uint32_t current_time = time(NULL);
-    uint8_t *p = result;
+    uint8_t *p = out;
 
     if (len < 4) {
       return 0;
@@ -691,6 +681,6 @@
     p[3] = current_time;
     return RAND_bytes(p + 4, len - 4);
   } else {
-    return RAND_bytes(result, len);
+    return RAND_bytes(out, len);
   }
 }
diff --git a/src/ssl/s3_clnt.c b/src/ssl/s3_clnt.c
index d01acae..159e2d7 100644
--- a/src/ssl/s3_clnt.c
+++ b/src/ssl/s3_clnt.c
@@ -193,25 +193,11 @@
     state = s->state;
 
     switch (s->state) {
-      case SSL_ST_RENEGOTIATE:
-        s->renegotiate = 1;
-        s->state = SSL_ST_CONNECT;
-        /* fallthrough */
       case SSL_ST_CONNECT:
-      case SSL_ST_BEFORE | SSL_ST_CONNECT:
         if (cb != NULL) {
           cb(s, SSL_CB_HANDSHAKE_START, 1);
         }
 
-        if ((s->version >> 8) != 3) {
-          /* TODO(davidben): Some consumers clear |s->version| to break the
-           * handshake in a callback. Remove this when they're using proper
-           * APIs. */
-          OPENSSL_PUT_ERROR(SSL, ssl3_connect, ERR_R_INTERNAL_ERROR);
-          ret = -1;
-          goto end;
-        }
-
         if (s->init_buf == NULL) {
           buf = BUF_MEM_new();
           if (buf == NULL ||
@@ -457,7 +443,7 @@
               ssl3_can_false_start(s) &&
               /* No False Start on renegotiation (would complicate the state
                * machine). */
-              s->s3->previous_server_finished_len == 0) {
+              !s->s3->initial_handshake_complete) {
             s->s3->tmp.next_state = SSL3_ST_FALSE_START;
           } else {
             /* Allow NewSessionTicket if ticket expected */
@@ -551,9 +537,8 @@
         ssl_free_wbio_buffer(s);
 
         s->init_num = 0;
-        s->renegotiate = 0;
-        s->new_session = 0;
         s->s3->tmp.in_false_start = 0;
+        s->s3->initial_handshake_complete = 1;
 
         ssl_update_cache(s, SSL_SESS_CACHE_CLIENT);
 
@@ -625,7 +610,8 @@
     /* If resending the ClientHello in DTLS after a HelloVerifyRequest, don't
      * renegerate the client_random. The random must be reused. */
     if ((!SSL_IS_DTLS(s) || !s->d1->send_cookie) &&
-        !ssl_fill_hello_random(s, 0, p, sizeof(s->s3->client_random))) {
+        !ssl_fill_hello_random(p, sizeof(s->s3->client_random),
+                               0 /* client */)) {
       goto err;
     }
 
@@ -666,7 +652,8 @@
     p += SSL3_RANDOM_SIZE;
 
     /* Session ID */
-    if (s->new_session || s->session == NULL) {
+    if (s->s3->initial_handshake_complete || s->session == NULL) {
+      /* Renegotiations do not participate in session resumption. */
       i = 0;
     } else {
       i = s->session->session_id_length;
@@ -778,6 +765,7 @@
     goto f_err;
   }
 
+  assert(s->s3->have_version == s->s3->initial_handshake_complete);
   if (!s->s3->have_version) {
     if (!ssl3_is_version_enabled(s, server_version)) {
       OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_UNSUPPORTED_PROTOCOL);
@@ -804,8 +792,9 @@
   memcpy(s->s3->server_random, CBS_data(&server_random), SSL3_RANDOM_SIZE);
 
   assert(s->session == NULL || s->session->session_id_length > 0);
-  if (s->session != NULL && CBS_mem_equal(&session_id, s->session->session_id,
-                                          s->session->session_id_length)) {
+  if (!s->s3->initial_handshake_complete && s->session != NULL &&
+      CBS_mem_equal(&session_id, s->session->session_id,
+                    s->session->session_id_length)) {
     if (s->sid_ctx_length != s->session->sid_ctx_length ||
         memcmp(s->session->sid_ctx, s->sid_ctx, s->sid_ctx_length)) {
       /* actually a client application bug */
@@ -827,7 +816,7 @@
     memcpy(s->session->session_id, CBS_data(&session_id), CBS_len(&session_id));
   }
 
-  c = ssl3_get_cipher_by_value(cipher_suite);
+  c = SSL_get_cipher_by_value(cipher_suite);
   if (c == NULL) {
     /* unknown cipher */
     al = SSL_AD_ILLEGAL_PARAMETER;
@@ -876,9 +865,10 @@
   }
   s->s3->tmp.new_cipher = c;
 
-  /* Don't digest cached records if no sigalgs: we may need them for client
-   * authentication. */
-  if (!SSL_USE_SIGALGS(s) &&
+  /* If doing a full handshake with TLS 1.2, the server may request a client
+   * certificate which requires hashing the handshake transcript under a
+   * different hash. Otherwise, release the handshake buffer. */
+  if ((!SSL_USE_SIGALGS(s) || s->hit) &&
       !ssl3_digest_cached_records(s, free_handshake_buffer)) {
     goto f_err;
   }
@@ -905,6 +895,19 @@
     goto f_err;
   }
 
+  if (s->hit &&
+      s->s3->tmp.extended_master_secret != s->session->extended_master_secret) {
+    al = SSL_AD_HANDSHAKE_FAILURE;
+    if (s->session->extended_master_secret) {
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello,
+                        SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION);
+    } else {
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello,
+                        SSL_R_RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION);
+    }
+    goto f_err;
+  }
+
   return 1;
 
 f_err:
@@ -1185,7 +1188,7 @@
       goto err;
     }
 
-    if (DH_size(dh) < 512 / 8) {
+    if (DH_num_bits(dh) < 1024) {
       OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange,
                         SSL_R_BAD_DH_P_LENGTH);
       goto err;
@@ -2128,6 +2131,13 @@
         return 1;
       } else {
         s->s3->tmp.cert_req = 2;
+        /* There is no client certificate, so the handshake buffer may be
+         * released. */
+        if (s->s3->handshake_buffer &&
+            !ssl3_digest_cached_records(s, free_handshake_buffer)) {
+          ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+          return -1;
+        }
       }
     }
 
diff --git a/src/ssl/s3_lib.c b/src/ssl/s3_lib.c
index 92c923e..1c28a73 100644
--- a/src/ssl/s3_lib.c
+++ b/src/ssl/s3_lib.c
@@ -160,327 +160,7 @@
 #include "internal.h"
 
 
-#define SSL3_NUM_CIPHERS (sizeof(ssl3_ciphers) / sizeof(SSL_CIPHER))
-
-/* list of available SSLv3 ciphers (sorted by id) */
-const SSL_CIPHER ssl3_ciphers[] = {
-    /* The RSA ciphers */
-    /* Cipher 04 */
-    {
-     SSL3_TXT_RSA_RC4_128_MD5, SSL3_CK_RSA_RC4_128_MD5, SSL_kRSA, SSL_aRSA,
-     SSL_RC4, SSL_MD5, SSL_SSLV3, SSL_MEDIUM,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 128, 128,
-    },
-
-    /* Cipher 05 */
-    {
-     SSL3_TXT_RSA_RC4_128_SHA, SSL3_CK_RSA_RC4_128_SHA, SSL_kRSA, SSL_aRSA,
-     SSL_RC4, SSL_SHA1, SSL_SSLV3, SSL_MEDIUM,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 128, 128,
-    },
-
-    /* Cipher 0A */
-    {
-     SSL3_TXT_RSA_DES_192_CBC3_SHA, SSL3_CK_RSA_DES_192_CBC3_SHA, SSL_kRSA,
-     SSL_aRSA, SSL_3DES, SSL_SHA1, SSL_SSLV3, SSL_HIGH | SSL_FIPS,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168,
-    },
-
-
-    /* New AES ciphersuites */
-
-    /* Cipher 2F */
-    {
-     TLS1_TXT_RSA_WITH_AES_128_SHA, TLS1_CK_RSA_WITH_AES_128_SHA, SSL_kRSA,
-     SSL_aRSA, SSL_AES128, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 128, 128,
-    },
-
-    /* Cipher 33 */
-    {
-     TLS1_TXT_DHE_RSA_WITH_AES_128_SHA, TLS1_CK_DHE_RSA_WITH_AES_128_SHA,
-     SSL_kDHE, SSL_aRSA, SSL_AES128, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 128, 128,
-    },
-
-    /* Cipher 35 */
-    {
-     TLS1_TXT_RSA_WITH_AES_256_SHA, TLS1_CK_RSA_WITH_AES_256_SHA, SSL_kRSA,
-     SSL_aRSA, SSL_AES256, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 256, 256,
-    },
-
-    /* Cipher 39 */
-    {
-     TLS1_TXT_DHE_RSA_WITH_AES_256_SHA, TLS1_CK_DHE_RSA_WITH_AES_256_SHA,
-     SSL_kDHE, SSL_aRSA, SSL_AES256, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 256, 256,
-    },
-
-
-    /* TLS v1.2 ciphersuites */
-
-    /* Cipher 3C */
-    {
-     TLS1_TXT_RSA_WITH_AES_128_SHA256, TLS1_CK_RSA_WITH_AES_128_SHA256,
-     SSL_kRSA, SSL_aRSA, SSL_AES128, SSL_SHA256, SSL_TLSV1_2,
-     SSL_HIGH | SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, 128, 128,
-    },
-
-    /* Cipher 3D */
-    {
-     TLS1_TXT_RSA_WITH_AES_256_SHA256, TLS1_CK_RSA_WITH_AES_256_SHA256,
-     SSL_kRSA, SSL_aRSA, SSL_AES256, SSL_SHA256, SSL_TLSV1_2,
-     SSL_HIGH | SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, 256, 256,
-    },
-
-    /* Cipher 67 */
-    {
-     TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256,
-     TLS1_CK_DHE_RSA_WITH_AES_128_SHA256, SSL_kDHE, SSL_aRSA, SSL_AES128,
-     SSL_SHA256, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
-     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, 128, 128,
-    },
-
-    /* Cipher 6B */
-    {
-     TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256,
-     TLS1_CK_DHE_RSA_WITH_AES_256_SHA256, SSL_kDHE, SSL_aRSA, SSL_AES256,
-     SSL_SHA256, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
-     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, 256, 256,
-    },
-
-    /* Cipher 8A */
-    {
-     TLS1_TXT_PSK_WITH_RC4_128_SHA, TLS1_CK_PSK_WITH_RC4_128_SHA, SSL_kPSK,
-     SSL_aPSK, SSL_RC4, SSL_SHA1, SSL_TLSV1, SSL_MEDIUM,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 128, 128,
-    },
-
-    /* Cipher 8C */
-    {
-     TLS1_TXT_PSK_WITH_AES_128_CBC_SHA, TLS1_CK_PSK_WITH_AES_128_CBC_SHA,
-     SSL_kPSK, SSL_aPSK, SSL_AES128, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 128, 128,
-    },
-
-    /* Cipher 8D */
-    {
-     TLS1_TXT_PSK_WITH_AES_256_CBC_SHA, TLS1_CK_PSK_WITH_AES_256_CBC_SHA,
-     SSL_kPSK, SSL_aPSK, SSL_AES256, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 256, 256,
-    },
-
-
-    /* GCM ciphersuites from RFC5288 */
-
-    /* Cipher 9C */
-    {
-     TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256,
-     TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, SSL_kRSA, SSL_aRSA, SSL_AES128GCM,
-     SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
-     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256 | SSL_CIPHER_ALGORITHM2_AEAD |
-         SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
-     128, 128,
-    },
-
-    /* Cipher 9D */
-    {
-     TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384,
-     TLS1_CK_RSA_WITH_AES_256_GCM_SHA384, SSL_kRSA, SSL_aRSA, SSL_AES256GCM,
-     SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
-     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384 | SSL_CIPHER_ALGORITHM2_AEAD |
-         SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
-     256, 256,
-    },
-
-    /* Cipher 9E */
-    {
-     TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256,
-     TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, SSL_kDHE, SSL_aRSA, SSL_AES128GCM,
-     SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
-     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256 | SSL_CIPHER_ALGORITHM2_AEAD |
-         SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
-     128, 128,
-    },
-
-    /* Cipher 9F */
-    {
-     TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384,
-     TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384, SSL_kDHE, SSL_aRSA, SSL_AES256GCM,
-     SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
-     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384 | SSL_CIPHER_ALGORITHM2_AEAD |
-         SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
-     256, 256,
-    },
-
-    /* Cipher C007 */
-    {
-     TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA,
-     TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA, SSL_kECDHE, SSL_aECDSA, SSL_RC4,
-     SSL_SHA1, SSL_TLSV1, SSL_MEDIUM, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 128,
-     128,
-    },
-
-    /* Cipher C009 */
-    {
-     TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
-     TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, SSL_kECDHE, SSL_aECDSA,
-     SSL_AES128, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 128, 128,
-    },
-
-    /* Cipher C00A */
-    {
-     TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
-     TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, SSL_kECDHE, SSL_aECDSA,
-     SSL_AES256, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 256, 256,
-    },
-
-    /* Cipher C011 */
-    {
-     TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA, TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA,
-     SSL_kECDHE, SSL_aRSA, SSL_RC4, SSL_SHA1, SSL_TLSV1, SSL_MEDIUM,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 128, 128,
-    },
-
-    /* Cipher C013 */
-    {
-     TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA,
-     TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, SSL_kECDHE, SSL_aRSA, SSL_AES128,
-     SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 128, 128,
-    },
-
-    /* Cipher C014 */
-    {
-     TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA,
-     TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, SSL_kECDHE, SSL_aRSA, SSL_AES256,
-     SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
-     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 256, 256,
-    },
-
-
-    /* HMAC based TLS v1.2 ciphersuites from RFC5289 */
-
-    /* Cipher C023 */
-    {
-     TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256,
-     TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256, SSL_kECDHE, SSL_aECDSA,
-     SSL_AES128, SSL_SHA256, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
-     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, 128, 128,
-    },
-
-    /* Cipher C024 */
-    {
-     TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384,
-     TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384, SSL_kECDHE, SSL_aECDSA,
-     SSL_AES256, SSL_SHA384, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
-     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, 256, 256,
-    },
-
-    /* Cipher C027 */
-    {
-     TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256,
-     TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256, SSL_kECDHE, SSL_aRSA, SSL_AES128,
-     SSL_SHA256, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
-     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, 128, 128,
-    },
-
-    /* Cipher C028 */
-    {
-     TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384,
-     TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384, SSL_kECDHE, SSL_aRSA, SSL_AES256,
-     SSL_SHA384, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
-     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, 256, 256,
-    },
-
-
-    /* GCM based TLS v1.2 ciphersuites from RFC5289 */
-
-    /* Cipher C02B */
-    {
-     TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
-     TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, SSL_kECDHE, SSL_aECDSA,
-     SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
-     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256 | SSL_CIPHER_ALGORITHM2_AEAD |
-         SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
-     128, 128,
-    },
-
-    /* Cipher C02C */
-    {
-     TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
-     TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, SSL_kECDHE, SSL_aECDSA,
-     SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
-     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384 | SSL_CIPHER_ALGORITHM2_AEAD |
-         SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
-     256, 256,
-    },
-
-    /* Cipher C02F */
-    {
-     TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
-     TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, SSL_kECDHE, SSL_aRSA,
-     SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
-     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256 | SSL_CIPHER_ALGORITHM2_AEAD |
-         SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
-     128, 128,
-    },
-
-    /* Cipher C030 */
-    {
-     TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
-     TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, SSL_kECDHE, SSL_aRSA,
-     SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
-     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384 | SSL_CIPHER_ALGORITHM2_AEAD |
-         SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
-     256, 256,
-    },
-
-
-    /* ECDH PSK ciphersuites */
-
-    /* Cipher CAFE */
-#if !defined(ANDROID)
-    {
-     TLS1_TXT_ECDHE_PSK_WITH_AES_128_GCM_SHA256,
-     TLS1_CK_ECDHE_PSK_WITH_AES_128_GCM_SHA256, SSL_kECDHE, SSL_aPSK,
-     SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH,
-     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256 | SSL_CIPHER_ALGORITHM2_AEAD |
-         SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
-     128, 128,
-    },
-
-    {
-     TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305,
-     TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, SSL_kECDHE, SSL_aRSA,
-     SSL_CHACHA20POLY1305, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH,
-     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256 | SSL_CIPHER_ALGORITHM2_AEAD,
-     256, 0,
-    },
-
-    {
-     TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
-     TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, SSL_kECDHE, SSL_aECDSA,
-     SSL_CHACHA20POLY1305, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH,
-     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256 | SSL_CIPHER_ALGORITHM2_AEAD,
-     256, 0,
-    },
-
-    {
-     TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305,
-     TLS1_CK_DHE_RSA_CHACHA20_POLY1305, SSL_kDHE, SSL_aRSA,
-     SSL_CHACHA20POLY1305, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH,
-     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256 | SSL_CIPHER_ALGORITHM2_AEAD,
-     256, 0,
-    },
-#endif
-};
-
 const SSL3_ENC_METHOD SSLv3_enc_data = {
-    tls1_enc,
     ssl3_prf,
     tls1_setup_key_block,
     tls1_generate_master_secret,
@@ -494,23 +174,8 @@
     0,
 };
 
-size_t ssl3_num_ciphers(void) { return SSL3_NUM_CIPHERS; }
-
-const SSL_CIPHER *ssl3_get_cipher(size_t i) {
-  if (i >= SSL3_NUM_CIPHERS) {
-    return NULL;
-  }
-
-  return &ssl3_ciphers[SSL3_NUM_CIPHERS - 1 - i];
-}
-
-int ssl3_pending(const SSL *s) {
-  if (s->rstate == SSL_ST_READ_BODY) {
-    return 0;
-  }
-
-  return (s->s3->rrec.type == SSL3_RT_APPLICATION_DATA) ? s->s3->rrec.length
-                                                        : 0;
+int ssl3_supports_cipher(const SSL_CIPHER *cipher) {
+  return 1;
 }
 
 int ssl3_set_handshake_header(SSL *s, int htype, unsigned long len) {
@@ -535,7 +200,6 @@
   }
   memset(s3, 0, sizeof *s3);
   memset(s3->rrec.seq_num, 0, sizeof(s3->rrec.seq_num));
-  memset(s3->wrec.seq_num, 0, sizeof(s3->wrec.seq_num));
 
   s->s3 = s3;
 
@@ -948,27 +612,6 @@
   return 1;
 }
 
-/* ssl3_get_cipher_by_value returns the SSL_CIPHER with value |value| or NULL
- * if none exists.
- *
- * This function needs to check if the ciphers required are actually
- * available. */
-const SSL_CIPHER *ssl3_get_cipher_by_value(uint16_t value) {
-  SSL_CIPHER c;
-
-  c.id = 0x03000000L | value;
-  return bsearch(&c, ssl3_ciphers, SSL3_NUM_CIPHERS, sizeof(SSL_CIPHER),
-                 ssl_cipher_id_cmp);
-}
-
-/* ssl3_get_cipher_by_value returns the cipher value of |c|. */
-uint16_t ssl3_get_cipher_value(const SSL_CIPHER *c) {
-  uint32_t id = c->id;
-  /* All ciphers are SSLv3 now. */
-  assert((id & 0xff000000) == 0x03000000);
-  return id & 0xffff;
-}
-
 struct ssl_cipher_preference_list_st *ssl_get_cipher_preferences(SSL *s) {
   if (s->cipher_list != NULL) {
     return s->cipher_list;
@@ -1121,106 +764,14 @@
   return 1;
 }
 
-int ssl3_shutdown(SSL *s) {
-  int ret;
-
-  /* Do nothing if configured not to send a close_notify. */
-  if (s->quiet_shutdown) {
-    s->shutdown = SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN;
-    return 1;
-  }
-
-  if (!(s->shutdown & SSL_SENT_SHUTDOWN)) {
-    s->shutdown |= SSL_SENT_SHUTDOWN;
-    ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY);
-
-    /* our shutdown alert has been sent now, and if it still needs to be
-     * written, s->s3->alert_dispatch will be true */
-    if (s->s3->alert_dispatch) {
-      return -1; /* return WANT_WRITE */
-    }
-  } else if (s->s3->alert_dispatch) {
-    /* resend it if not sent */
-    ret = s->method->ssl_dispatch_alert(s);
-    if (ret == -1) {
-      /* we only get to return -1 here the 2nd/Nth invocation, we must  have
-       * already signalled return 0 upon a previous invoation, return
-       * WANT_WRITE */
-      return ret;
-    }
-  } else if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) {
-    /* If we are waiting for a close from our peer, we are closed */
-    s->method->ssl_read_bytes(s, 0, NULL, 0, 0);
-    if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) {
-      return -1; /* return WANT_READ */
-    }
-  }
-
-  if (s->shutdown == (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN) &&
-      !s->s3->alert_dispatch) {
-    return 1;
-  } else {
-    return 0;
-  }
-}
-
-int ssl3_write(SSL *s, const void *buf, int len) {
-  ERR_clear_system_error();
-  if (s->s3->renegotiate) {
-    ssl3_renegotiate_check(s);
-  }
-
-  return s->method->ssl_write_bytes(s, SSL3_RT_APPLICATION_DATA, buf, len);
-}
-
-static int ssl3_read_internal(SSL *s, void *buf, int len, int peek) {
-  ERR_clear_system_error();
-  if (s->s3->renegotiate) {
-    ssl3_renegotiate_check(s);
-  }
-
-  return s->method->ssl_read_bytes(s, SSL3_RT_APPLICATION_DATA, buf, len, peek);
-}
-
-int ssl3_read(SSL *s, void *buf, int len) {
-  return ssl3_read_internal(s, buf, len, 0);
-}
-
-int ssl3_peek(SSL *s, void *buf, int len) {
-  return ssl3_read_internal(s, buf, len, 1);
-}
-
-int ssl3_renegotiate(SSL *s) {
-  if (s->handshake_func == NULL) {
-    return 1;
-  }
-
-  s->s3->renegotiate = 1;
-  return 1;
-}
-
-int ssl3_renegotiate_check(SSL *s) {
-  if (s->s3->renegotiate && s->s3->rbuf.left == 0 && s->s3->wbuf.left == 0 &&
-      !SSL_in_init(s)) {
-    /* if we are the server, and we have sent a 'RENEGOTIATE' message, we
-     * need to go to SSL_ST_ACCEPT. */
-    s->state = SSL_ST_RENEGOTIATE;
-    s->s3->renegotiate = 0;
-    s->s3->total_renegotiations++;
-    return 1;
-  }
-
-  return 0;
-}
-
 /* If we are using default SHA1+MD5 algorithms switch to new SHA256 PRF and
  * handshake macs if required. */
 uint32_t ssl_get_algorithm2(SSL *s) {
-  static const uint32_t kMask = SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF;
+  static const uint32_t kMask = SSL_HANDSHAKE_MAC_DEFAULT;
   uint32_t alg2 = s->s3->tmp.new_cipher->algorithm2;
   if (s->enc_method->enc_flags & SSL_ENC_FLAG_SHA256_PRF &&
       (alg2 & kMask) == kMask) {
-    return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256;
+    return SSL_HANDSHAKE_MAC_SHA256;
   }
   return alg2;
 }
diff --git a/src/ssl/s3_meth.c b/src/ssl/s3_meth.c
index 28b9051..66bbb29 100644
--- a/src/ssl/s3_meth.c
+++ b/src/ssl/s3_meth.c
@@ -63,21 +63,14 @@
     ssl3_free,
     ssl3_accept,
     ssl3_connect,
-    ssl3_read,
-    ssl3_peek,
-    ssl3_write,
-    ssl3_shutdown,
-    ssl3_renegotiate,
-    ssl3_renegotiate_check,
     ssl3_get_message,
-    ssl3_read_bytes,
-    ssl3_write_bytes,
+    ssl3_read_app_data,
+    ssl3_read_close_notify,
+    ssl3_write_app_data,
     ssl3_dispatch_alert,
     ssl3_ctrl,
     ssl3_ctx_ctrl,
-    ssl3_pending,
-    ssl3_num_ciphers,
-    ssl3_get_cipher,
+    ssl3_supports_cipher,
     SSL3_HM_HEADER_LENGTH,
     ssl3_set_handshake_header,
     ssl3_handshake_write,
diff --git a/src/ssl/s3_pkt.c b/src/ssl/s3_pkt.c
index c42d000..4a9ae83 100644
--- a/src/ssl/s3_pkt.c
+++ b/src/ssl/s3_pkt.c
@@ -129,9 +129,13 @@
    * if |extend| is 1, increase packet by another n bytes.
    *
    * The packet will be in the sub-array of |s->s3->rbuf.buf| specified by
-   * |s->packet| and |s->packet_length|. (If |s->read_ahead| is set and |extend|
-   * is 0, additional bytes may be read into |rbuf|, up to the size of the
-   * buffer.) */
+   * |s->packet| and |s->packet_length|. (If DTLS and |extend| is 0, additional
+   * bytes will be read into |rbuf|, up to the size of the buffer.)
+   *
+   * TODO(davidben): |dtls1_get_record| and |ssl3_get_record| have very
+   * different needs. Separate the two record layers. In DTLS, |BIO_read| is
+   * called at most once, and only when |extend| is 0. In TLS, the buffer never
+   * contains more than one record. */
   int i, len, left;
   uintptr_t align = 0;
   uint8_t *pkt;
@@ -173,10 +177,10 @@
     /* ... now we can act as if 'extend' was set */
   }
 
-  /* For DTLS/UDP reads should not span multiple packets because the read
-   * operation returns the whole packet at once (as long as it fits into the
-   * buffer). */
-  if (SSL_IS_DTLS(s) && left > 0 && n > left) {
+  /* In DTLS, if there is leftover data from the previous packet or |extend| is
+   * true, clamp to the previous read. DTLS records may not span packet
+   * boundaries. */
+  if (SSL_IS_DTLS(s) && n > left && (left > 0 || extend)) {
     n = left;
   }
 
@@ -207,7 +211,7 @@
   }
 
   int max = n;
-  if (s->read_ahead && !extend) {
+  if (SSL_IS_DTLS(s) && !extend) {
     max = rb->len - rb->offset;
   }
 
@@ -262,16 +266,14 @@
  * ssl->s3->rrec.length  - number of bytes */
 /* used only by ssl3_read_bytes */
 static int ssl3_get_record(SSL *s) {
-  int ssl_major, ssl_minor, al;
-  int n, i, ret = -1;
-  SSL3_RECORD *rr;
+  uint8_t ssl_major, ssl_minor;
+  int al, n, i, ret = -1;
+  SSL3_RECORD *rr = &s->s3->rrec;
   uint8_t *p;
-  short version;
+  uint16_t version;
   size_t extra;
   unsigned empty_record_count = 0;
 
-  rr = &s->s3->rrec;
-
 again:
   /* check if we have the header */
   if (s->rstate != SSL_ST_READ_BODY ||
@@ -296,7 +298,7 @@
     rr->type = *(p++);
     ssl_major = *(p++);
     ssl_minor = *(p++);
-    version = (ssl_major << 8) | ssl_minor;
+    version = (((uint16_t)ssl_major) << 8) | ssl_minor;
     n2s(p, rr->length);
 
     if (s->s3->have_version && version != s->version) {
@@ -339,40 +341,40 @@
 
   s->rstate = SSL_ST_READ_HEADER; /* set state for later operations */
 
-  /* At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length, and
-   * we have that many bytes in s->packet. */
-  rr->input = &s->packet[SSL3_RT_HEADER_LENGTH];
+  /* |rr->data| points to |rr->length| bytes of ciphertext in |s->packet|. */
+  rr->data = &s->packet[SSL3_RT_HEADER_LENGTH];
 
-  /* ok, we can now read from |s->packet| data into |rr|. |rr->input| points at
-   * |rr->length| bytes, which need to be copied into |rr->data| by decryption.
-   * When the data is 'copied' into the |rr->data| buffer, |rr->input| will be
-   * pointed at the new buffer. */
-
-  /* We now have - encrypted [ MAC [ compressed [ plain ] ] ]
-   * rr->length bytes of encrypted compressed stuff. */
-
-  /* decrypt in place in 'rr->input' */
-  rr->data = rr->input;
-
-  if (!s->enc_method->enc(s, 0)) {
+  /* Decrypt the packet in-place.
+   *
+   * TODO(davidben): This assumes |s->version| is the same as the record-layer
+   * version which isn't always true, but it only differs with the NULL cipher
+   * which ignores the parameter. */
+  size_t plaintext_len;
+  if (!SSL_AEAD_CTX_open(s->aead_read_ctx, rr->data, &plaintext_len, rr->length,
+                         rr->type, s->version, s->s3->read_sequence, rr->data,
+                         rr->length)) {
     al = SSL_AD_BAD_RECORD_MAC;
     OPENSSL_PUT_ERROR(SSL, ssl3_get_record,
                       SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
     goto f_err;
   }
-
-  if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH + extra) {
+  if (!ssl3_record_sequence_update(s->s3->read_sequence, 8)) {
+    goto err;
+  }
+  if (plaintext_len > SSL3_RT_MAX_PLAIN_LENGTH + extra) {
     al = SSL_AD_RECORD_OVERFLOW;
     OPENSSL_PUT_ERROR(SSL, ssl3_get_record, SSL_R_DATA_LENGTH_TOO_LONG);
     goto f_err;
   }
+  assert(plaintext_len <= (1u << 16));
+  rr->length = plaintext_len;
 
   rr->off = 0;
   /* So at this point the following is true:
    * ssl->s3->rrec.type is the type of record;
    * ssl->s3->rrec.length is the number of bytes in the record;
    * ssl->s3->rrec.off is the offset to first valid byte;
-   * ssl->s3->rrec.data is where to take bytes from (increment after use). */
+   * ssl->s3->rrec.data the first byte of the record body. */
 
   /* we have pulled in a full packet so zero things */
   s->packet_length = 0;
@@ -396,6 +398,10 @@
   return ret;
 }
 
+int ssl3_write_app_data(SSL *ssl, const void *buf, int len) {
+  return ssl3_write_bytes(ssl, SSL3_RT_APPLICATION_DATA, buf, len);
+}
+
 /* Call this to write data in records of type |type|. It will return <= 0 if
  * not all data has been sent or non-blocking IO. */
 int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) {
@@ -471,8 +477,8 @@
 
 /* ssl3_seal_record seals a new record of type |type| and plaintext |in| and
  * writes it to |out|. At most |max_out| bytes will be written. It returns one
- * on success and zero on error. On success, |s->s3->wrec| is updated to include
- * the new record. */
+ * on success and zero on error. On success, it updates the write sequence
+ * number. */
 static int ssl3_seal_record(SSL *s, uint8_t *out, size_t *out_len,
                             size_t max_out, uint8_t type, const uint8_t *in,
                             size_t in_len) {
@@ -485,61 +491,30 @@
 
   /* Some servers hang if initial ClientHello is larger than 256 bytes and
    * record version number > TLS 1.0. */
+  uint16_t wire_version = s->version;
   if (!s->s3->have_version && s->version > SSL3_VERSION) {
-    out[1] = TLS1_VERSION >> 8;
-    out[2] = TLS1_VERSION & 0xff;
-  } else {
-    out[1] = s->version >> 8;
-    out[2] = s->version & 0xff;
+    wire_version = TLS1_VERSION;
+  }
+  out[1] = wire_version >> 8;
+  out[2] = wire_version & 0xff;
+
+  size_t ciphertext_len;
+  if (!SSL_AEAD_CTX_seal(s->aead_write_ctx, out + SSL3_RT_HEADER_LENGTH,
+                         &ciphertext_len, max_out - SSL3_RT_HEADER_LENGTH,
+                         type, wire_version, s->s3->write_sequence, in,
+                         in_len) ||
+      !ssl3_record_sequence_update(s->s3->write_sequence, 8)) {
+    return 0;
   }
 
-  size_t explicit_nonce_len = 0;
-  if (s->aead_write_ctx != NULL &&
-      s->aead_write_ctx->variable_nonce_included_in_record) {
-    explicit_nonce_len = s->aead_write_ctx->variable_nonce_len;
-  }
-  size_t max_overhead = 0;
-  if (s->aead_write_ctx != NULL) {
-    max_overhead = s->aead_write_ctx->tag_len;
-  }
-
-  /* Assemble the input for |s->enc_method->enc|. The input is the plaintext
-   * with |explicit_nonce_len| bytes of space prepended for the explicit
-   * nonce. The input is copied into |out| and then encrypted in-place to take
-   * advantage of alignment.
-   *
-   * TODO(davidben): |tls1_enc| should accept its inputs and outputs directly
-   * rather than looking up in |wrec| and friends. The |max_overhead| bounds
-   * check would also be unnecessary if |max_out| were passed down. */
-  SSL3_RECORD *wr = &s->s3->wrec;
-  size_t plaintext_len = in_len + explicit_nonce_len;
-  if (plaintext_len < in_len || plaintext_len > INT_MAX ||
-      plaintext_len + max_overhead < plaintext_len) {
+  if (ciphertext_len >= 1 << 16) {
     OPENSSL_PUT_ERROR(SSL, ssl3_seal_record, ERR_R_OVERFLOW);
     return 0;
   }
-  if (max_out - SSL3_RT_HEADER_LENGTH < plaintext_len + max_overhead) {
-    OPENSSL_PUT_ERROR(SSL, ssl3_seal_record, SSL_R_BUFFER_TOO_SMALL);
-    return 0;
-  }
-  wr->type = type;
-  wr->input = out + SSL3_RT_HEADER_LENGTH;
-  wr->data = wr->input;
-  wr->length = plaintext_len;
-  memcpy(wr->input + explicit_nonce_len, in, in_len);
+  out[3] = ciphertext_len >> 8;
+  out[4] = ciphertext_len & 0xff;
 
-  if (!s->enc_method->enc(s, 1)) {
-    return 0;
-  }
-
-  /* |wr->length| has now been set to the ciphertext length. */
-  if (wr->length >= 1 << 16) {
-    OPENSSL_PUT_ERROR(SSL, ssl3_seal_record, ERR_R_OVERFLOW);
-    return 0;
-  }
-  out[3] = wr->length >> 8;
-  out[4] = wr->length & 0xff;
-  *out_len = SSL3_RT_HEADER_LENGTH + (size_t)wr->length;
+  *out_len = SSL3_RT_HEADER_LENGTH + ciphertext_len;
 
  if (s->msg_callback) {
    s->msg_callback(1 /* write */, 0, SSL3_RT_HEADER, out, SSL3_RT_HEADER_LENGTH,
@@ -696,6 +671,14 @@
   return 1;
 }
 
+int ssl3_read_app_data(SSL *ssl, uint8_t *buf, int len, int peek) {
+  return ssl3_read_bytes(ssl, SSL3_RT_APPLICATION_DATA, buf, len, peek);
+}
+
+void ssl3_read_close_notify(SSL *ssl) {
+  ssl3_read_bytes(ssl, 0, NULL, 0, 0);
+}
+
 /* Return up to 'len' payload bytes received in 'type' records.
  * 'type' is one of the following:
  *
@@ -859,22 +842,18 @@
     return n;
   }
 
-
-  /* If we get here, then type != rr->type; if we have a handshake message,
-   * then it was unexpected (Hello Request or Client Hello). */
-
-  /* In case of record types for which we have 'fragment' storage, fill that so
-   * that we can process the data at a fixed place. */
+  /* Process unexpected records. */
 
   if (rr->type == SSL3_RT_HANDSHAKE) {
     /* If peer renegotiations are disabled, all out-of-order handshake records
-     * are fatal. */
-    if (s->reject_peer_renegotiations) {
+     * are fatal. Renegotiations as a server are never supported. */
+    if (!s->accept_peer_renegotiations || s->server) {
       al = SSL_AD_NO_RENEGOTIATION;
       OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_NO_RENEGOTIATION);
       goto f_err;
     }
 
+    /* HelloRequests may be fragmented across multiple records. */
     const size_t size = sizeof(s->s3->handshake_fragment);
     const size_t avail = size - s->s3->handshake_fragment_len;
     const size_t todo = (rr->length < avail) ? rr->length : avail;
@@ -886,45 +865,53 @@
     if (s->s3->handshake_fragment_len < size) {
       goto start; /* fragment was too small */
     }
-  }
 
-  /* s->s3->handshake_fragment_len == 4  iff  rr->type == SSL3_RT_HANDSHAKE;
-   * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) */
-
-  /* If we are a client, check for an incoming 'Hello Request': */
-  if (!s->server && s->s3->handshake_fragment_len >= 4 &&
-      s->s3->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST &&
-      s->session != NULL && s->session->cipher != NULL) {
-    s->s3->handshake_fragment_len = 0;
-
-    if (s->s3->handshake_fragment[1] != 0 ||
+    /* Parse out and consume a HelloRequest. */
+    if (s->s3->handshake_fragment[0] != SSL3_MT_HELLO_REQUEST ||
+        s->s3->handshake_fragment[1] != 0 ||
         s->s3->handshake_fragment[2] != 0 ||
         s->s3->handshake_fragment[3] != 0) {
       al = SSL_AD_DECODE_ERROR;
       OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_BAD_HELLO_REQUEST);
       goto f_err;
     }
+    s->s3->handshake_fragment_len = 0;
 
     if (s->msg_callback) {
       s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
                       s->s3->handshake_fragment, 4, s, s->msg_callback_arg);
     }
 
-    if (SSL_is_init_finished(s) && !s->s3->renegotiate) {
-      ssl3_renegotiate(s);
-      if (ssl3_renegotiate_check(s)) {
-        i = s->handshake_func(s);
-        if (i < 0) {
-          return i;
-        }
-        if (i == 0) {
-          OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_SSL_HANDSHAKE_FAILURE);
-          return -1;
-        }
-      }
+    if (!SSL_is_init_finished(s) || !s->s3->initial_handshake_complete) {
+      /* This cannot happen. If a handshake is in progress, |type| must be
+       * |SSL3_RT_HANDSHAKE|. */
+      assert(0);
+      OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, ERR_R_INTERNAL_ERROR);
+      goto err;
     }
-    /* we either finished a handshake or ignored the request, now try again to
-     * obtain the (application) data we were asked for */
+
+    /* Renegotiation is only supported at quiescent points in the application
+     * protocol, namely in HTTPS, just before reading the HTTP response. Require
+     * the record-layer be idle and avoid complexities of sending a handshake
+     * record while an application_data record is being written. */
+    if (s->s3->wbuf.left != 0 || s->s3->rbuf.left != 0) {
+      al = SSL_AD_NO_RENEGOTIATION;
+      OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_NO_RENEGOTIATION);
+      goto f_err;
+    }
+
+    /* Begin a new handshake. */
+    s->state = SSL_ST_CONNECT;
+    i = s->handshake_func(s);
+    if (i < 0) {
+      return i;
+    }
+    if (i == 0) {
+      OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_SSL_HANDSHAKE_FAILURE);
+      return -1;
+    }
+
+    /* The handshake completed synchronously. Continue reading records. */
     goto start;
   }
 
@@ -1043,25 +1030,6 @@
     }
   }
 
-  /* Unexpected handshake message (Client Hello, or protocol violation) */
-  if (s->s3->handshake_fragment_len >= 4 && !s->in_handshake) {
-    if ((s->state & SSL_ST_MASK) == SSL_ST_OK) {
-      s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT;
-      s->renegotiate = 1;
-      s->new_session = 1;
-    }
-    i = s->handshake_func(s);
-    if (i < 0) {
-      return i;
-    }
-    if (i == 0) {
-      OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_SSL_HANDSHAKE_FAILURE);
-      return -1;
-    }
-
-    goto start;
-  }
-
   /* We already handled these. */
   assert(rr->type != SSL3_RT_CHANGE_CIPHER_SPEC && rr->type != SSL3_RT_ALERT &&
          rr->type != SSL3_RT_HANDSHAKE);
diff --git a/src/ssl/s3_srvr.c b/src/ssl/s3_srvr.c
index 3cc3032..a72e17e 100644
--- a/src/ssl/s3_srvr.c
+++ b/src/ssl/s3_srvr.c
@@ -207,79 +207,11 @@
     state = s->state;
 
     switch (s->state) {
-      case SSL_ST_RENEGOTIATE:
-        /* This state is the renegotiate entry point. It sends a HelloRequest
-         * and nothing else. */
-        s->renegotiate = 1;
-
-        if (cb != NULL) {
-          cb(s, SSL_CB_HANDSHAKE_START, 1);
-        }
-
-        if (s->init_buf == NULL) {
-          buf = BUF_MEM_new();
-          if (!buf || !BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
-            ret = -1;
-            goto end;
-          }
-          s->init_buf = buf;
-          buf = NULL;
-        }
-        s->init_num = 0;
-
-        if (!s->s3->send_connection_binding &&
-            !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
-          /* Server attempting to renegotiate with client that doesn't support
-           * secure renegotiation. */
-          OPENSSL_PUT_ERROR(SSL, ssl3_accept,
-                            SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
-          ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
-          ret = -1;
-          goto end;
-        }
-
-        s->state = SSL3_ST_SW_HELLO_REQ_A;
-        break;
-
-      case SSL3_ST_SW_HELLO_REQ_A:
-      case SSL3_ST_SW_HELLO_REQ_B:
-        s->shutdown = 0;
-        ret = ssl3_send_hello_request(s);
-        if (ret <= 0) {
-          goto end;
-        }
-        s->s3->tmp.next_state = SSL3_ST_SW_HELLO_REQ_C;
-        s->state = SSL3_ST_SW_FLUSH;
-        s->init_num = 0;
-
-        if (!ssl3_init_finished_mac(s)) {
-          OPENSSL_PUT_ERROR(SSL, ssl3_accept, ERR_R_INTERNAL_ERROR);
-          ret = -1;
-          goto end;
-        }
-        break;
-
-      case SSL3_ST_SW_HELLO_REQ_C:
-        s->state = SSL_ST_OK;
-        break;
-
       case SSL_ST_ACCEPT:
-      case SSL_ST_BEFORE | SSL_ST_ACCEPT:
-        /* This state is the entry point for the handshake itself (initial and
-         * renegotiation).  */
         if (cb != NULL) {
           cb(s, SSL_CB_HANDSHAKE_START, 1);
         }
 
-        if ((s->version >> 8) != 3) {
-          /* TODO(davidben): Some consumers clear |s->version| to break the
-           * handshake in a callback. Remove this when they're using proper
-           * APIs. */
-          OPENSSL_PUT_ERROR(SSL, ssl3_accept, ERR_R_INTERNAL_ERROR);
-          ret = -1;
-          goto end;
-        }
-
         if (s->init_buf == NULL) {
           buf = BUF_MEM_new();
           if (!buf || !BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
@@ -337,7 +269,6 @@
         if (ret <= 0) {
           goto end;
         }
-        s->renegotiate = 2;
         s->state = SSL3_ST_SW_SRVR_HELLO_A;
         s->init_num = 0;
         break;
@@ -406,35 +337,16 @@
 
       case SSL3_ST_SW_CERT_REQ_A:
       case SSL3_ST_SW_CERT_REQ_B:
-        if (/* don't request cert unless asked for it: */
-            !(s->verify_mode & SSL_VERIFY_PEER) ||
-            /* Don't request a certificate if an obc was presented */
-            ((s->verify_mode & SSL_VERIFY_PEER_IF_NO_OBC) &&
-             s->s3->tlsext_channel_id_valid) ||
-            /* if SSL_VERIFY_CLIENT_ONCE is set,
-             * don't request cert during re-negotiation: */
-            ((s->session->peer != NULL) &&
-             (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) ||
-            /* With normal PSK Certificates and
-             * Certificate Requests are omitted */
-            (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) {
-          /* no cert request */
-          skip = 1;
-          s->s3->tmp.cert_request = 0;
-          s->state = SSL3_ST_SW_SRVR_DONE_A;
-          if (s->s3->handshake_buffer &&
-              !ssl3_digest_cached_records(s, free_handshake_buffer)) {
-            return -1;
-          }
-        } else {
-          s->s3->tmp.cert_request = 1;
+        if (s->s3->tmp.cert_request) {
           ret = ssl3_send_certificate_request(s);
           if (ret <= 0) {
             goto end;
           }
-          s->state = SSL3_ST_SW_SRVR_DONE_A;
-          s->init_num = 0;
+        } else {
+          skip = 1;
         }
+        s->state = SSL3_ST_SW_SRVR_DONE_A;
+        s->init_num = 0;
         break;
 
       case SSL3_ST_SW_SRVR_DONE_A:
@@ -640,16 +552,12 @@
           s->session->peer = NULL;
         }
 
-        if (s->renegotiate == 2) {
-          /* skipped if we just sent a HelloRequest */
-          s->renegotiate = 0;
-          s->new_session = 0;
+        s->s3->initial_handshake_complete = 1;
 
-          ssl_update_cache(s, SSL_SESS_CACHE_SERVER);
+        ssl_update_cache(s, SSL_SESS_CACHE_SERVER);
 
-          if (cb != NULL) {
-            cb(s, SSL_CB_HANDSHAKE_DONE, 1);
-          }
+        if (cb != NULL) {
+          cb(s, SSL_CB_HANDSHAKE_DONE, 1);
         }
 
         ret = 1;
@@ -898,20 +806,8 @@
   return 1;
 }
 
-int ssl3_send_hello_request(SSL *s) {
-  if (s->state == SSL3_ST_SW_HELLO_REQ_A) {
-    if (!ssl_set_handshake_header(s, SSL3_MT_HELLO_REQUEST, 0)) {
-      return -1;
-    }
-    s->state = SSL3_ST_SW_HELLO_REQ_B;
-  }
-
-  /* SSL3_ST_SW_HELLO_REQ_B */
-  return ssl_do_write(s);
-}
-
 int ssl3_get_client_hello(SSL *s) {
-  int i, ok, al = SSL_AD_INTERNAL_ERROR, ret = -1;
+  int ok, al = SSL_AD_INTERNAL_ERROR, ret = -1;
   long n;
   const SSL_CIPHER *c;
   STACK_OF(SSL_CIPHER) *ciphers = NULL;
@@ -1011,6 +907,11 @@
     }
   }
 
+  /* Note: This codepath may run twice if |ssl_get_prev_session| completes
+   * asynchronously.
+   *
+   * TODO(davidben): Clean up the order of events around ClientHello
+   * processing. */
   if (!s->s3->have_version) {
     /* Select version to use */
     uint16_t version = ssl3_get_mutual_version(s, client_version);
@@ -1034,41 +935,49 @@
   }
 
   s->hit = 0;
-  /* Versions before 0.9.7 always allow clients to resume sessions in
-   * renegotiation. 0.9.7 and later allow this by default, but optionally
-   * ignore resumption requests with flag
-   * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION (it's a new flag rather than
-   * a change to default behavior so that applications relying on this for
-   * security won't even compile against older library versions).
-   *
-   * 1.0.1 and later also have a function SSL_renegotiate_abbreviated() to
-   * request renegotiation but not a new session (s->new_session remains
-   * unset): for servers, this essentially just means that the
-   * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION setting will be ignored. */
-  if (s->new_session &&
-      (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)) {
-    if (!ssl_get_new_session(s, 1)) {
-      goto err;
-    }
-  } else {
-    i = ssl_get_prev_session(s, &early_ctx);
-    if (i == PENDING_SESSION) {
-      s->rwstate = SSL_PENDING_SESSION;
-      goto err;
-    } else if (i == -1) {
-      goto err;
+  int session_ret = ssl_get_prev_session(s, &early_ctx);
+  if (session_ret == PENDING_SESSION) {
+    s->rwstate = SSL_PENDING_SESSION;
+    goto err;
+  } else if (session_ret == -1) {
+    goto err;
+  }
+
+  /* The EMS state is needed when making the resumption decision, but
+   * extensions are not normally parsed until later. This detects the EMS
+   * extension for the resumption decision and it's checked against the result
+   * of the normal parse later in this function. */
+  const uint8_t *ems_data;
+  size_t ems_len;
+  int have_extended_master_secret =
+      s->version != SSL3_VERSION &&
+      SSL_early_callback_ctx_extension_get(&early_ctx,
+                                           TLSEXT_TYPE_extended_master_secret,
+                                           &ems_data, &ems_len) &&
+      ems_len == 0;
+
+  if (session_ret == 1) {
+    if (s->session->extended_master_secret &&
+        !have_extended_master_secret) {
+      /* A ClientHello without EMS that attempts to resume a session with EMS
+       * is fatal to the connection. */
+      al = SSL_AD_HANDSHAKE_FAILURE;
+      OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello,
+                        SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION);
+      goto f_err;
     }
 
-    /* Only resume if the session's version matches the negotiated version:
-     * most clients do not accept a mismatch. */
-    if (i == 1 && s->version == s->session->ssl_version) {
-      s->hit = 1;
-    } else {
-      /* No session was found or it was unacceptable. */
-      if (!ssl_get_new_session(s, 1)) {
-        goto err;
-      }
-    }
+    s->hit =
+        /* Only resume if the session's version matches the negotiated version:
+         * most clients do not accept a mismatch. */
+        s->version == s->session->ssl_version &&
+        /* If the client offers the EMS extension, but the previous session
+         * didn't use it, then negotiate a new session. */
+        have_extended_master_secret == s->session->extended_master_secret;
+  }
+
+  if (!s->hit && !ssl_get_new_session(s, 1)) {
+    goto err;
   }
 
   if (s->ctx->dos_protection_cb != NULL && s->ctx->dos_protection_cb(&early_ctx) == 0) {
@@ -1141,6 +1050,12 @@
     goto f_err;
   }
 
+  if (have_extended_master_secret != s->s3->tmp.extended_master_secret) {
+    al = SSL_AD_INTERNAL_ERROR;
+    OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_EMS_STATE_INCONSISTENT);
+    goto f_err;
+  }
+
   /* Given ciphers and SSL_get_ciphers, we must pick a cipher */
   if (!s->hit) {
     if (ciphers == NULL) {
@@ -1171,12 +1086,27 @@
       goto f_err;
     }
     s->s3->tmp.new_cipher = c;
+
+    /* Determine whether to request a client certificate. */
+    s->s3->tmp.cert_request = !!(s->verify_mode & SSL_VERIFY_PEER);
+    /* Only request a certificate if Channel ID isn't negotiated. */
+    if ((s->verify_mode & SSL_VERIFY_PEER_IF_NO_OBC) &&
+        s->s3->tlsext_channel_id_valid) {
+      s->s3->tmp.cert_request = 0;
+    }
+    /* Plain PSK forbids Certificate and CertificateRequest. */
+    if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK) {
+      s->s3->tmp.cert_request = 0;
+    }
   } else {
     /* Session-id reuse */
     s->s3->tmp.new_cipher = s->session->cipher;
+    s->s3->tmp.cert_request = 0;
   }
 
-  if ((!SSL_USE_SIGALGS(s) || !(s->verify_mode & SSL_VERIFY_PEER)) &&
+  /* In TLS 1.2, client authentication requires hashing the handshake transcript
+   * under a different hash. Otherwise, release the handshake buffer. */
+  if ((!SSL_USE_SIGALGS(s) || !s->s3->tmp.cert_request) &&
       !ssl3_digest_cached_records(s, free_handshake_buffer)) {
     goto f_err;
   }
@@ -1235,7 +1165,8 @@
     *(p++) = s->version & 0xff;
 
     /* Random stuff */
-    if (!ssl_fill_hello_random(s, 1, s->s3->server_random, SSL3_RANDOM_SIZE)) {
+    if (!ssl_fill_hello_random(s->s3->server_random, SSL3_RANDOM_SIZE,
+                               1 /* server */)) {
       OPENSSL_PUT_ERROR(SSL, ssl3_send_server_hello, ERR_R_INTERNAL_ERROR);
       return -1;
     }
@@ -1268,7 +1199,7 @@
     p += sl;
 
     /* put the cipher */
-    s2n(ssl3_get_cipher_value(s->s3->tmp.new_cipher), p);
+    s2n(ssl_cipher_get_value(s->s3->tmp.new_cipher), p);
 
     /* put the compression method */
     *(p++) = 0;
diff --git a/src/ssl/ssl_aead_ctx.c b/src/ssl/ssl_aead_ctx.c
new file mode 100644
index 0000000..c2fba1d
--- /dev/null
+++ b/src/ssl/ssl_aead_ctx.c
@@ -0,0 +1,257 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <assert.h>
+#include <string.h>
+
+#include <openssl/aead.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#include <openssl/type_check.h>
+
+#include "internal.h"
+
+
+OPENSSL_COMPILE_ASSERT(EVP_AEAD_MAX_NONCE_LENGTH < 256,
+                       variable_nonce_len_doesnt_fit_in_uint8_t);
+
+SSL_AEAD_CTX *SSL_AEAD_CTX_new(enum evp_aead_direction_t direction,
+                               uint16_t version, const SSL_CIPHER *cipher,
+                               const uint8_t *enc_key, size_t enc_key_len,
+                               const uint8_t *mac_key, size_t mac_key_len,
+                               const uint8_t *fixed_iv, size_t fixed_iv_len) {
+  const EVP_AEAD *aead;
+  size_t discard;
+  if (!ssl_cipher_get_evp_aead(&aead, &discard, &discard, cipher, version)) {
+    OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_new, ERR_R_INTERNAL_ERROR);
+    return 0;
+  }
+
+  uint8_t merged_key[EVP_AEAD_MAX_KEY_LENGTH];
+  if (mac_key_len > 0) {
+    /* This is a "stateful" AEAD (for compatibility with pre-AEAD cipher
+     * suites). */
+    if (mac_key_len + enc_key_len + fixed_iv_len > sizeof(merged_key)) {
+      OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_new, ERR_R_INTERNAL_ERROR);
+      return 0;
+    }
+    memcpy(merged_key, mac_key, mac_key_len);
+    memcpy(merged_key + mac_key_len, enc_key, enc_key_len);
+    memcpy(merged_key + mac_key_len + enc_key_len, fixed_iv, fixed_iv_len);
+    enc_key = merged_key;
+    enc_key_len += mac_key_len;
+    enc_key_len += fixed_iv_len;
+  }
+
+  SSL_AEAD_CTX *aead_ctx = (SSL_AEAD_CTX *)OPENSSL_malloc(sizeof(SSL_AEAD_CTX));
+  if (aead_ctx == NULL) {
+    OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_new, ERR_R_MALLOC_FAILURE);
+    return NULL;
+  }
+  memset(aead_ctx, 0, sizeof(SSL_AEAD_CTX));
+  aead_ctx->cipher = cipher;
+
+  if (!EVP_AEAD_CTX_init_with_direction(
+          &aead_ctx->ctx, aead, enc_key, enc_key_len,
+          EVP_AEAD_DEFAULT_TAG_LENGTH, direction)) {
+    OPENSSL_free(aead_ctx);
+    return NULL;
+  }
+
+  assert(EVP_AEAD_nonce_length(aead) <= EVP_AEAD_MAX_NONCE_LENGTH);
+  aead_ctx->variable_nonce_len = (uint8_t)EVP_AEAD_nonce_length(aead);
+  if (mac_key_len == 0) {
+    /* For a real AEAD, the IV is the fixed part of the nonce. */
+    if (fixed_iv_len > sizeof(aead_ctx->fixed_nonce) ||
+        fixed_iv_len > aead_ctx->variable_nonce_len) {
+      SSL_AEAD_CTX_free(aead_ctx);
+      OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_new, ERR_R_INTERNAL_ERROR);
+      return 0;
+    }
+    aead_ctx->variable_nonce_len -= fixed_iv_len;
+
+    memcpy(aead_ctx->fixed_nonce, fixed_iv, fixed_iv_len);
+    aead_ctx->fixed_nonce_len = fixed_iv_len;
+    aead_ctx->variable_nonce_included_in_record =
+        (cipher->algorithm2 &
+         SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD) != 0;
+  } else {
+    aead_ctx->variable_nonce_included_in_record = 1;
+    aead_ctx->random_variable_nonce = 1;
+    aead_ctx->omit_length_in_ad = 1;
+    aead_ctx->omit_version_in_ad = (version == SSL3_VERSION);
+  }
+
+  return aead_ctx;
+}
+
+void SSL_AEAD_CTX_free(SSL_AEAD_CTX *aead) {
+  if (aead == NULL) {
+    return;
+  }
+  EVP_AEAD_CTX_cleanup(&aead->ctx);
+  OPENSSL_free(aead);
+}
+
+size_t SSL_AEAD_CTX_explicit_nonce_len(SSL_AEAD_CTX *aead) {
+  if (aead != NULL && aead->variable_nonce_included_in_record) {
+    return aead->variable_nonce_len;
+  }
+  return 0;
+}
+
+size_t SSL_AEAD_CTX_max_overhead(SSL_AEAD_CTX *aead) {
+  if (aead == NULL) {
+    return 0;
+  }
+  return EVP_AEAD_max_overhead(aead->ctx.aead) +
+      SSL_AEAD_CTX_explicit_nonce_len(aead);
+}
+
+/* ssl_aead_ctx_get_ad writes the additional data for |aead| into |out| and
+ * returns the number of bytes written. */
+static size_t ssl_aead_ctx_get_ad(SSL_AEAD_CTX *aead, uint8_t out[13],
+                                  uint8_t type, uint16_t wire_version,
+                                  const uint8_t seqnum[8],
+                                  size_t plaintext_len) {
+  memcpy(out, seqnum, 8);
+  size_t len = 8;
+  out[len++] = type;
+  if (!aead->omit_version_in_ad) {
+    out[len++] = (uint8_t)(wire_version >> 8);
+    out[len++] = (uint8_t)wire_version;
+  }
+  if (!aead->omit_length_in_ad) {
+    out[len++] = (uint8_t)(plaintext_len >> 8);
+    out[len++] = (uint8_t)plaintext_len;
+  }
+  return len;
+}
+
+int SSL_AEAD_CTX_open(SSL_AEAD_CTX *aead, uint8_t *out, size_t *out_len,
+                      size_t max_out, uint8_t type, uint16_t wire_version,
+                      const uint8_t seqnum[8], const uint8_t *in,
+                      size_t in_len) {
+  if (aead == NULL) {
+    /* Handle the initial NULL cipher. */
+    if (in_len > max_out) {
+      OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_open, SSL_R_BUFFER_TOO_SMALL);
+      return 0;
+    }
+    memmove(out, in, in_len);
+    *out_len = in_len;
+    return 1;
+  }
+
+  /* TLS 1.2 AEADs include the length in the AD and are assumed to have fixed
+   * overhead. Otherwise the parameter is unused. */
+  size_t plaintext_len = 0;
+  if (!aead->omit_length_in_ad) {
+    size_t overhead = SSL_AEAD_CTX_max_overhead(aead);
+    if (in_len < overhead) {
+      /* Publicly invalid. */
+      OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_open, SSL_R_BAD_PACKET_LENGTH);
+      return 0;
+    }
+    plaintext_len = in_len - overhead;
+  }
+  uint8_t ad[13];
+  size_t ad_len = ssl_aead_ctx_get_ad(aead, ad, type, wire_version, seqnum,
+                                      plaintext_len);
+
+  /* Assemble the nonce. */
+  uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
+  size_t nonce_len = 0;
+  memcpy(nonce, aead->fixed_nonce, aead->fixed_nonce_len);
+  nonce_len += aead->fixed_nonce_len;
+  if (aead->variable_nonce_included_in_record) {
+    if (in_len < aead->variable_nonce_len) {
+      /* Publicly invalid. */
+      OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_open, SSL_R_BAD_PACKET_LENGTH);
+      return 0;
+    }
+    memcpy(nonce + nonce_len, in, aead->variable_nonce_len);
+    in += aead->variable_nonce_len;
+    in_len -= aead->variable_nonce_len;
+  } else {
+    assert(aead->variable_nonce_len == 8);
+    memcpy(nonce + nonce_len, seqnum, aead->variable_nonce_len);
+  }
+  nonce_len += aead->variable_nonce_len;
+
+  return EVP_AEAD_CTX_open(&aead->ctx, out, out_len, max_out, nonce, nonce_len,
+                           in, in_len, ad, ad_len);
+}
+
+int SSL_AEAD_CTX_seal(SSL_AEAD_CTX *aead, uint8_t *out, size_t *out_len,
+                      size_t max_out, uint8_t type, uint16_t wire_version,
+                      const uint8_t seqnum[8], const uint8_t *in,
+                      size_t in_len) {
+  if (aead == NULL) {
+    /* Handle the initial NULL cipher. */
+    if (in_len > max_out) {
+      OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_seal, SSL_R_BUFFER_TOO_SMALL);
+      return 0;
+    }
+    memmove(out, in, in_len);
+    *out_len = in_len;
+    return 1;
+  }
+
+  uint8_t ad[13];
+  size_t ad_len = ssl_aead_ctx_get_ad(aead, ad, type, wire_version, seqnum,
+                                      in_len);
+
+  /* Assemble the nonce. */
+  uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
+  size_t nonce_len = 0;
+  memcpy(nonce, aead->fixed_nonce, aead->fixed_nonce_len);
+  nonce_len += aead->fixed_nonce_len;
+  if (aead->random_variable_nonce) {
+    assert(aead->variable_nonce_included_in_record);
+    if (!RAND_bytes(nonce + nonce_len, aead->variable_nonce_len)) {
+      return 0;
+    }
+  } else {
+    /* When sending we use the sequence number as the variable part of the
+     * nonce. */
+    assert(aead->variable_nonce_len == 8);
+    memcpy(nonce + nonce_len, ad, aead->variable_nonce_len);
+  }
+  nonce_len += aead->variable_nonce_len;
+
+  /* Emit the variable nonce if included in the record. */
+  size_t extra_len = 0;
+  if (aead->variable_nonce_included_in_record) {
+    if (max_out < aead->variable_nonce_len) {
+      OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_seal, SSL_R_BUFFER_TOO_SMALL);
+      return 0;
+    }
+    if (out < in + in_len && in < out + aead->variable_nonce_len) {
+      OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_seal, SSL_R_OUTPUT_ALIASES_INPUT);
+      return 0;
+    }
+    memcpy(out, nonce + aead->fixed_nonce_len, aead->variable_nonce_len);
+    extra_len = aead->variable_nonce_len;
+    out += aead->variable_nonce_len;
+    max_out -= aead->variable_nonce_len;
+  }
+
+  if (!EVP_AEAD_CTX_seal(&aead->ctx, out, out_len, max_out, nonce, nonce_len,
+                         in, in_len, ad, ad_len)) {
+    return 0;
+  }
+  *out_len += extra_len;
+  return 1;
+}
diff --git a/src/ssl/ssl_asn1.c b/src/ssl/ssl_asn1.c
index eb0c725..d1ac1b6 100644
--- a/src/ssl/ssl_asn1.c
+++ b/src/ssl/ssl_asn1.c
@@ -477,13 +477,17 @@
   }
   if (!CBS_get_optional_asn1_bool(&session, &extended_master_secret,
                                   kExtendedMasterSecretTag,
-                                  0 /* default to false */)) {
+                                  0 /* default to false */) ||
+      CBS_len(&session) != 0) {
     OPENSSL_PUT_ERROR(SSL, d2i_SSL_SESSION, SSL_R_INVALID_SSL_SESSION);
     goto err;
   }
   ret->extended_master_secret = extended_master_secret;
 
-  /* Ignore |version|. The structure version number is ignored. */
+  if (version != SSL_SESSION_ASN1_VERSION) {
+    OPENSSL_PUT_ERROR(SSL, d2i_SSL_SESSION, SSL_R_INVALID_SSL_SESSION);
+    goto err;
+  }
 
   /* Only support SSLv3/TLS and DTLS. */
   if ((ssl_version >> 8) != SSL3_VERSION_MAJOR &&
@@ -498,7 +502,7 @@
     OPENSSL_PUT_ERROR(SSL, d2i_SSL_SESSION, SSL_R_CIPHER_CODE_WRONG_LENGTH);
     goto err;
   }
-  ret->cipher = ssl3_get_cipher_by_value(cipher_value);
+  ret->cipher = SSL_get_cipher_by_value(cipher_value);
   if (ret->cipher == NULL) {
     OPENSSL_PUT_ERROR(SSL, d2i_SSL_SESSION, SSL_R_UNSUPPORTED_CIPHER);
     goto err;
diff --git a/src/ssl/ssl_cert.c b/src/ssl/ssl_cert.c
index 770912b..f1fd675 100644
--- a/src/ssl/ssl_cert.c
+++ b/src/ssl/ssl_cert.c
@@ -128,33 +128,22 @@
 
 #include "../crypto/dh/internal.h"
 #include "../crypto/directory.h"
+#include "../crypto/internal.h"
 #include "internal.h"
 
 
+static CRYPTO_once_t g_x509_store_ex_data_index_once;
+static int g_x509_store_ex_data_index;
+
+static void ssl_x509_store_ex_data_index_init(void) {
+  g_x509_store_ex_data_index = X509_STORE_CTX_get_ex_new_index(
+      0, "SSL for verify callback", NULL, NULL, NULL);
+}
+
 int SSL_get_ex_data_X509_STORE_CTX_idx(void) {
-  static int ssl_x509_store_ctx_idx = -1;
-  int got_write_lock = 0;
-
-  CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
-
-  if (ssl_x509_store_ctx_idx < 0) {
-    CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
-    CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
-    got_write_lock = 1;
-
-    if (ssl_x509_store_ctx_idx < 0) {
-      ssl_x509_store_ctx_idx = X509_STORE_CTX_get_ex_new_index(
-          0, "SSL for verify callback", NULL, NULL, NULL);
-    }
-  }
-
-  if (got_write_lock) {
-    CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
-  } else {
-    CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
-  }
-
-  return ssl_x509_store_ctx_idx;
+  CRYPTO_once(&g_x509_store_ex_data_index_once,
+              ssl_x509_store_ex_data_index_init);
+  return g_x509_store_ex_data_index;
 }
 
 CERT *ssl_cert_new(void) {
@@ -269,12 +258,12 @@
   ret->cert_cb_arg = cert->cert_cb_arg;
 
   if (cert->verify_store) {
-    CRYPTO_add(&cert->verify_store->references, 1, CRYPTO_LOCK_X509_STORE);
+    CRYPTO_refcount_inc(&cert->verify_store->references);
     ret->verify_store = cert->verify_store;
   }
 
   if (cert->chain_store) {
-    CRYPTO_add(&cert->chain_store->references, 1, CRYPTO_LOCK_X509_STORE);
+    CRYPTO_refcount_inc(&cert->chain_store->references);
     ret->chain_store = cert->chain_store;
   }
 
@@ -731,8 +720,6 @@
   const char *filename;
   int ret = 0;
 
-  CRYPTO_w_lock(CRYPTO_LOCK_READDIR);
-
   /* Note that a side effect is that the CAs will be sorted by name */
   while ((filename = OPENSSL_DIR_read(&d, dir))) {
     char buf[1024];
@@ -763,7 +750,6 @@
   if (d) {
     OPENSSL_DIR_end(&d);
   }
-  CRYPTO_w_unlock(CRYPTO_LOCK_READDIR);
   return ret;
 }
 
@@ -977,7 +963,7 @@
   *pstore = store;
 
   if (ref && store) {
-    CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE);
+    CRYPTO_refcount_inc(&store->references);
   }
   return 1;
 }
diff --git a/src/ssl/ssl_cipher.c b/src/ssl/ssl_cipher.c
index a9c8536..5e617b1 100644
--- a/src/ssl/ssl_cipher.c
+++ b/src/ssl/ssl_cipher.c
@@ -152,6 +152,325 @@
 #include "internal.h"
 
 
+/* kCiphers is an array of all supported ciphers, sorted by id. */
+const SSL_CIPHER kCiphers[] = {
+    /* The RSA ciphers */
+    /* Cipher 04 */
+    {
+     SSL3_TXT_RSA_RC4_128_MD5, SSL3_CK_RSA_RC4_128_MD5, SSL_kRSA, SSL_aRSA,
+     SSL_RC4, SSL_MD5, SSL_SSLV3, SSL_MEDIUM,
+     SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
+    },
+
+    /* Cipher 05 */
+    {
+     SSL3_TXT_RSA_RC4_128_SHA, SSL3_CK_RSA_RC4_128_SHA, SSL_kRSA, SSL_aRSA,
+     SSL_RC4, SSL_SHA1, SSL_SSLV3, SSL_MEDIUM,
+     SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
+    },
+
+    /* Cipher 0A */
+    {
+     SSL3_TXT_RSA_DES_192_CBC3_SHA, SSL3_CK_RSA_DES_192_CBC3_SHA, SSL_kRSA,
+     SSL_aRSA, SSL_3DES, SSL_SHA1, SSL_SSLV3, SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT, 112, 168,
+    },
+
+
+    /* New AES ciphersuites */
+
+    /* Cipher 2F */
+    {
+     TLS1_TXT_RSA_WITH_AES_128_SHA, TLS1_CK_RSA_WITH_AES_128_SHA, SSL_kRSA,
+     SSL_aRSA, SSL_AES128, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
+    },
+
+    /* Cipher 33 */
+    {
+     TLS1_TXT_DHE_RSA_WITH_AES_128_SHA, TLS1_CK_DHE_RSA_WITH_AES_128_SHA,
+     SSL_kDHE, SSL_aRSA, SSL_AES128, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
+    },
+
+    /* Cipher 35 */
+    {
+     TLS1_TXT_RSA_WITH_AES_256_SHA, TLS1_CK_RSA_WITH_AES_256_SHA, SSL_kRSA,
+     SSL_aRSA, SSL_AES256, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT, 256, 256,
+    },
+
+    /* Cipher 39 */
+    {
+     TLS1_TXT_DHE_RSA_WITH_AES_256_SHA, TLS1_CK_DHE_RSA_WITH_AES_256_SHA,
+     SSL_kDHE, SSL_aRSA, SSL_AES256, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT, 256, 256,
+    },
+
+
+    /* TLS v1.2 ciphersuites */
+
+    /* Cipher 3C */
+    {
+     TLS1_TXT_RSA_WITH_AES_128_SHA256, TLS1_CK_RSA_WITH_AES_128_SHA256,
+     SSL_kRSA, SSL_aRSA, SSL_AES128, SSL_SHA256, SSL_TLSV1_2,
+     SSL_HIGH | SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256, 128, 128,
+    },
+
+    /* Cipher 3D */
+    {
+     TLS1_TXT_RSA_WITH_AES_256_SHA256, TLS1_CK_RSA_WITH_AES_256_SHA256,
+     SSL_kRSA, SSL_aRSA, SSL_AES256, SSL_SHA256, SSL_TLSV1_2,
+     SSL_HIGH | SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256, 256, 256,
+    },
+
+    /* Cipher 67 */
+    {
+     TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256,
+     TLS1_CK_DHE_RSA_WITH_AES_128_SHA256, SSL_kDHE, SSL_aRSA, SSL_AES128,
+     SSL_SHA256, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA256, 128, 128,
+    },
+
+    /* Cipher 6B */
+    {
+     TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256,
+     TLS1_CK_DHE_RSA_WITH_AES_256_SHA256, SSL_kDHE, SSL_aRSA, SSL_AES256,
+     SSL_SHA256, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA256, 256, 256,
+    },
+
+    /* Cipher 8A */
+    {
+     TLS1_TXT_PSK_WITH_RC4_128_SHA, TLS1_CK_PSK_WITH_RC4_128_SHA, SSL_kPSK,
+     SSL_aPSK, SSL_RC4, SSL_SHA1, SSL_TLSV1, SSL_MEDIUM,
+     SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
+    },
+
+    /* Cipher 8C */
+    {
+     TLS1_TXT_PSK_WITH_AES_128_CBC_SHA, TLS1_CK_PSK_WITH_AES_128_CBC_SHA,
+     SSL_kPSK, SSL_aPSK, SSL_AES128, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
+    },
+
+    /* Cipher 8D */
+    {
+     TLS1_TXT_PSK_WITH_AES_256_CBC_SHA, TLS1_CK_PSK_WITH_AES_256_CBC_SHA,
+     SSL_kPSK, SSL_aPSK, SSL_AES256, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT, 256, 256,
+    },
+
+
+    /* GCM ciphersuites from RFC5288 */
+
+    /* Cipher 9C */
+    {
+     TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256,
+     TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, SSL_kRSA, SSL_aRSA, SSL_AES128GCM,
+     SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA256 |
+         SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
+     128, 128,
+    },
+
+    /* Cipher 9D */
+    {
+     TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384,
+     TLS1_CK_RSA_WITH_AES_256_GCM_SHA384, SSL_kRSA, SSL_aRSA, SSL_AES256GCM,
+     SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA384 |
+         SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
+     256, 256,
+    },
+
+    /* Cipher 9E */
+    {
+     TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256,
+     TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, SSL_kDHE, SSL_aRSA, SSL_AES128GCM,
+     SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA256 |
+         SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
+     128, 128,
+    },
+
+    /* Cipher 9F */
+    {
+     TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384,
+     TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384, SSL_kDHE, SSL_aRSA, SSL_AES256GCM,
+     SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA384 |
+         SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
+     256, 256,
+    },
+
+    /* Cipher C007 */
+    {
+     TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA,
+     TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA, SSL_kECDHE, SSL_aECDSA, SSL_RC4,
+     SSL_SHA1, SSL_TLSV1, SSL_MEDIUM, SSL_HANDSHAKE_MAC_DEFAULT, 128,
+     128,
+    },
+
+    /* Cipher C009 */
+    {
+     TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+     TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, SSL_kECDHE, SSL_aECDSA,
+     SSL_AES128, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
+    },
+
+    /* Cipher C00A */
+    {
+     TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+     TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, SSL_kECDHE, SSL_aECDSA,
+     SSL_AES256, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT, 256, 256,
+    },
+
+    /* Cipher C011 */
+    {
+     TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA, TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA,
+     SSL_kECDHE, SSL_aRSA, SSL_RC4, SSL_SHA1, SSL_TLSV1, SSL_MEDIUM,
+     SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
+    },
+
+    /* Cipher C013 */
+    {
+     TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+     TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, SSL_kECDHE, SSL_aRSA, SSL_AES128,
+     SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
+    },
+
+    /* Cipher C014 */
+    {
+     TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+     TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, SSL_kECDHE, SSL_aRSA, SSL_AES256,
+     SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT, 256, 256,
+    },
+
+
+    /* HMAC based TLS v1.2 ciphersuites from RFC5289 */
+
+    /* Cipher C023 */
+    {
+     TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256,
+     TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256, SSL_kECDHE, SSL_aECDSA,
+     SSL_AES128, SSL_SHA256, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA256, 128, 128,
+    },
+
+    /* Cipher C024 */
+    {
+     TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384,
+     TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384, SSL_kECDHE, SSL_aECDSA,
+     SSL_AES256, SSL_SHA384, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA384, 256, 256,
+    },
+
+    /* Cipher C027 */
+    {
+     TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256,
+     TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256, SSL_kECDHE, SSL_aRSA, SSL_AES128,
+     SSL_SHA256, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA256, 128, 128,
+    },
+
+    /* Cipher C028 */
+    {
+     TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384,
+     TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384, SSL_kECDHE, SSL_aRSA, SSL_AES256,
+     SSL_SHA384, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA384, 256, 256,
+    },
+
+
+    /* GCM based TLS v1.2 ciphersuites from RFC5289 */
+
+    /* Cipher C02B */
+    {
+     TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+     TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, SSL_kECDHE, SSL_aECDSA,
+     SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA256 |
+         SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
+     128, 128,
+    },
+
+    /* Cipher C02C */
+    {
+     TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+     TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, SSL_kECDHE, SSL_aECDSA,
+     SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA384 |
+         SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
+     256, 256,
+    },
+
+    /* Cipher C02F */
+    {
+     TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+     TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, SSL_kECDHE, SSL_aRSA,
+     SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA256 |
+         SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
+     128, 128,
+    },
+
+    /* Cipher C030 */
+    {
+     TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+     TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, SSL_kECDHE, SSL_aRSA,
+     SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA384 |
+         SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
+     256, 256,
+    },
+
+
+#if !defined(ANDROID)
+    /* ECDH PSK ciphersuites */
+
+    /* Cipher CAFE */
+    {
+     TLS1_TXT_ECDHE_PSK_WITH_AES_128_GCM_SHA256,
+     TLS1_CK_ECDHE_PSK_WITH_AES_128_GCM_SHA256, SSL_kECDHE, SSL_aPSK,
+     SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 |
+         SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
+     128, 128,
+    },
+
+    {
+     TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+     TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, SSL_kECDHE, SSL_aRSA,
+     SSL_CHACHA20POLY1305, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256,
+     256, 0,
+    },
+
+    {
+     TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
+     TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, SSL_kECDHE, SSL_aECDSA,
+     SSL_CHACHA20POLY1305, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256,
+     256, 0,
+    },
+
+    {
+     TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305,
+     TLS1_CK_DHE_RSA_CHACHA20_POLY1305, SSL_kDHE, SSL_aRSA,
+     SSL_CHACHA20POLY1305, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256,
+     256, 0,
+    },
+#endif
+};
+
+static const size_t kCiphersLen = sizeof(kCiphers) / sizeof(kCiphers[0]);
+
 struct handshake_digest {
   uint32_t mask;
   const EVP_MD *(*md_func)(void);
@@ -193,71 +512,96 @@
   uint32_t algo_strength;
 } CIPHER_ALIAS;
 
-static const CIPHER_ALIAS kCipherAliases[] =
-    {
-     {SSL_TXT_ALL, ~0u, ~0u, ~0u, ~0u, ~0u, ~0u},
+static const CIPHER_ALIAS kCipherAliases[] = {
+    {SSL_TXT_ALL, ~0u, ~0u, ~0u, ~0u, ~0u, ~0u},
 
-     /* The "COMPLEMENTOFDEFAULT" rule is omitted. It matches nothing. */
+    /* The "COMPLEMENTOFDEFAULT" rule is omitted. It matches nothing. */
 
-     /* key exchange aliases
-      * (some of those using only a single bit here combine
-      * multiple key exchange algs according to the RFCs,
-      * e.g. kEDH combines DHE_DSS and DHE_RSA) */
-     {SSL_TXT_kRSA, SSL_kRSA, ~0u, ~0u, ~0u, ~0u, ~0u},
+    /* key exchange aliases
+     * (some of those using only a single bit here combine
+     * multiple key exchange algs according to the RFCs,
+     * e.g. kEDH combines DHE_DSS and DHE_RSA) */
+    {SSL_TXT_kRSA, SSL_kRSA, ~0u, ~0u, ~0u, ~0u, ~0u},
 
-     {SSL_TXT_kDHE, SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
-     {SSL_TXT_kEDH, SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
-     {SSL_TXT_DH, SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
+    {SSL_TXT_kDHE, SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
+    {SSL_TXT_kEDH, SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
+    {SSL_TXT_DH, SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
 
-     {SSL_TXT_kECDHE, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
-     {SSL_TXT_kEECDH, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
-     {SSL_TXT_ECDH, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
+    {SSL_TXT_kECDHE, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
+    {SSL_TXT_kEECDH, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
+    {SSL_TXT_ECDH, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
 
-     {SSL_TXT_kPSK, SSL_kPSK, ~0u, ~0u, ~0u, ~0u, ~0u},
+    {SSL_TXT_kPSK, SSL_kPSK, ~0u, ~0u, ~0u, ~0u, ~0u},
 
-     /* server authentication aliases */
-     {SSL_TXT_aRSA, ~0u, SSL_aRSA, ~0u, ~0u, ~0u, ~0u},
-     {SSL_TXT_aECDSA, ~0u, SSL_aECDSA, ~0u, ~0u, ~0u, ~0u},
-     {SSL_TXT_ECDSA, ~0u, SSL_aECDSA, ~0u, ~0u, ~0u, ~0u},
-     {SSL_TXT_aPSK, ~0u, SSL_aPSK, ~0u, ~0u, ~0u, ~0u},
+    /* server authentication aliases */
+    {SSL_TXT_aRSA, ~0u, SSL_aRSA, ~0u, ~0u, ~0u, ~0u},
+    {SSL_TXT_aECDSA, ~0u, SSL_aECDSA, ~0u, ~0u, ~0u, ~0u},
+    {SSL_TXT_ECDSA, ~0u, SSL_aECDSA, ~0u, ~0u, ~0u, ~0u},
+    {SSL_TXT_aPSK, ~0u, SSL_aPSK, ~0u, ~0u, ~0u, ~0u},
 
-     /* aliases combining key exchange and server authentication */
-     {SSL_TXT_DHE, SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
-     {SSL_TXT_EDH, SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
-     {SSL_TXT_ECDHE, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
-     {SSL_TXT_EECDH, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
-     {SSL_TXT_RSA, SSL_kRSA, SSL_aRSA, ~0u, ~0u, ~0u, ~0u},
-     {SSL_TXT_PSK, SSL_kPSK, SSL_aPSK, ~0u, ~0u, ~0u, ~0u},
+    /* aliases combining key exchange and server authentication */
+    {SSL_TXT_DHE, SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
+    {SSL_TXT_EDH, SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
+    {SSL_TXT_ECDHE, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
+    {SSL_TXT_EECDH, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
+    {SSL_TXT_RSA, SSL_kRSA, SSL_aRSA, ~0u, ~0u, ~0u, ~0u},
+    {SSL_TXT_PSK, SSL_kPSK, SSL_aPSK, ~0u, ~0u, ~0u, ~0u},
 
-     /* symmetric encryption aliases */
-     {SSL_TXT_3DES, ~0u, ~0u, SSL_3DES, ~0u, ~0u, ~0u},
-     {SSL_TXT_RC4, ~0u, ~0u, SSL_RC4, ~0u, ~0u, ~0u},
-     {SSL_TXT_AES128, ~0u, ~0u, SSL_AES128 | SSL_AES128GCM, ~0u, ~0u, ~0u},
-     {SSL_TXT_AES256, ~0u, ~0u, SSL_AES256 | SSL_AES256GCM, ~0u, ~0u, ~0u},
-     {SSL_TXT_AES, ~0u, ~0u, SSL_AES, ~0u, ~0u, ~0u},
-     {SSL_TXT_AES_GCM, ~0u, ~0u, SSL_AES128GCM | SSL_AES256GCM, ~0u, ~0u, ~0u},
-     {SSL_TXT_CHACHA20, ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, ~0u, ~0u},
+    /* symmetric encryption aliases */
+    {SSL_TXT_3DES, ~0u, ~0u, SSL_3DES, ~0u, ~0u, ~0u},
+    {SSL_TXT_RC4, ~0u, ~0u, SSL_RC4, ~0u, ~0u, ~0u},
+    {SSL_TXT_AES128, ~0u, ~0u, SSL_AES128 | SSL_AES128GCM, ~0u, ~0u, ~0u},
+    {SSL_TXT_AES256, ~0u, ~0u, SSL_AES256 | SSL_AES256GCM, ~0u, ~0u, ~0u},
+    {SSL_TXT_AES, ~0u, ~0u, SSL_AES, ~0u, ~0u, ~0u},
+    {SSL_TXT_AES_GCM, ~0u, ~0u, SSL_AES128GCM | SSL_AES256GCM, ~0u, ~0u, ~0u},
+    {SSL_TXT_CHACHA20, ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, ~0u, ~0u},
 
-     /* MAC aliases */
-     {SSL_TXT_MD5, ~0u, ~0u, ~0u, SSL_MD5, ~0u, ~0u},
-     {SSL_TXT_SHA1, ~0u, ~0u, ~0u, SSL_SHA1, ~0u, ~0u},
-     {SSL_TXT_SHA, ~0u, ~0u, ~0u, SSL_SHA1, ~0u, ~0u},
-     {SSL_TXT_SHA256, ~0u, ~0u, ~0u, SSL_SHA256, ~0u, ~0u},
-     {SSL_TXT_SHA384, ~0u, ~0u, ~0u, SSL_SHA384, ~0u, ~0u},
+    /* MAC aliases */
+    {SSL_TXT_MD5, ~0u, ~0u, ~0u, SSL_MD5, ~0u, ~0u},
+    {SSL_TXT_SHA1, ~0u, ~0u, ~0u, SSL_SHA1, ~0u, ~0u},
+    {SSL_TXT_SHA, ~0u, ~0u, ~0u, SSL_SHA1, ~0u, ~0u},
+    {SSL_TXT_SHA256, ~0u, ~0u, ~0u, SSL_SHA256, ~0u, ~0u},
+    {SSL_TXT_SHA384, ~0u, ~0u, ~0u, SSL_SHA384, ~0u, ~0u},
 
-     /* protocol version aliases */
-     {SSL_TXT_SSLV3, ~0u, ~0u, ~0u, ~0u, SSL_SSLV3, ~0u},
-     {SSL_TXT_TLSV1, ~0u, ~0u, ~0u, ~0u, SSL_TLSV1, ~0u},
-     {SSL_TXT_TLSV1_2, ~0u, ~0u, ~0u, ~0u, SSL_TLSV1_2, ~0u},
+    /* protocol version aliases */
+    {SSL_TXT_SSLV3, ~0u, ~0u, ~0u, ~0u, SSL_SSLV3, ~0u},
+    {SSL_TXT_TLSV1, ~0u, ~0u, ~0u, ~0u, SSL_TLSV1, ~0u},
+    {SSL_TXT_TLSV1_2, ~0u, ~0u, ~0u, ~0u, SSL_TLSV1_2, ~0u},
 
-     /* strength classes */
-     {SSL_TXT_MEDIUM, ~0u, ~0u, ~0u, ~0u, ~0u, SSL_MEDIUM},
-     {SSL_TXT_HIGH, ~0u, ~0u, ~0u, ~0u, ~0u, SSL_HIGH},
-     /* FIPS 140-2 approved ciphersuite */
-     {SSL_TXT_FIPS, ~0u, ~0u, ~0u, ~0u, ~0u, SSL_FIPS},
+    /* strength classes */
+    {SSL_TXT_MEDIUM, ~0u, ~0u, ~0u, ~0u, ~0u, SSL_MEDIUM},
+    {SSL_TXT_HIGH, ~0u, ~0u, ~0u, ~0u, ~0u, SSL_HIGH},
+    /* FIPS 140-2 approved ciphersuite */
+    {SSL_TXT_FIPS, ~0u, ~0u, ~0u, ~0u, ~0u, SSL_FIPS},
 };
 
-#define NUM_CIPHER_ALIASES (sizeof(kCipherAliases) / sizeof(kCipherAliases[0]))
+static const size_t kCipherAliasesLen =
+    sizeof(kCipherAliases) / sizeof(kCipherAliases[0]);
+
+static int ssl_cipher_id_cmp(const void *in_a, const void *in_b) {
+  const SSL_CIPHER *a = in_a;
+  const SSL_CIPHER *b = in_b;
+
+  if (a->id > b->id) {
+    return 1;
+  } else if (a->id < b->id) {
+    return -1;
+  } else {
+    return 0;
+  }
+}
+
+static int ssl_cipher_ptr_id_cmp(const SSL_CIPHER **a, const SSL_CIPHER **b) {
+  return ssl_cipher_id_cmp(*a, *b);
+}
+
+const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value) {
+  SSL_CIPHER c;
+
+  c.id = 0x03000000L | value;
+  return bsearch(&c, kCiphers, kCiphersLen, sizeof(SSL_CIPHER),
+                 ssl_cipher_id_cmp);
+}
 
 int ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead,
                             size_t *out_mac_secret_len,
@@ -439,22 +783,17 @@
 }
 
 static void ssl_cipher_collect_ciphers(const SSL_PROTOCOL_METHOD *ssl_method,
-                                       size_t num_of_ciphers,
                                        CIPHER_ORDER *co_list,
                                        CIPHER_ORDER **head_p,
                                        CIPHER_ORDER **tail_p) {
-  size_t i, co_list_num;
-
-  /* We have num_of_ciphers descriptions compiled in, depending on the method
-   * selected (SSLv2 and/or SSLv3, TLSv1 etc). These will later be sorted in a
-   * linked list with at most num entries. */
-
-  /* Get the initial list of ciphers */
-  co_list_num = 0; /* actual count of ciphers */
-  for (i = 0; i < num_of_ciphers; i++) {
-    const SSL_CIPHER *c = ssl_method->get_cipher(i);
-    if (c != NULL) {
-      co_list[co_list_num].cipher = c;
+  /* The set of ciphers is static, but some subset may be unsupported by
+   * |ssl_method|, so the list may be smaller. */
+  size_t co_list_num = 0;
+  size_t i;
+  for (i = 0; i < kCiphersLen; i++) {
+    const SSL_CIPHER *cipher = &kCiphers[i];
+    if (ssl_method->supports_cipher(cipher)) {
+      co_list[co_list_num].cipher = cipher;
       co_list[co_list_num].next = NULL;
       co_list[co_list_num].prev = NULL;
       co_list[co_list_num].active = 0;
@@ -777,10 +1116,9 @@
       /* Look for a matching exact cipher. These aren't allowed in multipart
        * rules. */
       if (!multi && ch != '+') {
-        size_t num_ciphers = ssl_method->num_ciphers();
-        for (j = 0; j < num_ciphers; j++) {
-          const SSL_CIPHER *cipher = ssl_method->get_cipher(j);
-          if (cipher != NULL && rule_equals(cipher->name, buf, buf_len)) {
+        for (j = 0; j < kCiphersLen; j++) {
+          const SSL_CIPHER *cipher = &kCiphers[j];
+          if (rule_equals(cipher->name, buf, buf_len)) {
             cipher_id = cipher->id;
             break;
           }
@@ -788,7 +1126,7 @@
       }
       if (cipher_id == 0) {
         /* If not an exact cipher, look for a matching cipher alias. */
-        for (j = 0; j < NUM_CIPHER_ALIASES; j++) {
+        for (j = 0; j < kCipherAliasesLen; j++) {
           if (rule_equals(kCipherAliases[j].name, buf, buf_len)) {
             alg_mkey &= kCipherAliases[j].algorithm_mkey;
             alg_auth &= kCipherAliases[j].algorithm_auth;
@@ -799,7 +1137,7 @@
             break;
           }
         }
-        if (j == NUM_CIPHER_ALIASES) {
+        if (j == kCipherAliasesLen) {
           alg_mkey = alg_auth = alg_enc = alg_mac = alg_ssl = algo_strength = 0;
         }
       }
@@ -853,7 +1191,6 @@
                        STACK_OF(SSL_CIPHER) **out_cipher_list_by_id,
                        const char *rule_str) {
   int ok;
-  size_t num_of_ciphers;
   STACK_OF(SSL_CIPHER) *cipherstack = NULL, *tmp_cipher_list = NULL;
   const char *rule_p;
   CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr;
@@ -869,23 +1206,21 @@
   /* Now we have to collect the available ciphers from the compiled in ciphers.
    * We cannot get more than the number compiled in, so it is used for
    * allocation. */
-  num_of_ciphers = ssl_method->num_ciphers();
-  co_list =
-      (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * num_of_ciphers);
+  co_list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * kCiphersLen);
   if (co_list == NULL) {
     OPENSSL_PUT_ERROR(SSL, ssl_create_cipher_list, ERR_R_MALLOC_FAILURE);
     return NULL;
   }
 
-  ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers, co_list, &head, &tail);
+  ssl_cipher_collect_ciphers(ssl_method, co_list, &head, &tail);
 
   /* Now arrange all ciphers by preference:
    * TODO(davidben): Compute this order once and copy it. */
 
   /* Everything else being equal, prefer ECDHE_ECDSA then ECDHE_RSA over other
    * key exchange mechanisms */
- ssl_cipher_apply_rule(0, SSL_kECDHE, SSL_aECDSA, ~0u, ~0u, ~0u, ~0u,
-                       CIPHER_ADD, -1, 0, &head, &tail);
+  ssl_cipher_apply_rule(0, SSL_kECDHE, SSL_aECDSA, ~0u, ~0u, ~0u, ~0u,
+                        CIPHER_ADD, -1, 0, &head, &tail);
   ssl_cipher_apply_rule(0, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u, CIPHER_ADD, -1,
                         0, &head, &tail);
   ssl_cipher_apply_rule(0, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u, CIPHER_DEL, -1,
@@ -963,7 +1298,7 @@
     goto err;
   }
 
-  in_group_flags = OPENSSL_malloc(num_of_ciphers);
+  in_group_flags = OPENSSL_malloc(kCiphersLen);
   if (!in_group_flags) {
     goto err;
   }
@@ -1032,6 +1367,13 @@
 
 uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *cipher) { return cipher->id; }
 
+uint16_t ssl_cipher_get_value(const SSL_CIPHER *cipher) {
+  uint32_t id = cipher->id;
+  /* All ciphers are SSLv3. */
+  assert((id & 0xff000000) == 0x03000000);
+  return id & 0xffff;
+}
+
 int SSL_CIPHER_is_AES(const SSL_CIPHER *cipher) {
   return (cipher->algorithm_enc & SSL_AES) != 0;
 }
@@ -1122,7 +1464,8 @@
 }
 
 static const char *ssl_cipher_get_prf_name(const SSL_CIPHER *cipher) {
-  if ((cipher->algorithm2 & TLS1_PRF) == TLS1_PRF) {
+  if ((cipher->algorithm2 & SSL_HANDSHAKE_MAC_DEFAULT) ==
+      SSL_HANDSHAKE_MAC_DEFAULT) {
     /* Before TLS 1.2, the PRF component is the hash used in the HMAC, which is
      * only ever MD5 or SHA-1. */
     switch (cipher->algorithm_mac) {
@@ -1134,9 +1477,9 @@
         assert(0);
         return "UNKNOWN";
     }
-  } else if (cipher->algorithm2 & TLS1_PRF_SHA256) {
+  } else if (cipher->algorithm2 & SSL_HANDSHAKE_MAC_SHA256) {
     return "SHA256";
-  } else if (cipher->algorithm2 & TLS1_PRF_SHA384) {
+  } else if (cipher->algorithm2 & SSL_HANDSHAKE_MAC_SHA384) {
     return "SHA384";
   } else {
     assert(0);
diff --git a/src/ssl/ssl_lib.c b/src/ssl/ssl_lib.c
index 6c8e2c9..e95226f 100644
--- a/src/ssl/ssl_lib.c
+++ b/src/ssl/ssl_lib.c
@@ -167,80 +167,75 @@
 static CRYPTO_EX_DATA_CLASS g_ex_data_class_ssl = CRYPTO_EX_DATA_CLASS_INIT;
 static CRYPTO_EX_DATA_CLASS g_ex_data_class_ssl_ctx = CRYPTO_EX_DATA_CLASS_INIT;
 
-int SSL_clear(SSL *s) {
-  if (s->method == NULL) {
+int SSL_clear(SSL *ssl) {
+  if (ssl->method == NULL) {
     OPENSSL_PUT_ERROR(SSL, SSL_clear, SSL_R_NO_METHOD_SPECIFIED);
     return 0;
   }
 
-  if (ssl_clear_bad_session(s)) {
-    SSL_SESSION_free(s->session);
-    s->session = NULL;
+  if (ssl_clear_bad_session(ssl)) {
+    SSL_SESSION_free(ssl->session);
+    ssl->session = NULL;
   }
 
-  s->hit = 0;
-  s->shutdown = 0;
+  ssl->hit = 0;
+  ssl->shutdown = 0;
 
-  if (s->renegotiate) {
-    OPENSSL_PUT_ERROR(SSL, SSL_clear, ERR_R_INTERNAL_ERROR);
-    return 0;
-  }
-
-  /* SSL_clear may be called before or after the |s| is initialized in either
+  /* SSL_clear may be called before or after the |ssl| is initialized in either
    * accept or connect state. In the latter case, SSL_clear should preserve the
-   * half and reset |s->state| accordingly. */
-  if (s->handshake_func != NULL) {
-    if (s->server) {
-      SSL_set_accept_state(s);
+   * half and reset |ssl->state| accordingly. */
+  if (ssl->handshake_func != NULL) {
+    if (ssl->server) {
+      SSL_set_accept_state(ssl);
     } else {
-      SSL_set_connect_state(s);
+      SSL_set_connect_state(ssl);
     }
   } else {
-    assert(s->state == 0);
+    assert(ssl->state == 0);
   }
 
-  /* TODO(davidben): Some state on |s| is reset both in |SSL_new| and
+  /* TODO(davidben): Some state on |ssl| is reset both in |SSL_new| and
    * |SSL_clear| because it is per-connection state rather than configuration
-   * state. Per-connection state should be on |s->s3| and |s->d1| so it is
+   * state. Per-connection state should be on |ssl->s3| and |ssl->d1| so it is
    * naturally reset at the right points between |SSL_new|, |SSL_clear|, and
    * |ssl3_new|. */
 
-  s->rwstate = SSL_NOTHING;
-  s->rstate = SSL_ST_READ_HEADER;
+  ssl->rwstate = SSL_NOTHING;
+  ssl->rstate = SSL_ST_READ_HEADER;
 
-  BUF_MEM_free(s->init_buf);
-  s->init_buf = NULL;
+  BUF_MEM_free(ssl->init_buf);
+  ssl->init_buf = NULL;
 
-  s->packet = NULL;
-  s->packet_length = 0;
+  ssl->packet = NULL;
+  ssl->packet_length = 0;
 
-  ssl_clear_cipher_ctx(s);
+  ssl_clear_cipher_ctx(ssl);
 
-  OPENSSL_free(s->next_proto_negotiated);
-  s->next_proto_negotiated = NULL;
-  s->next_proto_negotiated_len = 0;
+  OPENSSL_free(ssl->next_proto_negotiated);
+  ssl->next_proto_negotiated = NULL;
+  ssl->next_proto_negotiated_len = 0;
 
-  /* The s->d1->mtu is simultaneously configuration (preserved across
+  /* The ssl->d1->mtu is simultaneously configuration (preserved across
    * clear) and connection-specific state (gets reset).
    *
    * TODO(davidben): Avoid this. */
   unsigned mtu = 0;
-  if (s->d1 != NULL) {
-    mtu = s->d1->mtu;
+  if (ssl->d1 != NULL) {
+    mtu = ssl->d1->mtu;
   }
 
-  s->method->ssl_free(s);
-  if (!s->method->ssl_new(s)) {
+  ssl->method->ssl_free(ssl);
+  if (!ssl->method->ssl_new(ssl)) {
     return 0;
   }
-  s->enc_method = ssl3_get_enc_method(s->version);
-  assert(s->enc_method != NULL);
+  ssl->enc_method = ssl3_get_enc_method(ssl->version);
+  assert(ssl->enc_method != NULL);
 
-  if (SSL_IS_DTLS(s) && (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) {
-    s->d1->mtu = mtu;
+  if (SSL_IS_DTLS(ssl) && (SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) {
+    ssl->d1->mtu = mtu;
   }
 
-  s->client_version = s->version;
+  ssl->client_version = ssl->version;
 
   return 1;
 }
@@ -275,7 +270,6 @@
     goto err;
   }
 
-  s->read_ahead = ctx->read_ahead;
   s->msg_callback = ctx->msg_callback;
   s->msg_callback_arg = ctx->msg_callback_arg;
   s->verify_mode = ctx->verify_mode;
@@ -293,10 +287,10 @@
   s->quiet_shutdown = ctx->quiet_shutdown;
   s->max_send_fragment = ctx->max_send_fragment;
 
-  CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX);
+  CRYPTO_refcount_inc(&ctx->references);
   s->ctx = ctx;
   s->tlsext_ticket_expected = 0;
-  CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX);
+  CRYPTO_refcount_inc(&ctx->references);
   s->initial_ctx = ctx;
   if (ctx->tlsext_ecpointformatlist) {
     s->tlsext_ecpointformatlist = BUF_memdup(
@@ -396,9 +390,7 @@
 }
 
 int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb) {
-  CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
   ctx->generate_session_id = cb;
-  CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
   return 1;
 }
 
@@ -424,9 +416,9 @@
   r.session_id_length = id_len;
   memcpy(r.session_id, id, id_len);
 
-  CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
+  CRYPTO_MUTEX_lock_read(&ssl->ctx->lock);
   p = lh_SSL_SESSION_retrieve(ssl->ctx->sessions, &r);
-  CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
+  CRYPTO_MUTEX_unlock(&ssl->ctx->lock);
   return p != NULL;
 }
 
@@ -525,60 +517,60 @@
 
 void SSL_certs_clear(SSL *s) { ssl_cert_clear_certs(s->cert); }
 
-void SSL_free(SSL *s) {
-  if (s == NULL) {
+void SSL_free(SSL *ssl) {
+  if (ssl == NULL) {
     return;
   }
 
-  X509_VERIFY_PARAM_free(s->param);
+  X509_VERIFY_PARAM_free(ssl->param);
 
-  CRYPTO_free_ex_data(&g_ex_data_class_ssl, s, &s->ex_data);
+  CRYPTO_free_ex_data(&g_ex_data_class_ssl, ssl, &ssl->ex_data);
 
-  if (s->bbio != NULL) {
+  if (ssl->bbio != NULL) {
     /* If the buffering BIO is in place, pop it off */
-    if (s->bbio == s->wbio) {
-      s->wbio = BIO_pop(s->wbio);
+    if (ssl->bbio == ssl->wbio) {
+      ssl->wbio = BIO_pop(ssl->wbio);
     }
-    BIO_free(s->bbio);
-    s->bbio = NULL;
+    BIO_free(ssl->bbio);
+    ssl->bbio = NULL;
   }
 
-  int free_wbio = s->wbio != s->rbio;
-  BIO_free_all(s->rbio);
+  int free_wbio = ssl->wbio != ssl->rbio;
+  BIO_free_all(ssl->rbio);
   if (free_wbio) {
-    BIO_free_all(s->wbio);
+    BIO_free_all(ssl->wbio);
   }
 
-  BUF_MEM_free(s->init_buf);
+  BUF_MEM_free(ssl->init_buf);
 
   /* add extra stuff */
-  ssl_cipher_preference_list_free(s->cipher_list);
-  sk_SSL_CIPHER_free(s->cipher_list_by_id);
+  ssl_cipher_preference_list_free(ssl->cipher_list);
+  sk_SSL_CIPHER_free(ssl->cipher_list_by_id);
 
-  ssl_clear_bad_session(s);
-  SSL_SESSION_free(s->session);
+  ssl_clear_bad_session(ssl);
+  SSL_SESSION_free(ssl->session);
 
-  ssl_clear_cipher_ctx(s);
+  ssl_clear_cipher_ctx(ssl);
 
-  ssl_cert_free(s->cert);
+  ssl_cert_free(ssl->cert);
 
-  OPENSSL_free(s->tlsext_hostname);
-  SSL_CTX_free(s->initial_ctx);
-  OPENSSL_free(s->tlsext_ecpointformatlist);
-  OPENSSL_free(s->tlsext_ellipticcurvelist);
-  OPENSSL_free(s->alpn_client_proto_list);
-  EVP_PKEY_free(s->tlsext_channel_id_private);
-  OPENSSL_free(s->psk_identity_hint);
-  sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free);
-  OPENSSL_free(s->next_proto_negotiated);
-  sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles);
+  OPENSSL_free(ssl->tlsext_hostname);
+  SSL_CTX_free(ssl->initial_ctx);
+  OPENSSL_free(ssl->tlsext_ecpointformatlist);
+  OPENSSL_free(ssl->tlsext_ellipticcurvelist);
+  OPENSSL_free(ssl->alpn_client_proto_list);
+  EVP_PKEY_free(ssl->tlsext_channel_id_private);
+  OPENSSL_free(ssl->psk_identity_hint);
+  sk_X509_NAME_pop_free(ssl->client_CA, X509_NAME_free);
+  OPENSSL_free(ssl->next_proto_negotiated);
+  sk_SRTP_PROTECTION_PROFILE_free(ssl->srtp_profiles);
 
-  if (s->method != NULL) {
-    s->method->ssl_free(s);
+  if (ssl->method != NULL) {
+    ssl->method->ssl_free(ssl);
   }
-  SSL_CTX_free(s->ctx);
+  SSL_CTX_free(ssl->ctx);
 
-  OPENSSL_free(s);
+  OPENSSL_free(ssl);
 }
 
 void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio) {
@@ -758,21 +750,21 @@
   X509_VERIFY_PARAM_set_depth(s->param, depth);
 }
 
-int SSL_CTX_get_read_ahead(const SSL_CTX *ctx) { return ctx->read_ahead; }
+int SSL_CTX_get_read_ahead(const SSL_CTX *ctx) { return 0; }
 
-int SSL_get_read_ahead(const SSL *s) { return s->read_ahead; }
+int SSL_get_read_ahead(const SSL *s) { return 0; }
 
-void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes) { ctx->read_ahead = !!yes; }
+void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes) { }
 
-void SSL_set_read_ahead(SSL *s, int yes) { s->read_ahead = !!yes; }
+void SSL_set_read_ahead(SSL *s, int yes) { }
 
 int SSL_pending(const SSL *s) {
-  /* SSL_pending cannot work properly if read-ahead is enabled
-   * (SSL_[CTX_]ctrl(..., SSL_CTRL_SET_READ_AHEAD, 1, NULL)), and it is
-   * impossible to fix since SSL_pending cannot report errors that may be
-   * observed while scanning the new data. (Note that SSL_pending() is often
-   * used as a boolean value, so we'd better not return -1.). */
-  return s->method->ssl_pending(s);
+  if (s->rstate == SSL_ST_READ_BODY) {
+    return 0;
+  }
+
+  return (s->s3->rrec.type == SSL3_RT_APPLICATION_DATA) ? s->s3->rrec.length
+                                                        : 0;
 }
 
 X509 *SSL_get_peer_certificate(const SSL *s) {
@@ -895,7 +887,8 @@
     return 0;
   }
 
-  return s->method->ssl_read(s, buf, num);
+  ERR_clear_system_error();
+  return s->method->ssl_read_app_data(s, buf, num, 0);
 }
 
 int SSL_peek(SSL *s, void *buf, int num) {
@@ -908,7 +901,8 @@
     return 0;
   }
 
-  return s->method->ssl_peek(s, buf, num);
+  ERR_clear_system_error();
+  return s->method->ssl_read_app_data(s, buf, num, 1);
 }
 
 int SSL_write(SSL *s, const void *buf, int num) {
@@ -923,7 +917,8 @@
     return -1;
   }
 
-  return s->method->ssl_write(s, buf, num);
+  ERR_clear_system_error();
+  return s->method->ssl_write_app_data(s, buf, num);
 }
 
 int SSL_shutdown(SSL *s) {
@@ -937,32 +932,58 @@
     return -1;
   }
 
-  if (!SSL_in_init(s)) {
-    return s->method->ssl_shutdown(s);
+  if (SSL_in_init(s)) {
+    return 1;
   }
 
-  return 1;
-}
+  /* Do nothing if configured not to send a close_notify. */
+  if (s->quiet_shutdown) {
+    s->shutdown = SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN;
+    return 1;
+  }
 
-int SSL_renegotiate(SSL *s) {
-  if (SSL_IS_DTLS(s)) {
-    /* Renegotiation is not supported for DTLS. */
-    OPENSSL_PUT_ERROR(SSL, SSL_renegotiate, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+  if (!(s->shutdown & SSL_SENT_SHUTDOWN)) {
+    s->shutdown |= SSL_SENT_SHUTDOWN;
+    ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY);
+
+    /* our shutdown alert has been sent now, and if it still needs to be
+     * written, s->s3->alert_dispatch will be true */
+    if (s->s3->alert_dispatch) {
+      return -1; /* return WANT_WRITE */
+    }
+  } else if (s->s3->alert_dispatch) {
+    /* resend it if not sent */
+    int ret = s->method->ssl_dispatch_alert(s);
+    if (ret == -1) {
+      /* we only get to return -1 here the 2nd/Nth invocation, we must  have
+       * already signalled return 0 upon a previous invoation, return
+       * WANT_WRITE */
+      return ret;
+    }
+  } else if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) {
+    /* If we are waiting for a close from our peer, we are closed */
+    s->method->ssl_read_close_notify(s);
+    if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) {
+      return -1; /* return WANT_READ */
+    }
+  }
+
+  if (s->shutdown == (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN) &&
+      !s->s3->alert_dispatch) {
+    return 1;
+  } else {
     return 0;
   }
-
-  if (s->renegotiate == 0) {
-    s->renegotiate = 1;
-  }
-
-  s->new_session = 1;
-  return s->method->ssl_renegotiate(s);
 }
 
-int SSL_renegotiate_pending(SSL *s) {
-  /* becomes true when negotiation is requested; false again once a handshake
-   * has finished */
-  return s->renegotiate != 0;
+int SSL_renegotiate(SSL *ssl) {
+  /* Caller-initiated renegotiation is not supported. */
+  OPENSSL_PUT_ERROR(SSL, SSL_renegotiate, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+  return 0;
+}
+
+int SSL_renegotiate_pending(SSL *ssl) {
+  return SSL_in_init(ssl) && ssl->s3->initial_handshake_complete;
 }
 
 uint32_t SSL_CTX_set_options(SSL_CTX *ctx, uint32_t options) {
@@ -1101,34 +1122,6 @@
   return ctx->method->ssl_ctx_ctrl(ctx, cmd, larg, parg);
 }
 
-int ssl_cipher_id_cmp(const void *in_a, const void *in_b) {
-  long l;
-  const SSL_CIPHER *a = in_a;
-  const SSL_CIPHER *b = in_b;
-  const long a_id = a->id;
-  const long b_id = b->id;
-
-  l = a_id - b_id;
-  if (l == 0L) {
-    return 0;
-  } else {
-    return (l > 0) ? 1 : -1;
-  }
-}
-
-int ssl_cipher_ptr_id_cmp(const SSL_CIPHER **ap, const SSL_CIPHER **bp) {
-  long l;
-  const long a_id = (*ap)->id;
-  const long b_id = (*bp)->id;
-
-  l = a_id - b_id;
-  if (l == 0) {
-    return 0;
-  } else {
-    return (l > 0) ? 1 : -1;
-  }
-}
-
 /* return a STACK of the ciphers available for the SSL and in order of
  * preference */
 STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s) {
@@ -1267,7 +1260,7 @@
         c->algorithm_auth & ct->mask_a) {
       continue;
     }
-    s2n(ssl3_get_cipher_value(c), p);
+    s2n(ssl_cipher_get_value(c), p);
   }
 
   /* If all ciphers were disabled, return the error to the caller. */
@@ -1276,7 +1269,7 @@
   }
 
   /* Add SCSVs. */
-  if (!s->renegotiate) {
+  if (!s->s3->initial_handshake_complete) {
     s2n(SSL3_CK_SCSV & 0xffff, p);
   }
 
@@ -1319,7 +1312,7 @@
     /* Check for SCSV. */
     if (s->s3 && cipher_suite == (SSL3_CK_SCSV & 0xffff)) {
       /* SCSV is fatal if renegotiating. */
-      if (s->renegotiate) {
+      if (s->s3->initial_handshake_complete) {
         OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list,
                           SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);
         ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
@@ -1342,7 +1335,7 @@
       continue;
     }
 
-    c = ssl3_get_cipher_by_value(cipher_suite);
+    c = SSL_get_cipher_by_value(cipher_suite);
     if (c != NULL && !sk_SSL_CIPHER_push(sk, c)) {
       OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list, ERR_R_MALLOC_FAILURE);
       goto err;
@@ -1629,10 +1622,10 @@
   return memcmp(a->session_id, b->session_id, a->session_id_length);
 }
 
-SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) {
+SSL_CTX *SSL_CTX_new(const SSL_METHOD *method) {
   SSL_CTX *ret = NULL;
 
-  if (meth == NULL) {
+  if (method == NULL) {
     OPENSSL_PUT_ERROR(SSL, SSL_CTX_new, SSL_R_NULL_SSL_METHOD_PASSED);
     return NULL;
   }
@@ -1649,7 +1642,9 @@
 
   memset(ret, 0, sizeof(SSL_CTX));
 
-  ret->method = meth->method;
+  ret->method = method->method;
+
+  CRYPTO_MUTEX_init(&ret->lock);
 
   ret->cert_store = NULL;
   ret->session_cache_mode = SSL_SESS_CACHE_SERVER;
@@ -1674,7 +1669,6 @@
   ret->app_verify_arg = NULL;
 
   ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT;
-  ret->read_ahead = 0;
   ret->msg_callback = 0;
   ret->msg_callback_arg = NULL;
   ret->verify_mode = SSL_VERIFY_NONE;
@@ -1743,9 +1737,9 @@
 
   /* Lock the SSL_CTX to the specified version, for compatibility with legacy
    * uses of SSL_METHOD. */
-  if (meth->version != 0) {
-    SSL_CTX_set_max_version(ret, meth->version);
-    SSL_CTX_set_min_version(ret, meth->version);
+  if (method->version != 0) {
+    SSL_CTX_set_max_version(ret, method->version);
+    SSL_CTX_set_min_version(ret, method->version);
   }
 
   return ret;
@@ -1759,7 +1753,7 @@
 
 void SSL_CTX_free(SSL_CTX *ctx) {
   if (ctx == NULL ||
-      CRYPTO_add(&ctx->references, -1, CRYPTO_LOCK_SSL_CTX) > 0) {
+      !CRYPTO_refcount_dec_and_test_zero(&ctx->references)) {
     return;
   }
 
@@ -1775,6 +1769,7 @@
 
   CRYPTO_free_ex_data(&g_ex_data_class_ssl_ctx, ctx, &ctx->ex_data);
 
+  CRYPTO_MUTEX_cleanup(&ctx->lock);
   lh_SSL_SESSION_free(ctx->sessions);
   X509_STORE_free(ctx->cert_store);
   ssl_cipher_preference_list_free(ctx->cipher_list);
@@ -1997,13 +1992,13 @@
       (ctx->session_cache_mode & mode) == mode) {
     /* Automatically flush the internal session cache every 255 connections. */
     int flush_cache = 0;
-    CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+    CRYPTO_MUTEX_lock_write(&ctx->lock);
     ctx->handshakes_since_cache_flush++;
     if (ctx->handshakes_since_cache_flush >= 255) {
       flush_cache = 1;
       ctx->handshakes_since_cache_flush = 0;
     }
-    CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+    CRYPTO_MUTEX_unlock(&ctx->lock);
 
     if (flush_cache) {
       SSL_CTX_flush_sessions(ctx, (unsigned long)time(NULL));
@@ -2124,30 +2119,28 @@
     return -1;
   }
 
-  s->method->ssl_renegotiate_check(s);
-
   if (SSL_in_init(s)) {
     ret = s->handshake_func(s);
   }
   return ret;
 }
 
-void SSL_set_accept_state(SSL *s) {
-  s->server = 1;
-  s->shutdown = 0;
-  s->state = SSL_ST_ACCEPT | SSL_ST_BEFORE;
-  s->handshake_func = s->method->ssl_accept;
+void SSL_set_accept_state(SSL *ssl) {
+  ssl->server = 1;
+  ssl->shutdown = 0;
+  ssl->state = SSL_ST_ACCEPT;
+  ssl->handshake_func = ssl->method->ssl_accept;
   /* clear the current cipher */
-  ssl_clear_cipher_ctx(s);
+  ssl_clear_cipher_ctx(ssl);
 }
 
-void SSL_set_connect_state(SSL *s) {
-  s->server = 0;
-  s->shutdown = 0;
-  s->state = SSL_ST_CONNECT | SSL_ST_BEFORE;
-  s->handshake_func = s->method->ssl_connect;
+void SSL_set_connect_state(SSL *ssl) {
+  ssl->server = 0;
+  ssl->shutdown = 0;
+  ssl->state = SSL_ST_CONNECT;
+  ssl->handshake_func = ssl->method->ssl_connect;
   /* clear the current cipher */
-  ssl_clear_cipher_ctx(s);
+  ssl_clear_cipher_ctx(ssl);
 }
 
 static const char *ssl_get_version(int version) {
@@ -2184,17 +2177,10 @@
 }
 
 void ssl_clear_cipher_ctx(SSL *s) {
-  if (s->aead_read_ctx != NULL) {
-    EVP_AEAD_CTX_cleanup(&s->aead_read_ctx->ctx);
-    OPENSSL_free(s->aead_read_ctx);
-    s->aead_read_ctx = NULL;
-  }
-
-  if (s->aead_write_ctx != NULL) {
-    EVP_AEAD_CTX_cleanup(&s->aead_write_ctx->ctx);
-    OPENSSL_free(s->aead_write_ctx);
-    s->aead_write_ctx = NULL;
-  }
+  SSL_AEAD_CTX_free(s->aead_read_ctx);
+  s->aead_read_ctx = NULL;
+  SSL_AEAD_CTX_free(s->aead_write_ctx);
+  s->aead_write_ctx = NULL;
 }
 
 X509 *SSL_get_certificate(const SSL *s) {
@@ -2230,11 +2216,10 @@
 }
 
 const SSL_CIPHER *SSL_get_current_cipher(const SSL *s) {
-  if (s->session != NULL && s->session->cipher != NULL) {
-    return s->session->cipher;
+  if (s->aead_write_ctx == NULL) {
+    return NULL;
   }
-
-  return NULL;
+  return s->aead_write_ctx->cipher;
 }
 
 const void *SSL_get_current_compression(SSL *s) { return NULL; }
@@ -2322,7 +2307,7 @@
   ssl_cert_free(ssl->cert);
   ssl->cert = ssl_cert_dup(ctx->cert);
 
-  CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX);
+  CRYPTO_refcount_inc(&ctx->references);
   SSL_CTX_free(ssl->ctx); /* decrement reference count */
   ssl->ctx = ctx;
 
@@ -2354,7 +2339,7 @@
 
 int SSL_state(const SSL *ssl) { return ssl->state; }
 
-void SSL_set_state(SSL *ssl, int state) { ssl->state = state; }
+void SSL_set_state(SSL *ssl, int state) { }
 
 void SSL_set_verify_result(SSL *ssl, long arg) { ssl->verify_result = arg; }
 
@@ -2397,8 +2382,6 @@
   return CRYPTO_get_ex_data(&s->ex_data, idx);
 }
 
-int ssl_ok(SSL *s) { return 1; }
-
 X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx) {
   return ctx->cert_store;
 }
@@ -2626,9 +2609,9 @@
     return 0;
   }
 
-  CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+  CRYPTO_MUTEX_lock_write(&ctx->lock);
   ret = BIO_write(bio, out, out_len) >= 0 && BIO_flush(bio);
-  CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+  CRYPTO_MUTEX_unlock(&ctx->lock);
 
   OPENSSL_free(out);
   return ret;
@@ -2666,9 +2649,9 @@
     return 0;
   }
 
-  CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+  CRYPTO_MUTEX_lock_write(&ctx->lock);
   ret = BIO_write(bio, out, out_len) >= 0 && BIO_flush(bio);
-  CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+  CRYPTO_MUTEX_unlock(&ctx->lock);
 
   OPENSSL_free(out);
   return ret;
@@ -2929,11 +2912,7 @@
 }
 
 void SSL_set_reject_peer_renegotiations(SSL *s, int reject) {
-  s->reject_peer_renegotiations = !!reject;
-}
-
-const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value) {
-  return ssl3_get_cipher_by_value(value);
+  s->accept_peer_renegotiations = !reject;
 }
 
 int SSL_get_rc4_state(const SSL *ssl, const RC4_KEY **read_key,
@@ -2946,6 +2925,41 @@
          EVP_AEAD_CTX_get_rc4_state(&ssl->aead_write_ctx->ctx, write_key);
 }
 
+int SSL_get_tls_unique(const SSL *ssl, uint8_t *out, size_t *out_len,
+                       size_t max_out) {
+  /* The tls-unique value is the first Finished message in the handshake, which
+   * is the client's in a full handshake and the server's for a resumption. See
+   * https://tools.ietf.org/html/rfc5929#section-3.1. */
+  const uint8_t *finished = ssl->s3->previous_client_finished;
+  size_t finished_len = ssl->s3->previous_client_finished_len;
+  if (ssl->hit) {
+    /* tls-unique is broken for resumed sessions unless EMS is used. */
+    if (!ssl->session->extended_master_secret) {
+      goto err;
+    }
+    finished = ssl->s3->previous_server_finished;
+    finished_len = ssl->s3->previous_server_finished_len;
+  }
+
+  if (!ssl->s3->initial_handshake_complete ||
+      ssl->version < TLS1_VERSION) {
+    goto err;
+  }
+
+  *out_len = finished_len;
+  if (finished_len > max_out) {
+    *out_len = max_out;
+  }
+
+  memcpy(out, finished, *out_len);
+  return 1;
+
+err:
+  *out_len = 0;
+  memset(out, 0, max_out);
+  return 0;
+}
+
 int SSL_CTX_sess_connect(const SSL_CTX *ctx) { return 0; }
 int SSL_CTX_sess_connect_good(const SSL_CTX *ctx) { return 0; }
 int SSL_CTX_sess_connect_renegotiate(const SSL_CTX *ctx) { return 0; }
diff --git a/src/ssl/ssl_sess.c b/src/ssl/ssl_sess.c
index 3eb428f..9ab4585 100644
--- a/src/ssl/ssl_sess.c
+++ b/src/ssl/ssl_sess.c
@@ -295,13 +295,11 @@
     }
 
     /* Choose which callback will set the session ID */
-    CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
     if (s->generate_session_id) {
       cb = s->generate_session_id;
     } else if (s->initial_ctx->generate_session_id) {
       cb = s->initial_ctx->generate_session_id;
     }
-    CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
 
     /* Choose a session ID */
     tmp = ss->session_id_length;
@@ -419,10 +417,14 @@
       return 0;
     }
     memcpy(data.session_id, ctx->session_id, ctx->session_id_len);
-    CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
-    ret = SSL_SESSION_up_ref(lh_SSL_SESSION_retrieve(s->initial_ctx->sessions,
-                                                     &data));
-    CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
+
+    CRYPTO_MUTEX_lock_read(&s->initial_ctx->lock);
+    ret = lh_SSL_SESSION_retrieve(s->initial_ctx->sessions, &data);
+    CRYPTO_MUTEX_unlock(&s->initial_ctx->lock);
+
+    if (ret != NULL) {
+      SSL_SESSION_up_ref(ret);
+    }
   }
 
   if (try_session_cache && ret == NULL &&
@@ -524,8 +526,9 @@
   SSL_SESSION_up_ref(c);
   /* if session c is in already in cache, we take back the increment later */
 
-  CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+  CRYPTO_MUTEX_lock_write(&ctx->lock);
   if (!lh_SSL_SESSION_insert(ctx->sessions, &s, c)) {
+    CRYPTO_MUTEX_unlock(&ctx->lock);
     return 0;
   }
 
@@ -566,7 +569,7 @@
     }
   }
 
-  CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+  CRYPTO_MUTEX_unlock(&ctx->lock);
   return ret;
 }
 
@@ -580,7 +583,7 @@
 
   if (c != NULL && c->session_id_length != 0) {
     if (lock) {
-      CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+      CRYPTO_MUTEX_lock_write(&ctx->lock);
     }
     r = lh_SSL_SESSION_retrieve(ctx->sessions, c);
     if (r == c) {
@@ -590,7 +593,7 @@
     }
 
     if (lock) {
-      CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+      CRYPTO_MUTEX_unlock(&ctx->lock);
     }
 
     if (ret) {
@@ -607,14 +610,14 @@
 
 SSL_SESSION *SSL_SESSION_up_ref(SSL_SESSION *session) {
   if (session) {
-    CRYPTO_add(&session->references, 1, CRYPTO_LOCK_SSL_SESSION);
+    CRYPTO_refcount_inc(&session->references);
   }
   return session;
 }
 
 void SSL_SESSION_free(SSL_SESSION *session) {
   if (session == NULL ||
-      CRYPTO_add(&session->references, -1, CRYPTO_LOCK_SSL_SESSION) > 0) {
+      !CRYPTO_refcount_dec_and_test_zero(&session->references)) {
     return;
   }
 
@@ -741,18 +744,18 @@
   }
 }
 
-void SSL_CTX_flush_sessions(SSL_CTX *s, long t) {
+void SSL_CTX_flush_sessions(SSL_CTX *ctx, long t) {
   TIMEOUT_PARAM tp;
 
-  tp.ctx = s;
-  tp.cache = s->sessions;
+  tp.ctx = ctx;
+  tp.cache = ctx->sessions;
   if (tp.cache == NULL) {
     return;
   }
   tp.time = t;
-  CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+  CRYPTO_MUTEX_lock_write(&ctx->lock);
   lh_SSL_SESSION_doall_arg(tp.cache, timeout_doall_arg, &tp);
-  CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+  CRYPTO_MUTEX_unlock(&ctx->lock);
 }
 
 int ssl_clear_bad_session(SSL *s) {
diff --git a/src/ssl/ssl_stat.c b/src/ssl/ssl_stat.c
index 8bed9ad..fa5541b 100644
--- a/src/ssl/ssl_stat.c
+++ b/src/ssl/ssl_stat.c
@@ -105,14 +105,6 @@
       str = "SSL renegotiate ciphers";
       break;
 
-    case SSL_ST_BEFORE | SSL_ST_CONNECT:
-      str = "before/connect initialization";
-      break;
-
-    case SSL_ST_BEFORE | SSL_ST_ACCEPT:
-      str = "before/accept initialization";
-      break;
-
     /* SSLv3 additions */
     case SSL3_ST_CW_CLNT_HELLO_A:
       str = "SSLv3 write client hello A";
diff --git a/src/ssl/ssl_test.cc b/src/ssl/ssl_test.cc
index 7886304..b29d28c 100644
--- a/src/ssl/ssl_test.cc
+++ b/src/ssl/ssl_test.cc
@@ -335,6 +335,30 @@
     "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
     "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
 
+// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
+// the final (optional) element of |kCustomSession| with tag number 30.
+static const char kBadSessionExtraField[] =
+    "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
+    "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
+    "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
+    "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
+    "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
+    "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
+    "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
+    "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
+
+// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
+// the version of |kCustomSession| with 2.
+static const char kBadSessionVersion[] =
+    "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
+    "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
+    "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
+    "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
+    "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
+    "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
+    "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
+    "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
+
 static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
   size_t len;
   if (!EVP_DecodedLength(&len, strlen(in))) {
@@ -416,6 +440,23 @@
   return true;
 }
 
+static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
+  std::vector<uint8_t> input;
+  if (!DecodeBase64(&input, input_b64)) {
+    return false;
+  }
+
+  // Verify that the SSL_SESSION fails to decode.
+  const uint8_t *ptr = bssl::vector_data(&input);
+  ScopedSSL_SESSION session(d2i_SSL_SESSION(NULL, &ptr, input.size()));
+  if (session) {
+    fprintf(stderr, "d2i_SSL_SESSION unexpectedly succeeded\n");
+    return false;
+  }
+  ERR_clear_error();
+  return true;
+}
+
 static bool TestDefaultVersion(uint16_t version,
                                const SSL_METHOD *(*method)(void)) {
   ScopedSSL_CTX ctx(SSL_CTX_new(method()));
@@ -431,6 +472,9 @@
     return false;
   }
   ScopedOpenSSLString rfc_name(SSL_CIPHER_get_rfc_name(cipher));
+  if (!rfc_name) {
+    return false;
+  }
   out->assign(rfc_name.get());
   return true;
 }
@@ -491,6 +535,8 @@
   if (!TestCipherRules() ||
       !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
       !TestSSL_SESSIONEncoding(kCustomSession) ||
+      !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
+      !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
       !TestDefaultVersion(0, &TLS_method) ||
       !TestDefaultVersion(SSL3_VERSION, &SSLv3_method) ||
       !TestDefaultVersion(TLS1_VERSION, &TLSv1_method) ||
diff --git a/src/ssl/t1_enc.c b/src/ssl/t1_enc.c
index 3eaffe7..6bd80c3 100644
--- a/src/ssl/t1_enc.c
+++ b/src/ssl/t1_enc.c
@@ -245,7 +245,7 @@
   /* Count number of digests and partition |secret| evenly. */
   count = 0;
   for (idx = 0; ssl_get_handshake_digest(&m, &md, idx); idx++) {
-    if ((m << TLS1_PRF_DGST_SHIFT) & ssl_get_algorithm2(s)) {
+    if (m & ssl_get_algorithm2(s)) {
       count++;
     }
   }
@@ -260,7 +260,7 @@
   S1 = secret;
   memset(out, 0, out_len);
   for (idx = 0; ssl_get_handshake_digest(&m, &md, idx); idx++) {
-    if ((m << TLS1_PRF_DGST_SHIFT) & ssl_get_algorithm2(s)) {
+    if (m & ssl_get_algorithm2(s)) {
       /* If |count| is 2 and |secret_len| is odd, |secret| is partitioned into
        * two halves with an overlapping byte. */
       if (!tls1_P_hash(tmp, out_len, md, S1, len + (secret_len & 1),
@@ -292,114 +292,6 @@
                             SSL3_RANDOM_SIZE);
 }
 
-/* tls1_aead_ctx_init allocates |*aead_ctx|, if needed and returns 1. It
- * returns 0 on malloc error. */
-static int tls1_aead_ctx_init(SSL_AEAD_CTX **aead_ctx) {
-  if (*aead_ctx != NULL) {
-    EVP_AEAD_CTX_cleanup(&(*aead_ctx)->ctx);
-  } else {
-    *aead_ctx = (SSL_AEAD_CTX *)OPENSSL_malloc(sizeof(SSL_AEAD_CTX));
-    if (*aead_ctx == NULL) {
-      OPENSSL_PUT_ERROR(SSL, tls1_aead_ctx_init, ERR_R_MALLOC_FAILURE);
-      return 0;
-    }
-  }
-
-  return 1;
-}
-
-static int tls1_change_cipher_state_aead(SSL *s, char is_read,
-                                         const uint8_t *key, unsigned key_len,
-                                         const uint8_t *iv, unsigned iv_len,
-                                         const uint8_t *mac_secret,
-                                         unsigned mac_secret_len) {
-  const EVP_AEAD *aead = s->s3->tmp.new_aead;
-  SSL_AEAD_CTX *aead_ctx;
-  /* merged_key is used to merge the MAC, cipher, and IV keys for an AEAD which
-   * simulates pre-AEAD cipher suites. */
-  uint8_t merged_key[EVP_AEAD_MAX_KEY_LENGTH];
-
-  if (mac_secret_len > 0) {
-    /* This is a "stateful" AEAD (for compatibility with pre-AEAD cipher
-     * suites). */
-    if (mac_secret_len + key_len + iv_len > sizeof(merged_key)) {
-      OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state_aead,
-                        ERR_R_INTERNAL_ERROR);
-      return 0;
-    }
-    memcpy(merged_key, mac_secret, mac_secret_len);
-    memcpy(merged_key + mac_secret_len, key, key_len);
-    memcpy(merged_key + mac_secret_len + key_len, iv, iv_len);
-    key = merged_key;
-    key_len += mac_secret_len;
-    key_len += iv_len;
-  }
-
-  if (is_read) {
-    if (!tls1_aead_ctx_init(&s->aead_read_ctx)) {
-      return 0;
-    }
-    aead_ctx = s->aead_read_ctx;
-  } else {
-    if (SSL_IS_DTLS(s) && s->aead_write_ctx != NULL) {
-      /* DTLS renegotiation is unsupported, so a CCS can only switch away from
-       * the NULL cipher. This simplifies renegotiation. */
-      OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state_aead,
-                        ERR_R_INTERNAL_ERROR);
-      return 0;
-    }
-    if (!tls1_aead_ctx_init(&s->aead_write_ctx)) {
-      return 0;
-    }
-    aead_ctx = s->aead_write_ctx;
-  }
-
-  if (!EVP_AEAD_CTX_init_with_direction(
-          &aead_ctx->ctx, aead, key, key_len, EVP_AEAD_DEFAULT_TAG_LENGTH,
-          is_read ? evp_aead_open : evp_aead_seal)) {
-    OPENSSL_free(aead_ctx);
-    if (is_read) {
-      s->aead_read_ctx = NULL;
-    } else {
-      s->aead_write_ctx = NULL;
-    }
-
-    return 0;
-  }
-
-  if (mac_secret_len == 0) {
-    /* For a real AEAD, the IV is the fixed part of the nonce. */
-    if (iv_len > sizeof(aead_ctx->fixed_nonce)) {
-      OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state_aead, ERR_R_INTERNAL_ERROR);
-      return 0;
-    }
-
-    memcpy(aead_ctx->fixed_nonce, iv, iv_len);
-    aead_ctx->fixed_nonce_len = iv_len;
-    aead_ctx->variable_nonce_included_in_record =
-      (s->s3->tmp.new_cipher->algorithm2 &
-       SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD) != 0;
-    aead_ctx->random_variable_nonce = 0;
-    aead_ctx->omit_length_in_ad = 0;
-  } else {
-    aead_ctx->fixed_nonce_len = 0;
-    aead_ctx->variable_nonce_included_in_record = 1;
-    aead_ctx->random_variable_nonce = 1;
-    aead_ctx->omit_length_in_ad = 1;
-  }
-  aead_ctx->variable_nonce_len = s->s3->tmp.new_variable_iv_len;
-  aead_ctx->omit_version_in_ad = (s->version == SSL3_VERSION);
-
-  if (aead_ctx->variable_nonce_len + aead_ctx->fixed_nonce_len !=
-      EVP_AEAD_nonce_length(aead)) {
-    OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state_aead, ERR_R_INTERNAL_ERROR);
-    return 0;
-  }
-  aead_ctx->tag_len = EVP_AEAD_max_overhead(aead);
-
-  return 1;
-}
-
 int tls1_change_cipher_state(SSL *s, int which) {
   /* is_read is true if we have just read a ChangeCipherSpec message - i.e. we
    * need to update the read cipherspec. Otherwise we have just written one. */
@@ -470,8 +362,21 @@
     return 0;
   }
 
-  return tls1_change_cipher_state_aead(s, is_read, key, key_len, iv, iv_len,
-                                       mac_secret, mac_secret_len);
+  if (is_read) {
+    SSL_AEAD_CTX_free(s->aead_read_ctx);
+    s->aead_read_ctx = SSL_AEAD_CTX_new(
+        evp_aead_open, ssl3_version_from_wire(s, s->version),
+        s->s3->tmp.new_cipher, key, key_len, mac_secret, mac_secret_len, iv,
+        iv_len);
+    return s->aead_read_ctx != NULL;
+  } else {
+    SSL_AEAD_CTX_free(s->aead_write_ctx);
+    s->aead_write_ctx = SSL_AEAD_CTX_new(
+        evp_aead_seal, ssl3_version_from_wire(s, s->version),
+        s->s3->tmp.new_cipher, key, key_len, mac_secret, mac_secret_len, iv,
+        iv_len);
+    return s->aead_write_ctx != NULL;
+  }
 }
 
 int tls1_setup_key_block(SSL *s) {
@@ -564,153 +469,6 @@
   return 0;
 }
 
-/* tls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|,
- * respectively. It returns one on success and zero on failure. */
-int tls1_enc(SSL *s, int send) {
-  SSL3_RECORD *rec;
-  const SSL_AEAD_CTX *aead;
-
-  if (send) {
-    rec = &s->s3->wrec;
-    aead = s->aead_write_ctx;
-  } else {
-    rec = &s->s3->rrec;
-    aead = s->aead_read_ctx;
-  }
-
-  if (aead == NULL) {
-    /* Handle the initial NULL cipher. */
-    memmove(rec->data, rec->input, rec->length);
-    rec->input = rec->data;
-    return 1;
-  }
-
-  uint8_t ad[13], *seq, *in, *out, nonce[EVP_AEAD_MAX_NONCE_LENGTH];
-  unsigned nonce_used;
-  size_t n, ad_len;
-
-  seq = send ? s->s3->write_sequence : s->s3->read_sequence;
-
-  if (SSL_IS_DTLS(s)) {
-    uint8_t dtlsseq[9], *p = dtlsseq;
-
-    s2n(send ? s->d1->w_epoch : s->d1->r_epoch, p);
-    memcpy(p, &seq[2], 6);
-    memcpy(ad, dtlsseq, 8);
-  } else {
-    memcpy(ad, seq, 8);
-    if (!ssl3_record_sequence_update(seq, 8)) {
-      return 0;
-    }
-  }
-
-  ad[8] = rec->type;
-  ad_len = 9;
-  if (!aead->omit_version_in_ad) {
-    ad[ad_len++] = (uint8_t)(s->version >> 8);
-    ad[ad_len++] = (uint8_t)(s->version);
-  }
-
-  if (aead->fixed_nonce_len + aead->variable_nonce_len > sizeof(nonce)) {
-    OPENSSL_PUT_ERROR(SSL, tls1_enc, ERR_R_INTERNAL_ERROR);
-    return 0;
-  }
-
-  memcpy(nonce, aead->fixed_nonce, aead->fixed_nonce_len);
-  nonce_used = aead->fixed_nonce_len;
-
-  if (send) {
-    size_t len = rec->length;
-    size_t eivlen = 0;
-    in = rec->input;
-    out = rec->data;
-
-    uint8_t *variable_nonce = nonce + nonce_used;
-    if (aead->random_variable_nonce) {
-      assert(aead->variable_nonce_included_in_record);
-      if (!RAND_bytes(nonce + nonce_used, aead->variable_nonce_len)) {
-        return 0;
-      }
-    } else {
-      /* When sending we use the sequence number as the variable part of the
-       * nonce. */
-      if (aead->variable_nonce_len != 8) {
-        OPENSSL_PUT_ERROR(SSL, tls1_enc, ERR_R_INTERNAL_ERROR);
-        return 0;
-      }
-      memcpy(nonce + nonce_used, ad, aead->variable_nonce_len);
-    }
-    nonce_used += aead->variable_nonce_len;
-
-    /* in do_ssl3_write, rec->input is moved forward by variable_nonce_len in
-     * order to leave space for the variable nonce. Thus we can copy the
-     * sequence number bytes into place without overwriting any of the
-     * plaintext. */
-    if (aead->variable_nonce_included_in_record) {
-      memcpy(out, variable_nonce, aead->variable_nonce_len);
-      len -= aead->variable_nonce_len;
-      eivlen = aead->variable_nonce_len;
-    }
-
-    if (!aead->omit_length_in_ad) {
-      ad[ad_len++] = len >> 8;
-      ad[ad_len++] = len & 0xff;
-    }
-
-    if (!EVP_AEAD_CTX_seal(&aead->ctx, out + eivlen, &n, len + aead->tag_len,
-                           nonce, nonce_used, in + eivlen, len, ad, ad_len)) {
-      return 0;
-    }
-
-    if (aead->variable_nonce_included_in_record) {
-      n += aead->variable_nonce_len;
-    }
-  } else {
-    /* receive */
-    size_t len = rec->length;
-
-    if (rec->data != rec->input) {
-      OPENSSL_PUT_ERROR(SSL, tls1_enc, ERR_R_INTERNAL_ERROR);
-      return 0;
-    }
-    out = in = rec->input;
-
-    if (len < aead->variable_nonce_len) {
-      return 0;
-    }
-    memcpy(nonce + nonce_used,
-           aead->variable_nonce_included_in_record ? in : ad,
-           aead->variable_nonce_len);
-    nonce_used += aead->variable_nonce_len;
-
-    if (aead->variable_nonce_included_in_record) {
-      in += aead->variable_nonce_len;
-      len -= aead->variable_nonce_len;
-      out += aead->variable_nonce_len;
-    }
-
-    if (!aead->omit_length_in_ad) {
-      if (len < aead->tag_len) {
-        return 0;
-      }
-      size_t plaintext_len = len - aead->tag_len;
-
-      ad[ad_len++] = plaintext_len >> 8;
-      ad[ad_len++] = plaintext_len & 0xff;
-    }
-
-    if (!EVP_AEAD_CTX_open(&aead->ctx, out, &n, rec->length, nonce, nonce_used, in,
-                           len, ad, ad_len)) {
-      return 0;
-    }
-
-    rec->data = rec->input = out;
-  }
-
-  rec->length = n;
-  return 1;
-}
-
 int tls1_cert_verify_mac(SSL *s, int md_nid, uint8_t *out) {
   unsigned int ret;
   EVP_MD_CTX ctx, *d = NULL;
@@ -796,6 +554,11 @@
   int err = 0;
   int digests_len;
 
+  /* At this point, the handshake should have released the handshake buffer on
+   * its own.
+   * TODO(davidben): Apart from initialization, the handshake buffer should be
+   * orthogonal to the handshake digest. https://crbug.com/492371 */
+  assert(s->s3->handshake_buffer == NULL);
   if (s->s3->handshake_buffer &&
       !ssl3_digest_cached_records(s, free_handshake_buffer)) {
     return 0;
diff --git a/src/ssl/t1_lib.c b/src/ssl/t1_lib.c
index 58b7f04..9e5c011 100644
--- a/src/ssl/t1_lib.c
+++ b/src/ssl/t1_lib.c
@@ -129,7 +129,6 @@
 static int ssl_check_serverhello_tlsext(SSL *s);
 
 const SSL3_ENC_METHOD TLSv1_enc_data = {
-    tls1_enc,
     tls1_prf,
     tls1_setup_key_block,
     tls1_generate_master_secret,
@@ -144,7 +143,6 @@
 };
 
 const SSL3_ENC_METHOD TLSv1_1_enc_data = {
-    tls1_enc,
     tls1_prf,
     tls1_setup_key_block,
     tls1_generate_master_secret,
@@ -159,7 +157,6 @@
 };
 
 const SSL3_ENC_METHOD TLSv1_2_enc_data = {
-    tls1_enc,
     tls1_prf,
     tls1_setup_key_block,
     tls1_generate_master_secret,
@@ -874,7 +871,7 @@
   }
 
   /* Add RI if renegotiating */
-  if (s->renegotiate) {
+  if (s->s3->initial_handshake_complete) {
     int el;
 
     if (!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0)) {
@@ -908,7 +905,12 @@
 
   if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) {
     int ticklen = 0;
-    if (!s->new_session && s->session && s->session->tlsext_tick) {
+    /* Renegotiation does not participate in session resumption. However, still
+     * advertise the extension to avoid potentially breaking servers which carry
+     * over the state from the previous handshake, such as OpenSSL servers
+     * without upstream's 3c3f0259238594d77264a78944d409f2127642c4. */
+    if (!s->s3->initial_handshake_complete && s->session != NULL &&
+        s->session->tlsext_tick != NULL) {
       ticklen = s->session->tlsext_ticklen;
     }
 
@@ -957,7 +959,7 @@
     s2n(0, ret);
   }
 
-  if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len &&
+  if (s->ctx->next_proto_select_cb && !s->s3->initial_handshake_complete &&
       !SSL_IS_DTLS(s)) {
     /* The client advertises an emtpy extension to indicate its support for
      * Next Protocol Negotiation */
@@ -968,7 +970,7 @@
     s2n(0, ret);
   }
 
-  if (s->signed_cert_timestamps_enabled && !s->s3->tmp.finish_md_len) {
+  if (s->signed_cert_timestamps_enabled) {
     /* The client advertises an empty extension to indicate its support for
      * certificate timestamps. */
     if (limit - ret - 4 < 0) {
@@ -978,7 +980,7 @@
     s2n(0, ret);
   }
 
-  if (s->alpn_client_proto_list && !s->s3->tmp.finish_md_len) {
+  if (s->alpn_client_proto_list && !s->s3->initial_handshake_complete) {
     if ((size_t)(limit - ret) < 6 + s->alpn_client_proto_list_len) {
       return NULL;
     }
@@ -1587,29 +1589,16 @@
         return 0;
       }
     } else if (type == TLSEXT_TYPE_next_proto_neg &&
-               s->s3->tmp.finish_md_len == 0 && s->s3->alpn_selected == NULL &&
-               !SSL_IS_DTLS(s)) {
+               !s->s3->initial_handshake_complete &&
+               s->s3->alpn_selected == NULL && !SSL_IS_DTLS(s)) {
       /* The extension must be empty. */
       if (CBS_len(&extension) != 0) {
         *out_alert = SSL_AD_DECODE_ERROR;
         return 0;
       }
-
-      /* We shouldn't accept this extension on a renegotiation.
-       *
-       * s->new_session will be set on renegotiation, but we probably shouldn't
-       * rely that it couldn't be set on the initial renegotation too in
-       * certain cases (when there's some other reason to disallow resuming an
-       * earlier session -- the current code won't be doing anything like that,
-       * but this might change).
-
-       * A valid sign that there's been a previous handshake in this connection
-       * is if s->s3->tmp.finish_md_len > 0.  (We are talking about a check
-       * that will happen in the Hello protocol round, well before a new
-       * Finished message could have been computed.) */
       s->s3->next_proto_neg_seen = 1;
     } else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation &&
-               s->ctx->alpn_select_cb && s->s3->tmp.finish_md_len == 0) {
+               s->ctx->alpn_select_cb && !s->s3->initial_handshake_complete) {
       if (!tls1_alpn_handle_client_hello(s, &extension, out_alert)) {
         return 0;
       }
@@ -1652,7 +1641,7 @@
 ri_check:
   /* Need RI if renegotiating */
 
-  if (!renegotiate_seen && s->renegotiate &&
+  if (!renegotiate_seen && s->s3->initial_handshake_complete &&
       !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
     *out_alert = SSL_AD_HANDSHAKE_FAILURE;
     OPENSSL_PUT_ERROR(SSL, ssl_scan_clienthello_tlsext,
@@ -1791,8 +1780,7 @@
       /* Set a flag to expect a CertificateStatus message */
       s->s3->tmp.certificate_status_expected = 1;
     } else if (type == TLSEXT_TYPE_next_proto_neg &&
-               s->s3->tmp.finish_md_len == 0 &&
-               !SSL_IS_DTLS(s)) {
+               !s->s3->initial_handshake_complete && !SSL_IS_DTLS(s)) {
       uint8_t *selected;
       uint8_t selected_len;
 
@@ -1824,7 +1812,8 @@
 
       s->next_proto_negotiated_len = selected_len;
       s->s3->next_proto_neg_seen = 1;
-    } else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation) {
+    } else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation &&
+               !s->s3->initial_handshake_complete) {
       CBS protocol_name_list, protocol_name;
 
       /* We must have requested it. */
diff --git a/src/ssl/test/CMakeLists.txt b/src/ssl/test/CMakeLists.txt
index a0d7a5e..3b07903 100644
--- a/src/ssl/test/CMakeLists.txt
+++ b/src/ssl/test/CMakeLists.txt
@@ -5,9 +5,10 @@
 
   async_bio.cc
   bssl_shim.cc
-  malloc.cc
   packeted_bio.cc
   test_config.cc
+
+  $<TARGET_OBJECTS:test_support>
 )
 
 target_link_libraries(bssl_shim ssl crypto)
diff --git a/src/ssl/test/bssl_shim.cc b/src/ssl/test/bssl_shim.cc
index 1cf96f2..40cb149 100644
--- a/src/ssl/test/bssl_shim.cc
+++ b/src/ssl/test/bssl_shim.cc
@@ -406,14 +406,6 @@
     return nullptr;
   }
 
-  if (config->is_dtls) {
-    // DTLS needs read-ahead to function on a datagram BIO.
-    //
-    // TODO(davidben): this should not be necessary. DTLS code should only
-    // expect a datagram BIO.
-    SSL_CTX_set_read_ahead(ssl_ctx.get(), 1);
-  }
-
   if (!SSL_CTX_set_cipher_list(ssl_ctx.get(), "ALL")) {
     return nullptr;
   }
@@ -599,6 +591,9 @@
   if (config->allow_unsafe_legacy_renegotiation) {
     SSL_set_options(ssl.get(), SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
   }
+  if (config->no_legacy_server_connect) {
+    SSL_clear_options(ssl.get(), SSL_OP_LEGACY_SERVER_CONNECT);
+  }
   if (!config->expected_channel_id.empty()) {
     SSL_enable_tls_channel_id(ssl.get());
   }
@@ -660,8 +655,9 @@
       !SSL_set_cipher_list(ssl.get(), config->cipher.c_str())) {
     return false;
   }
-  if (config->reject_peer_renegotiations) {
-    SSL_set_reject_peer_renegotiations(ssl.get(), 1);
+  if (!config->reject_peer_renegotiations) {
+    /* Renegotiations are disabled by default. */
+    SSL_set_reject_peer_renegotiations(ssl.get(), 0);
   }
 
   int sock = Connect(config->port);
@@ -703,6 +699,11 @@
     }
   }
 
+  if (SSL_get_current_cipher(ssl.get()) != nullptr) {
+    fprintf(stderr, "non-null cipher before handshake\n");
+    return false;
+  }
+
   int ret;
   if (config->implicit_handshake) {
     if (config->is_server) {
@@ -722,6 +723,11 @@
       return false;
     }
 
+    if (SSL_get_current_cipher(ssl.get()) == nullptr) {
+      fprintf(stderr, "null cipher after handshake\n");
+      return false;
+    }
+
     if (is_resume &&
         (!!SSL_session_reused(ssl.get()) == config->expect_session_miss)) {
       fprintf(stderr, "session was%s reused\n",
@@ -834,30 +840,6 @@
     }
   }
 
-  if (config->renegotiate) {
-    if (config->async) {
-      fprintf(stderr, "-renegotiate is not supported with -async.\n");
-      return false;
-    }
-    if (config->implicit_handshake) {
-      fprintf(stderr, "-renegotiate is not supported with -implicit-handshake.\n");
-      return false;
-    }
-
-    SSL_renegotiate(ssl.get());
-
-    ret = SSL_do_handshake(ssl.get());
-    if (ret != 1) {
-      return false;
-    }
-
-    SSL_set_state(ssl.get(), SSL_ST_ACCEPT);
-    ret = SSL_do_handshake(ssl.get());
-    if (ret != 1) {
-      return false;
-    }
-  }
-
   if (config->export_keying_material > 0) {
     std::vector<uint8_t> result(
         static_cast<size_t>(config->export_keying_material));
@@ -874,6 +856,26 @@
     }
   }
 
+  if (config->tls_unique) {
+    uint8_t tls_unique[16];
+    size_t tls_unique_len;
+    if (!SSL_get_tls_unique(ssl.get(), tls_unique, &tls_unique_len,
+                            sizeof(tls_unique))) {
+      fprintf(stderr, "failed to get tls-unique\n");
+      return false;
+    }
+
+    if (tls_unique_len != 12) {
+      fprintf(stderr, "expected 12 bytes of tls-unique but got %u",
+              static_cast<unsigned>(tls_unique_len));
+      return false;
+    }
+
+    if (WriteAll(ssl.get(), tls_unique, tls_unique_len) < 0) {
+      return false;
+    }
+  }
+
   if (config->write_different_record_sizes) {
     if (config->is_dtls) {
       fprintf(stderr, "write_different_record_sizes not supported for DTLS\n");
diff --git a/src/ssl/test/runner/common.go b/src/ssl/test/runner/common.go
index 4ac7250..edebba1 100644
--- a/src/ssl/test/runner/common.go
+++ b/src/ssl/test/runner/common.go
@@ -188,6 +188,7 @@
 	VerifiedChains             [][]*x509.Certificate // verified chains built from PeerCertificates
 	ChannelID                  *ecdsa.PublicKey      // the channel ID for this connection
 	SRTPProtectionProfile      uint16                // the negotiated DTLS-SRTP protection profile
+	TLSUnique                  []byte
 }
 
 // ClientAuthType declares the policy the server will follow for
@@ -478,7 +479,9 @@
 	// MaxHandshakeRecordLength, if non-zero, is the maximum size of a
 	// handshake record. Handshake messages will be split into multiple
 	// records at the specified size, except that the client_version will
-	// never be fragmented.
+	// never be fragmented. For DTLS, it is the maximum handshake fragment
+	// size, not record size; DTLS allows multiple handshake fragments in a
+	// single handshake record. See |PackHandshakeFragments|.
 	MaxHandshakeRecordLength int
 
 	// FragmentClientVersion will allow MaxHandshakeRecordLength to apply to
@@ -681,13 +684,14 @@
 	// fragments in DTLS.
 	SendEmptyFragments bool
 
-	// NeverResumeOnRenego, if true, causes renegotiations to always be full
-	// handshakes.
-	NeverResumeOnRenego bool
+	// SendSplitAlert, if true, causes an alert to be sent with the header
+	// and record body split across multiple packets. The peer should
+	// discard these packets rather than process it.
+	SendSplitAlert bool
 
-	// NoSignatureAlgorithmsOnRenego, if true, causes renegotiations to omit
-	// the signature_algorithms extension.
-	NoSignatureAlgorithmsOnRenego bool
+	// FailIfResumeOnRenego, if true, causes renegotiations to fail if the
+	// client offers a resumption or the server accepts one.
+	FailIfResumeOnRenego bool
 
 	// IgnorePeerCipherPreferences, if true, causes the peer's cipher
 	// preferences to be ignored.
@@ -707,6 +711,22 @@
 
 	// BadFinished, if true, causes the Finished hash to be broken.
 	BadFinished bool
+
+	// DHGroupPrime, if not nil, is used to define the (finite field)
+	// Diffie-Hellman group. The generator used is always two.
+	DHGroupPrime *big.Int
+
+	// PackHandshakeFragments, if true, causes handshake fragments to be
+	// packed into individual handshake records, up to the specified record
+	// size.
+	PackHandshakeFragments int
+
+	// PackHandshakeRecords, if true, causes handshake records to be packed
+	// into individual packets, up to the specified packet size.
+	PackHandshakeRecords int
+
+	// EnableAllCiphersInDTLS, if true, causes RC4 to be enabled in DTLS.
+	EnableAllCiphersInDTLS bool
 }
 
 func (c *Config) serverInit() {
diff --git a/src/ssl/test/runner/conn.go b/src/ssl/test/runner/conn.go
index fd198ca..adbc1c3 100644
--- a/src/ssl/test/runner/conn.go
+++ b/src/ssl/test/runner/conn.go
@@ -44,7 +44,11 @@
 	// opposed to the ones presented by the server.
 	verifiedChains [][]*x509.Certificate
 	// serverName contains the server name indicated by the client, if any.
-	serverName                 string
+	serverName string
+	// firstFinished contains the first Finished hash sent during the
+	// handshake. This is the "tls-unique" channel binding value.
+	firstFinished [12]byte
+
 	clientRandom, serverRandom [32]byte
 	masterSecret               [48]byte
 
@@ -1260,6 +1264,15 @@
 		return nil
 	}
 
+	if c.isDTLS && c.config.Bugs.SendSplitAlert {
+		c.conn.Write([]byte{
+			byte(recordTypeAlert), // type
+			0xfe, 0xff, // version
+			0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // sequence
+			0x0, 0x2, // length
+		})
+		c.conn.Write([]byte{alertLevelError, byte(alertInternalError)})
+	}
 	if c.isClient {
 		c.handshakeErr = c.clientHandshake()
 	} else {
@@ -1290,6 +1303,7 @@
 		state.ServerName = c.serverName
 		state.ChannelID = c.channelID
 		state.SRTPProtectionProfile = c.srtpProtectionProfile
+		state.TLSUnique = c.firstFinished[:]
 	}
 
 	return state
diff --git a/src/ssl/test/runner/dtls.go b/src/ssl/test/runner/dtls.go
index 85c4247..50f7786 100644
--- a/src/ssl/test/runner/dtls.go
+++ b/src/ssl/test/runner/dtls.go
@@ -196,6 +196,8 @@
 		return nil
 	}
 
+	// This is a test-only DTLS implementation, so there is no need to
+	// retain |c.pendingFragments| for a future retransmit.
 	var fragments [][]byte
 	fragments, c.pendingFragments = c.pendingFragments, fragments
 
@@ -208,38 +210,66 @@
 		fragments = tmp
 	}
 
-	// Send them all.
+	maxRecordLen := c.config.Bugs.PackHandshakeFragments
+	maxPacketLen := c.config.Bugs.PackHandshakeRecords
+
+	// Pack handshake fragments into records.
+	var records [][]byte
 	for _, fragment := range fragments {
 		if c.config.Bugs.SplitFragmentHeader {
-			if _, err := c.dtlsWriteRawRecord(recordTypeHandshake, fragment[:2]); err != nil {
-				return err
+			records = append(records, fragment[:2])
+			records = append(records, fragment[2:])
+		} else if c.config.Bugs.SplitFragmentBody {
+			if len(fragment) > 12 {
+				records = append(records, fragment[:13])
+				records = append(records, fragment[13:])
+			} else {
+				records = append(records, fragment)
 			}
-			fragment = fragment[2:]
-		} else if c.config.Bugs.SplitFragmentBody && len(fragment) > 12 {
-			if _, err := c.dtlsWriteRawRecord(recordTypeHandshake, fragment[:13]); err != nil {
-				return err
-			}
-			fragment = fragment[13:]
+		} else if i := len(records) - 1; len(records) > 0 && len(records[i])+len(fragment) <= maxRecordLen {
+			records[i] = append(records[i], fragment...)
+		} else {
+			// The fragment will be appended to, so copy it.
+			records = append(records, append([]byte{}, fragment...))
+		}
+	}
+
+	// Format them into packets.
+	var packets [][]byte
+	for _, record := range records {
+		b, err := c.dtlsSealRecord(recordTypeHandshake, record)
+		if err != nil {
+			return err
 		}
 
-		// TODO(davidben): A real DTLS implementation needs to
-		// retransmit handshake messages. For testing purposes, we don't
-		// actually care.
-		if _, err := c.dtlsWriteRawRecord(recordTypeHandshake, fragment); err != nil {
+		if i := len(packets) - 1; len(packets) > 0 && len(packets[i])+len(b.data) <= maxPacketLen {
+			packets[i] = append(packets[i], b.data...)
+		} else {
+			// The sealed record will be appended to and reused by
+			// |c.out|, so copy it.
+			packets = append(packets, append([]byte{}, b.data...))
+		}
+		c.out.freeBlock(b)
+	}
+
+	// Send all the packets.
+	for _, packet := range packets {
+		if _, err := c.conn.Write(packet); err != nil {
 			return err
 		}
 	}
 	return nil
 }
 
-func (c *Conn) dtlsWriteRawRecord(typ recordType, data []byte) (n int, err error) {
+// dtlsSealRecord seals a record into a block from |c.out|'s pool.
+func (c *Conn) dtlsSealRecord(typ recordType, data []byte) (b *block, err error) {
 	recordHeaderLen := dtlsRecordHeaderLen
 	maxLen := c.config.Bugs.MaxHandshakeRecordLength
 	if maxLen <= 0 {
 		maxLen = 1024
 	}
 
-	b := c.out.newBlock()
+	b = c.out.newBlock()
 
 	explicitIVLen := 0
 	explicitIVIsSeq := false
@@ -286,6 +316,14 @@
 	}
 	copy(b.data[recordHeaderLen+explicitIVLen:], data)
 	c.out.encrypt(b, explicitIVLen)
+	return
+}
+
+func (c *Conn) dtlsWriteRawRecord(typ recordType, data []byte) (n int, err error) {
+	b, err := c.dtlsSealRecord(typ, data)
+	if err != nil {
+		return
+	}
 
 	_, err = c.conn.Write(b.data)
 	if err != nil {
diff --git a/src/ssl/test/runner/handshake_client.go b/src/ssl/test/runner/handshake_client.go
index 0dac05d..a950313 100644
--- a/src/ssl/test/runner/handshake_client.go
+++ b/src/ssl/test/runner/handshake_client.go
@@ -115,7 +115,7 @@
 				continue
 			}
 			// Don't advertise non-DTLS cipher suites on DTLS.
-			if c.isDTLS && suite.flags&suiteNoDTLS != 0 {
+			if c.isDTLS && suite.flags&suiteNoDTLS != 0 && !c.config.Bugs.EnableAllCiphersInDTLS {
 				continue
 			}
 			hello.cipherSuites = append(hello.cipherSuites, suiteId)
@@ -133,16 +133,13 @@
 		return errors.New("tls: short read from Rand: " + err.Error())
 	}
 
-	if hello.vers >= VersionTLS12 && !c.config.Bugs.NoSignatureAndHashes && (c.cipherSuite == nil || !c.config.Bugs.NoSignatureAlgorithmsOnRenego) {
+	if hello.vers >= VersionTLS12 && !c.config.Bugs.NoSignatureAndHashes {
 		hello.signatureAndHashes = c.config.signatureAndHashesForClient()
 	}
 
 	var session *ClientSessionState
 	var cacheKey string
 	sessionCache := c.config.ClientSessionCache
-	if c.config.Bugs.NeverResumeOnRenego && c.cipherSuite != nil {
-		sessionCache = nil
-	}
 
 	if sessionCache != nil {
 		hello.ticketSupported = !c.config.SessionTicketsDisabled
@@ -316,10 +313,10 @@
 		if err := hs.readSessionTicket(); err != nil {
 			return err
 		}
-		if err := hs.readFinished(); err != nil {
+		if err := hs.readFinished(c.firstFinished[:]); err != nil {
 			return err
 		}
-		if err := hs.sendFinished(isResume); err != nil {
+		if err := hs.sendFinished(nil, isResume); err != nil {
 			return err
 		}
 	} else {
@@ -329,7 +326,7 @@
 		if err := hs.establishKeys(); err != nil {
 			return err
 		}
-		if err := hs.sendFinished(isResume); err != nil {
+		if err := hs.sendFinished(c.firstFinished[:], isResume); err != nil {
 			return err
 		}
 		// Most retransmits are triggered by a timeout, but the final
@@ -344,7 +341,7 @@
 		if err := hs.readSessionTicket(); err != nil {
 			return err
 		}
-		if err := hs.readFinished(); err != nil {
+		if err := hs.readFinished(nil); err != nil {
 			return err
 		}
 	}
@@ -727,6 +724,12 @@
 	}
 
 	if hs.serverResumedSession() {
+		// For test purposes, assert that the server never accepts the
+		// resumption offer on renegotiation.
+		if c.cipherSuite != nil && c.config.Bugs.FailIfResumeOnRenego {
+			return false, errors.New("tls: server resumed session on renegotiation")
+		}
+
 		// Restore masterSecret and peerCerts from previous state
 		hs.masterSecret = hs.session.masterSecret
 		c.peerCertificates = hs.session.serverCertificates
@@ -737,7 +740,7 @@
 	return false, nil
 }
 
-func (hs *clientHandshakeState) readFinished() error {
+func (hs *clientHandshakeState) readFinished(out []byte) error {
 	c := hs.c
 
 	c.readRecord(recordTypeChangeCipherSpec)
@@ -764,6 +767,7 @@
 		}
 	}
 	c.serverVerify = append(c.serverVerify[:0], serverFinished.verifyData...)
+	copy(out, serverFinished.verifyData)
 	hs.writeServerHash(serverFinished.marshal())
 	return nil
 }
@@ -807,7 +811,7 @@
 	return nil
 }
 
-func (hs *clientHandshakeState) sendFinished(isResume bool) error {
+func (hs *clientHandshakeState) sendFinished(out []byte, isResume bool) error {
 	c := hs.c
 
 	var postCCSBytes []byte
@@ -859,6 +863,7 @@
 	} else {
 		finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
 	}
+	copy(out, finished.verifyData)
 	if c.config.Bugs.BadFinished {
 		finished.verifyData[0]++
 	}
diff --git a/src/ssl/test/runner/handshake_server.go b/src/ssl/test/runner/handshake_server.go
index 59ed9df..85cc0d2 100644
--- a/src/ssl/test/runner/handshake_server.go
+++ b/src/ssl/test/runner/handshake_server.go
@@ -69,7 +69,7 @@
 				return err
 			}
 		}
-		if err := hs.sendFinished(); err != nil {
+		if err := hs.sendFinished(c.firstFinished[:]); err != nil {
 			return err
 		}
 		// Most retransmits are triggered by a timeout, but the final
@@ -81,7 +81,7 @@
 		}); err != nil {
 			return err
 		}
-		if err := hs.readFinished(isResume); err != nil {
+		if err := hs.readFinished(nil, isResume); err != nil {
 			return err
 		}
 		c.didResume = true
@@ -94,7 +94,7 @@
 		if err := hs.establishKeys(); err != nil {
 			return err
 		}
-		if err := hs.readFinished(isResume); err != nil {
+		if err := hs.readFinished(c.firstFinished[:], isResume); err != nil {
 			return err
 		}
 		if c.config.Bugs.AlertBeforeFalseStartTest != 0 {
@@ -108,7 +108,7 @@
 		if err := hs.sendSessionTicket(); err != nil {
 			return err
 		}
-		if err := hs.sendFinished(); err != nil {
+		if err := hs.sendFinished(nil); err != nil {
 			return err
 		}
 	}
@@ -274,6 +274,10 @@
 		hs.hello.secureRenegotiation = hs.clientHello.secureRenegotiation
 	}
 
+	if c.config.Bugs.NoRenegotiationInfo {
+		hs.hello.secureRenegotiation = nil
+	}
+
 	hs.hello.compressionMethod = compressionNone
 	hs.hello.duplicateExtension = c.config.Bugs.DuplicateExtension
 	if len(hs.clientHello.serverName) > 0 {
@@ -333,6 +337,12 @@
 
 	_, hs.ecdsaOk = hs.cert.PrivateKey.(*ecdsa.PrivateKey)
 
+	// For test purposes, check that the peer never offers a session when
+	// renegotiating.
+	if c.cipherSuite != nil && len(hs.clientHello.sessionId) > 0 && c.config.Bugs.FailIfResumeOnRenego {
+		return false, errors.New("tls: offered resumption on renegotiation")
+	}
+
 	if hs.checkForResumption() {
 		return true, nil
 	}
@@ -382,10 +392,6 @@
 func (hs *serverHandshakeState) checkForResumption() bool {
 	c := hs.c
 
-	if c.config.Bugs.NeverResumeOnRenego && c.cipherSuite != nil {
-		return false
-	}
-
 	if len(hs.clientHello.sessionTicket) > 0 {
 		if c.config.SessionTicketsDisabled {
 			return false
@@ -748,7 +754,7 @@
 	return nil
 }
 
-func (hs *serverHandshakeState) readFinished(isResume bool) error {
+func (hs *serverHandshakeState) readFinished(out []byte, isResume bool) error {
 	c := hs.c
 
 	c.readRecord(recordTypeChangeCipherSpec)
@@ -817,6 +823,7 @@
 		return errors.New("tls: client's Finished message is incorrect")
 	}
 	c.clientVerify = append(c.clientVerify[:0], clientFinished.verifyData...)
+	copy(out, clientFinished.verifyData)
 
 	hs.writeClientHash(clientFinished.marshal())
 	return nil
@@ -853,11 +860,12 @@
 	return nil
 }
 
-func (hs *serverHandshakeState) sendFinished() error {
+func (hs *serverHandshakeState) sendFinished(out []byte) error {
 	c := hs.c
 
 	finished := new(finishedMsg)
 	finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret)
+	copy(out, finished.verifyData)
 	if c.config.Bugs.BadFinished {
 		finished.verifyData[0]++
 	}
diff --git a/src/ssl/test/runner/key_agreement.go b/src/ssl/test/runner/key_agreement.go
index 5e44b54..2ee0087 100644
--- a/src/ssl/test/runner/key_agreement.go
+++ b/src/ssl/test/runner/key_agreement.go
@@ -561,11 +561,18 @@
 }
 
 func (ka *dheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
-	// 2048-bit MODP Group with 256-bit Prime Order Subgroup (RFC
-	// 5114, Section 2.3)
-	ka.p, _ = new(big.Int).SetString("87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F25D2CEED4435E3B00E00DF8F1D61957D4FAF7DF4561B2AA3016C3D91134096FAA3BF4296D830E9A7C209E0C6497517ABD5A8A9D306BCF67ED91F9E6725B4758C022E0B1EF4275BF7B6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF12307F5C4FDB70C581B23F76B63ACAE1CAA6B7902D52526735488A0EF13C6D9A51BFA4AB3AD8347796524D8EF6A167B5A41825D967E144E5140564251CCACB83E6B486F6B3CA3F7971506026C0B857F689962856DED4010ABD0BE621C3A3960A54E710C375F26375D7014103A4B54330C198AF126116D2276E11715F693877FAD7EF09CADB094AE91E1A1597", 16)
-	ka.g, _ = new(big.Int).SetString("3FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF205407F4793A1A0BA12510DBC15077BE463FFF4FED4AAC0BB555BE3A6C1B0C6B47B1BC3773BF7E8C6F62901228F8C28CBB18A55AE31341000A650196F931C77A57F2DDF463E5E9EC144B777DE62AAAB8A8628AC376D282D6ED3864E67982428EBC831D14348F6F2F9193B5045AF2767164E1DFC967C1FB3F2E55A4BD1BFFE83B9C80D052B985D182EA0ADB2A3B7313D3FE14C8484B1E052588B9B7D2BBD2DF016199ECD06E1557CD0915B3353BBB64E0EC377FD028370DF92B52C7891428CDC67EB6184B523D1DB246C32F63078490F00EF8D647D148D47954515E2327CFEF98C582664B4C0F6CC41659", 16)
-	q, _ := new(big.Int).SetString("8CF83642A709A097B447997640129DA299B1A47D1EB3750BA308B0FE64F5FBD3", 16)
+	var q *big.Int
+	if p := config.Bugs.DHGroupPrime; p != nil {
+		ka.p = p
+		ka.g = big.NewInt(2)
+		q = p
+	} else {
+		// 2048-bit MODP Group with 256-bit Prime Order Subgroup (RFC
+		// 5114, Section 2.3)
+		ka.p, _ = new(big.Int).SetString("87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F25D2CEED4435E3B00E00DF8F1D61957D4FAF7DF4561B2AA3016C3D91134096FAA3BF4296D830E9A7C209E0C6497517ABD5A8A9D306BCF67ED91F9E6725B4758C022E0B1EF4275BF7B6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF12307F5C4FDB70C581B23F76B63ACAE1CAA6B7902D52526735488A0EF13C6D9A51BFA4AB3AD8347796524D8EF6A167B5A41825D967E144E5140564251CCACB83E6B486F6B3CA3F7971506026C0B857F689962856DED4010ABD0BE621C3A3960A54E710C375F26375D7014103A4B54330C198AF126116D2276E11715F693877FAD7EF09CADB094AE91E1A1597", 16)
+		ka.g, _ = new(big.Int).SetString("3FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF205407F4793A1A0BA12510DBC15077BE463FFF4FED4AAC0BB555BE3A6C1B0C6B47B1BC3773BF7E8C6F62901228F8C28CBB18A55AE31341000A650196F931C77A57F2DDF463E5E9EC144B777DE62AAAB8A8628AC376D282D6ED3864E67982428EBC831D14348F6F2F9193B5045AF2767164E1DFC967C1FB3F2E55A4BD1BFFE83B9C80D052B985D182EA0ADB2A3B7313D3FE14C8484B1E052588B9B7D2BBD2DF016199ECD06E1557CD0915B3353BBB64E0EC377FD028370DF92B52C7891428CDC67EB6184B523D1DB246C32F63078490F00EF8D647D148D47954515E2327CFEF98C582664B4C0F6CC41659", 16)
+		q, _ = new(big.Int).SetString("8CF83642A709A097B447997640129DA299B1A47D1EB3750BA308B0FE64F5FBD3", 16)
+	}
 
 	var err error
 	ka.xOurs, err = rand.Int(config.rand(), q)
diff --git a/src/ssl/test/runner/runner.go b/src/ssl/test/runner/runner.go
index ec2fede..bd03cb1 100644
--- a/src/ssl/test/runner/runner.go
+++ b/src/ssl/test/runner/runner.go
@@ -11,6 +11,7 @@
 	"fmt"
 	"io"
 	"io/ioutil"
+	"math/big"
 	"net"
 	"os"
 	"os/exec"
@@ -160,6 +161,10 @@
 	// resumeSession controls whether a second connection should be tested
 	// which attempts to resume the first session.
 	resumeSession bool
+	// expectResumeRejected, if true, specifies that the attempted
+	// resumption must be rejected by the client. This is only valid for a
+	// serverTest.
+	expectResumeRejected bool
 	// resumeConfig, if not nil, points to a Config to be used on
 	// resumption. Unless newSessionsOnResume is set,
 	// SessionTicketKey, ServerSessionCache, and
@@ -196,6 +201,9 @@
 	// flags, if not empty, contains a list of command-line flags that will
 	// be passed to the shim program.
 	flags []string
+	// testTLSUnique, if true, causes the shim to send the tls-unique value
+	// which will be compared against the expected value.
+	testTLSUnique bool
 }
 
 var testCases = []testCase{
@@ -1085,6 +1093,49 @@
 		},
 		expectedCipher: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
 	},
+	{
+		protocol: dtls,
+		name:     "SendSplitAlert-Sync",
+		config: Config{
+			Bugs: ProtocolBugs{
+				SendSplitAlert: true,
+			},
+		},
+	},
+	{
+		protocol: dtls,
+		name:     "SendSplitAlert-Async",
+		config: Config{
+			Bugs: ProtocolBugs{
+				SendSplitAlert: true,
+			},
+		},
+		flags: []string{"-async"},
+	},
+	{
+		protocol: dtls,
+		name:     "PackDTLSHandshake",
+		config: Config{
+			Bugs: ProtocolBugs{
+				MaxHandshakeRecordLength: 2,
+				PackHandshakeFragments:   20,
+				PackHandshakeRecords:     200,
+			},
+		},
+	},
+	{
+		testType: serverTest,
+		protocol: dtls,
+		name:     "NoRC4-DTLS",
+		config: Config{
+			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_RC4_128_SHA},
+			Bugs: ProtocolBugs{
+				EnableAllCiphersInDTLS: true,
+			},
+		},
+		shouldFail:    true,
+		expectedError: ":NO_SHARED_CIPHER:",
+	},
 }
 
 func doExchange(test *testCase, config *Config, conn net.Conn, messageLen int, isResume bool) error {
@@ -1144,16 +1195,20 @@
 	if isResume && test.expectedResumeVersion != 0 {
 		expectedVersion = test.expectedResumeVersion
 	}
-	if vers := tlsConn.ConnectionState().Version; expectedVersion != 0 && vers != expectedVersion {
+	connState := tlsConn.ConnectionState()
+	if vers := connState.Version; expectedVersion != 0 && vers != expectedVersion {
 		return fmt.Errorf("got version %x, expected %x", vers, expectedVersion)
 	}
 
-	if cipher := tlsConn.ConnectionState().CipherSuite; test.expectedCipher != 0 && cipher != test.expectedCipher {
+	if cipher := connState.CipherSuite; test.expectedCipher != 0 && cipher != test.expectedCipher {
 		return fmt.Errorf("got cipher %x, expected %x", cipher, test.expectedCipher)
 	}
+	if didResume := connState.DidResume; isResume && didResume == test.expectResumeRejected {
+		return fmt.Errorf("didResume is %t, but we expected the opposite", didResume)
+	}
 
 	if test.expectChannelID {
-		channelID := tlsConn.ConnectionState().ChannelID
+		channelID := connState.ChannelID
 		if channelID == nil {
 			return fmt.Errorf("no channel ID negotiated")
 		}
@@ -1165,18 +1220,18 @@
 	}
 
 	if expected := test.expectedNextProto; expected != "" {
-		if actual := tlsConn.ConnectionState().NegotiatedProtocol; actual != expected {
+		if actual := connState.NegotiatedProtocol; actual != expected {
 			return fmt.Errorf("next proto mismatch: got %s, wanted %s", actual, expected)
 		}
 	}
 
 	if test.expectedNextProtoType != 0 {
-		if (test.expectedNextProtoType == alpn) != tlsConn.ConnectionState().NegotiatedProtocolFromALPN {
+		if (test.expectedNextProtoType == alpn) != connState.NegotiatedProtocolFromALPN {
 			return fmt.Errorf("next proto type mismatch")
 		}
 	}
 
-	if p := tlsConn.ConnectionState().SRTPProtectionProfile; p != test.expectedSRTPProtectionProfile {
+	if p := connState.SRTPProtectionProfile; p != test.expectedSRTPProtectionProfile {
 		return fmt.Errorf("SRTP profile mismatch: got %d, wanted %d", p, test.expectedSRTPProtectionProfile)
 	}
 
@@ -1194,6 +1249,17 @@
 		}
 	}
 
+	if test.testTLSUnique {
+		var peersValue [12]byte
+		if _, err := io.ReadFull(tlsConn, peersValue[:]); err != nil {
+			return err
+		}
+		expected := tlsConn.ConnectionState().TLSUnique
+		if !bytes.Equal(peersValue[:], expected) {
+			return fmt.Errorf("tls-unique mismatch: peer sent %x, but %x was expected", peersValue[:], expected)
+		}
+	}
+
 	if test.shimWritesFirst {
 		var buf [5]byte
 		_, err := io.ReadFull(tlsConn, buf[:])
@@ -1321,6 +1387,10 @@
 		panic("Error expected without shouldFail in " + test.name)
 	}
 
+	if test.expectResumeRejected && !test.resumeSession {
+		panic("expectResumeRejected without resumeSession in " + test.name)
+	}
+
 	listener, err := net.ListenTCP("tcp4", &net.TCPAddr{IP: net.IP{127, 0, 0, 1}})
 	if err != nil {
 		panic(err)
@@ -1371,6 +1441,13 @@
 			flags = append(flags, "-use-export-context")
 		}
 	}
+	if test.expectResumeRejected {
+		flags = append(flags, "-expect-session-miss")
+	}
+
+	if test.testTLSUnique {
+		flags = append(flags, "-tls-unique")
+	}
 
 	flags = append(flags, test.flags...)
 
@@ -1569,6 +1646,14 @@
 	return !hasComponent(suiteName, "RC4")
 }
 
+func bigFromHex(hex string) *big.Int {
+	ret, ok := new(big.Int).SetString(hex, 16)
+	if !ok {
+		panic("failed to parse hex number 0x" + hex)
+	}
+	return ret
+}
+
 func addCipherSuiteTests() {
 	for _, suite := range testCipherSuites {
 		const psk = "12345"
@@ -1667,6 +1752,21 @@
 			}
 		}
 	}
+
+	testCases = append(testCases, testCase{
+		name: "WeakDH",
+		config: Config{
+			CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
+			Bugs: ProtocolBugs{
+				// This is a 1023-bit prime number, generated
+				// with:
+				// openssl gendh 1023 | openssl asn1parse -i
+				DHGroupPrime: bigFromHex("518E9B7930CE61C6E445C8360584E5FC78D9137C0FFDC880B495D5338ADF7689951A6821C17A76B3ACB8E0156AEA607B7EC406EBEDBB84D8376EB8FE8F8BA1433488BEE0C3EDDFD3A32DBB9481980A7AF6C96BFCF490A094CFFB2B8192C1BB5510B77B658436E27C2D4D023FE3718222AB0CA1273995B51F6D625A4944D0DD4B"),
+			},
+		},
+		shouldFail:    true,
+		expectedError: "BAD_DH_P_LENGTH",
+	})
 }
 
 func addBadECDSASignatureTests() {
@@ -1866,24 +1966,361 @@
 		}
 	}
 
-	// When a session is resumed, it should still be aware that its master
-	// secret was generated via EMS and thus it's safe to use tls-unique.
-	testCases = append(testCases, testCase{
-		name: "ExtendedMasterSecret-Resume",
-		config: Config{
-			Bugs: ProtocolBugs{
-				RequireExtendedMasterSecret: true,
-			},
-		},
-		flags:         []string{expectEMSFlag},
-		resumeSession: true,
-	})
+	for _, isClient := range []bool{false, true} {
+		for _, supportedInFirstConnection := range []bool{false, true} {
+			for _, supportedInResumeConnection := range []bool{false, true} {
+				boolToWord := func(b bool) string {
+					if b {
+						return "Yes"
+					}
+					return "No"
+				}
+				suffix := boolToWord(supportedInFirstConnection) + "To" + boolToWord(supportedInResumeConnection) + "-"
+				if isClient {
+					suffix += "Client"
+				} else {
+					suffix += "Server"
+				}
+
+				supportedConfig := Config{
+					Bugs: ProtocolBugs{
+						RequireExtendedMasterSecret: true,
+					},
+				}
+
+				noSupportConfig := Config{
+					Bugs: ProtocolBugs{
+						NoExtendedMasterSecret: true,
+					},
+				}
+
+				test := testCase{
+					name:          "ExtendedMasterSecret-" + suffix,
+					resumeSession: true,
+				}
+
+				if !isClient {
+					test.testType = serverTest
+				}
+
+				if supportedInFirstConnection {
+					test.config = supportedConfig
+				} else {
+					test.config = noSupportConfig
+				}
+
+				if supportedInResumeConnection {
+					test.resumeConfig = &supportedConfig
+				} else {
+					test.resumeConfig = &noSupportConfig
+				}
+
+				switch suffix {
+				case "YesToYes-Client", "YesToYes-Server":
+					// When a session is resumed, it should
+					// still be aware that its master
+					// secret was generated via EMS and
+					// thus it's safe to use tls-unique.
+					test.flags = []string{expectEMSFlag}
+				case "NoToYes-Server":
+					// If an original connection did not
+					// contain EMS, but a resumption
+					// handshake does, then a server should
+					// not resume the session.
+					test.expectResumeRejected = true
+				case "YesToNo-Server":
+					// Resuming an EMS session without the
+					// EMS extension should cause the
+					// server to abort the connection.
+					test.shouldFail = true
+					test.expectedError = ":RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION:"
+				case "NoToYes-Client":
+					// A client should abort a connection
+					// where the server resumed a non-EMS
+					// session but echoed the EMS
+					// extension.
+					test.shouldFail = true
+					test.expectedError = ":RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION:"
+				case "YesToNo-Client":
+					// A client should abort a connection
+					// where the server didn't echo EMS
+					// when the session used it.
+					test.shouldFail = true
+					test.expectedError = ":RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION:"
+				}
+
+				testCases = append(testCases, test)
+			}
+		}
+	}
 }
 
 // Adds tests that try to cover the range of the handshake state machine, under
 // various conditions. Some of these are redundant with other tests, but they
 // only cover the synchronous case.
 func addStateMachineCoverageTests(async, splitHandshake bool, protocol protocol) {
+	var tests []testCase
+
+	// Basic handshake, with resumption. Client and server,
+	// session ID and session ticket.
+	tests = append(tests, testCase{
+		name:          "Basic-Client",
+		resumeSession: true,
+	})
+	tests = append(tests, testCase{
+		name: "Basic-Client-RenewTicket",
+		config: Config{
+			Bugs: ProtocolBugs{
+				RenewTicketOnResume: true,
+			},
+		},
+		resumeSession: true,
+	})
+	tests = append(tests, testCase{
+		name: "Basic-Client-NoTicket",
+		config: Config{
+			SessionTicketsDisabled: true,
+		},
+		resumeSession: true,
+	})
+	tests = append(tests, testCase{
+		name:          "Basic-Client-Implicit",
+		flags:         []string{"-implicit-handshake"},
+		resumeSession: true,
+	})
+	tests = append(tests, testCase{
+		testType:      serverTest,
+		name:          "Basic-Server",
+		resumeSession: true,
+	})
+	tests = append(tests, testCase{
+		testType: serverTest,
+		name:     "Basic-Server-NoTickets",
+		config: Config{
+			SessionTicketsDisabled: true,
+		},
+		resumeSession: true,
+	})
+	tests = append(tests, testCase{
+		testType:      serverTest,
+		name:          "Basic-Server-Implicit",
+		flags:         []string{"-implicit-handshake"},
+		resumeSession: true,
+	})
+	tests = append(tests, testCase{
+		testType:      serverTest,
+		name:          "Basic-Server-EarlyCallback",
+		flags:         []string{"-use-early-callback"},
+		resumeSession: true,
+	})
+
+	// TLS client auth.
+	tests = append(tests, testCase{
+		testType: clientTest,
+		name:     "ClientAuth-Client",
+		config: Config{
+			ClientAuth: RequireAnyClientCert,
+		},
+		flags: []string{
+			"-cert-file", rsaCertificateFile,
+			"-key-file", rsaKeyFile,
+		},
+	})
+	tests = append(tests, testCase{
+		testType: serverTest,
+		name:     "ClientAuth-Server",
+		config: Config{
+			Certificates: []Certificate{rsaCertificate},
+		},
+		flags: []string{"-require-any-client-certificate"},
+	})
+
+	// No session ticket support; server doesn't send NewSessionTicket.
+	tests = append(tests, testCase{
+		name: "SessionTicketsDisabled-Client",
+		config: Config{
+			SessionTicketsDisabled: true,
+		},
+	})
+	tests = append(tests, testCase{
+		testType: serverTest,
+		name:     "SessionTicketsDisabled-Server",
+		config: Config{
+			SessionTicketsDisabled: true,
+		},
+	})
+
+	// Skip ServerKeyExchange in PSK key exchange if there's no
+	// identity hint.
+	tests = append(tests, testCase{
+		name: "EmptyPSKHint-Client",
+		config: Config{
+			CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA},
+			PreSharedKey: []byte("secret"),
+		},
+		flags: []string{"-psk", "secret"},
+	})
+	tests = append(tests, testCase{
+		testType: serverTest,
+		name:     "EmptyPSKHint-Server",
+		config: Config{
+			CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA},
+			PreSharedKey: []byte("secret"),
+		},
+		flags: []string{"-psk", "secret"},
+	})
+
+	if protocol == tls {
+		tests = append(tests, testCase{
+			name:        "Renegotiate-Client",
+			renegotiate: true,
+		})
+		// NPN on client and server; results in post-handshake message.
+		tests = append(tests, testCase{
+			name: "NPN-Client",
+			config: Config{
+				NextProtos: []string{"foo"},
+			},
+			flags:                 []string{"-select-next-proto", "foo"},
+			expectedNextProto:     "foo",
+			expectedNextProtoType: npn,
+		})
+		tests = append(tests, testCase{
+			testType: serverTest,
+			name:     "NPN-Server",
+			config: Config{
+				NextProtos: []string{"bar"},
+			},
+			flags: []string{
+				"-advertise-npn", "\x03foo\x03bar\x03baz",
+				"-expect-next-proto", "bar",
+			},
+			expectedNextProto:     "bar",
+			expectedNextProtoType: npn,
+		})
+
+		// TODO(davidben): Add tests for when False Start doesn't trigger.
+
+		// Client does False Start and negotiates NPN.
+		tests = append(tests, testCase{
+			name: "FalseStart",
+			config: Config{
+				CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+				NextProtos:   []string{"foo"},
+				Bugs: ProtocolBugs{
+					ExpectFalseStart: true,
+				},
+			},
+			flags: []string{
+				"-false-start",
+				"-select-next-proto", "foo",
+			},
+			shimWritesFirst: true,
+			resumeSession:   true,
+		})
+
+		// Client does False Start and negotiates ALPN.
+		tests = append(tests, testCase{
+			name: "FalseStart-ALPN",
+			config: Config{
+				CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+				NextProtos:   []string{"foo"},
+				Bugs: ProtocolBugs{
+					ExpectFalseStart: true,
+				},
+			},
+			flags: []string{
+				"-false-start",
+				"-advertise-alpn", "\x03foo",
+			},
+			shimWritesFirst: true,
+			resumeSession:   true,
+		})
+
+		// Client does False Start but doesn't explicitly call
+		// SSL_connect.
+		tests = append(tests, testCase{
+			name: "FalseStart-Implicit",
+			config: Config{
+				CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+				NextProtos:   []string{"foo"},
+			},
+			flags: []string{
+				"-implicit-handshake",
+				"-false-start",
+				"-advertise-alpn", "\x03foo",
+			},
+		})
+
+		// False Start without session tickets.
+		tests = append(tests, testCase{
+			name: "FalseStart-SessionTicketsDisabled",
+			config: Config{
+				CipherSuites:           []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+				NextProtos:             []string{"foo"},
+				SessionTicketsDisabled: true,
+				Bugs: ProtocolBugs{
+					ExpectFalseStart: true,
+				},
+			},
+			flags: []string{
+				"-false-start",
+				"-select-next-proto", "foo",
+			},
+			shimWritesFirst: true,
+		})
+
+		// Server parses a V2ClientHello.
+		tests = append(tests, testCase{
+			testType: serverTest,
+			name:     "SendV2ClientHello",
+			config: Config{
+				// Choose a cipher suite that does not involve
+				// elliptic curves, so no extensions are
+				// involved.
+				CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+				Bugs: ProtocolBugs{
+					SendV2ClientHello: true,
+				},
+			},
+		})
+
+		// Client sends a Channel ID.
+		tests = append(tests, testCase{
+			name: "ChannelID-Client",
+			config: Config{
+				RequestChannelID: true,
+			},
+			flags:           []string{"-send-channel-id", channelIDKeyFile},
+			resumeSession:   true,
+			expectChannelID: true,
+		})
+
+		// Server accepts a Channel ID.
+		tests = append(tests, testCase{
+			testType: serverTest,
+			name:     "ChannelID-Server",
+			config: Config{
+				ChannelID: channelIDKey,
+			},
+			flags: []string{
+				"-expect-channel-id",
+				base64.StdEncoding.EncodeToString(channelIDBytes),
+			},
+			resumeSession:   true,
+			expectChannelID: true,
+		})
+	} else {
+		tests = append(tests, testCase{
+			name: "SkipHelloVerifyRequest",
+			config: Config{
+				Bugs: ProtocolBugs{
+					SkipHelloVerifyRequest: true,
+				},
+			},
+		})
+	}
+
 	var suffix string
 	var flags []string
 	var maxHandshakeRecordLength int
@@ -1900,357 +2337,12 @@
 		suffix += "-SplitHandshakeRecords"
 		maxHandshakeRecordLength = 1
 	}
-
-	// Basic handshake, with resumption. Client and server,
-	// session ID and session ticket.
-	testCases = append(testCases, testCase{
-		protocol: protocol,
-		name:     "Basic-Client" + suffix,
-		config: Config{
-			Bugs: ProtocolBugs{
-				MaxHandshakeRecordLength: maxHandshakeRecordLength,
-			},
-		},
-		flags:         flags,
-		resumeSession: true,
-	})
-	testCases = append(testCases, testCase{
-		protocol: protocol,
-		name:     "Basic-Client-RenewTicket" + suffix,
-		config: Config{
-			Bugs: ProtocolBugs{
-				MaxHandshakeRecordLength: maxHandshakeRecordLength,
-				RenewTicketOnResume:      true,
-			},
-		},
-		flags:         flags,
-		resumeSession: true,
-	})
-	testCases = append(testCases, testCase{
-		protocol: protocol,
-		name:     "Basic-Client-NoTicket" + suffix,
-		config: Config{
-			SessionTicketsDisabled: true,
-			Bugs: ProtocolBugs{
-				MaxHandshakeRecordLength: maxHandshakeRecordLength,
-			},
-		},
-		flags:         flags,
-		resumeSession: true,
-	})
-	testCases = append(testCases, testCase{
-		protocol: protocol,
-		name:     "Basic-Client-Implicit" + suffix,
-		config: Config{
-			Bugs: ProtocolBugs{
-				MaxHandshakeRecordLength: maxHandshakeRecordLength,
-			},
-		},
-		flags:         append(flags, "-implicit-handshake"),
-		resumeSession: true,
-	})
-	testCases = append(testCases, testCase{
-		protocol: protocol,
-		testType: serverTest,
-		name:     "Basic-Server" + suffix,
-		config: Config{
-			Bugs: ProtocolBugs{
-				MaxHandshakeRecordLength: maxHandshakeRecordLength,
-			},
-		},
-		flags:         flags,
-		resumeSession: true,
-	})
-	testCases = append(testCases, testCase{
-		protocol: protocol,
-		testType: serverTest,
-		name:     "Basic-Server-NoTickets" + suffix,
-		config: Config{
-			SessionTicketsDisabled: true,
-			Bugs: ProtocolBugs{
-				MaxHandshakeRecordLength: maxHandshakeRecordLength,
-			},
-		},
-		flags:         flags,
-		resumeSession: true,
-	})
-	testCases = append(testCases, testCase{
-		protocol: protocol,
-		testType: serverTest,
-		name:     "Basic-Server-Implicit" + suffix,
-		config: Config{
-			Bugs: ProtocolBugs{
-				MaxHandshakeRecordLength: maxHandshakeRecordLength,
-			},
-		},
-		flags:         append(flags, "-implicit-handshake"),
-		resumeSession: true,
-	})
-	testCases = append(testCases, testCase{
-		protocol: protocol,
-		testType: serverTest,
-		name:     "Basic-Server-EarlyCallback" + suffix,
-		config: Config{
-			Bugs: ProtocolBugs{
-				MaxHandshakeRecordLength: maxHandshakeRecordLength,
-			},
-		},
-		flags:         append(flags, "-use-early-callback"),
-		resumeSession: true,
-	})
-
-	// TLS client auth.
-	testCases = append(testCases, testCase{
-		protocol: protocol,
-		testType: clientTest,
-		name:     "ClientAuth-Client" + suffix,
-		config: Config{
-			ClientAuth: RequireAnyClientCert,
-			Bugs: ProtocolBugs{
-				MaxHandshakeRecordLength: maxHandshakeRecordLength,
-			},
-		},
-		flags: append(flags,
-			"-cert-file", rsaCertificateFile,
-			"-key-file", rsaKeyFile),
-	})
-	testCases = append(testCases, testCase{
-		protocol: protocol,
-		testType: serverTest,
-		name:     "ClientAuth-Server" + suffix,
-		config: Config{
-			Certificates: []Certificate{rsaCertificate},
-		},
-		flags: append(flags, "-require-any-client-certificate"),
-	})
-
-	// No session ticket support; server doesn't send NewSessionTicket.
-	testCases = append(testCases, testCase{
-		protocol: protocol,
-		name:     "SessionTicketsDisabled-Client" + suffix,
-		config: Config{
-			SessionTicketsDisabled: true,
-			Bugs: ProtocolBugs{
-				MaxHandshakeRecordLength: maxHandshakeRecordLength,
-			},
-		},
-		flags: flags,
-	})
-	testCases = append(testCases, testCase{
-		protocol: protocol,
-		testType: serverTest,
-		name:     "SessionTicketsDisabled-Server" + suffix,
-		config: Config{
-			SessionTicketsDisabled: true,
-			Bugs: ProtocolBugs{
-				MaxHandshakeRecordLength: maxHandshakeRecordLength,
-			},
-		},
-		flags: flags,
-	})
-
-	// Skip ServerKeyExchange in PSK key exchange if there's no
-	// identity hint.
-	testCases = append(testCases, testCase{
-		protocol: protocol,
-		name:     "EmptyPSKHint-Client" + suffix,
-		config: Config{
-			CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA},
-			PreSharedKey: []byte("secret"),
-			Bugs: ProtocolBugs{
-				MaxHandshakeRecordLength: maxHandshakeRecordLength,
-			},
-		},
-		flags: append(flags, "-psk", "secret"),
-	})
-	testCases = append(testCases, testCase{
-		protocol: protocol,
-		testType: serverTest,
-		name:     "EmptyPSKHint-Server" + suffix,
-		config: Config{
-			CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA},
-			PreSharedKey: []byte("secret"),
-			Bugs: ProtocolBugs{
-				MaxHandshakeRecordLength: maxHandshakeRecordLength,
-			},
-		},
-		flags: append(flags, "-psk", "secret"),
-	})
-
-	if protocol == tls {
-		// NPN on client and server; results in post-handshake message.
-		testCases = append(testCases, testCase{
-			protocol: protocol,
-			name:     "NPN-Client" + suffix,
-			config: Config{
-				NextProtos: []string{"foo"},
-				Bugs: ProtocolBugs{
-					MaxHandshakeRecordLength: maxHandshakeRecordLength,
-				},
-			},
-			flags:                 append(flags, "-select-next-proto", "foo"),
-			expectedNextProto:     "foo",
-			expectedNextProtoType: npn,
-		})
-		testCases = append(testCases, testCase{
-			protocol: protocol,
-			testType: serverTest,
-			name:     "NPN-Server" + suffix,
-			config: Config{
-				NextProtos: []string{"bar"},
-				Bugs: ProtocolBugs{
-					MaxHandshakeRecordLength: maxHandshakeRecordLength,
-				},
-			},
-			flags: append(flags,
-				"-advertise-npn", "\x03foo\x03bar\x03baz",
-				"-expect-next-proto", "bar"),
-			expectedNextProto:     "bar",
-			expectedNextProtoType: npn,
-		})
-
-		// TODO(davidben): Add tests for when False Start doesn't trigger.
-
-		// Client does False Start and negotiates NPN.
-		testCases = append(testCases, testCase{
-			protocol: protocol,
-			name:     "FalseStart" + suffix,
-			config: Config{
-				CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
-				NextProtos:   []string{"foo"},
-				Bugs: ProtocolBugs{
-					ExpectFalseStart:         true,
-					MaxHandshakeRecordLength: maxHandshakeRecordLength,
-				},
-			},
-			flags: append(flags,
-				"-false-start",
-				"-select-next-proto", "foo"),
-			shimWritesFirst: true,
-			resumeSession:   true,
-		})
-
-		// Client does False Start and negotiates ALPN.
-		testCases = append(testCases, testCase{
-			protocol: protocol,
-			name:     "FalseStart-ALPN" + suffix,
-			config: Config{
-				CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
-				NextProtos:   []string{"foo"},
-				Bugs: ProtocolBugs{
-					ExpectFalseStart:         true,
-					MaxHandshakeRecordLength: maxHandshakeRecordLength,
-				},
-			},
-			flags: append(flags,
-				"-false-start",
-				"-advertise-alpn", "\x03foo"),
-			shimWritesFirst: true,
-			resumeSession:   true,
-		})
-
-		// Client does False Start but doesn't explicitly call
-		// SSL_connect.
-		testCases = append(testCases, testCase{
-			protocol: protocol,
-			name:     "FalseStart-Implicit" + suffix,
-			config: Config{
-				CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
-				NextProtos:   []string{"foo"},
-				Bugs: ProtocolBugs{
-					MaxHandshakeRecordLength: maxHandshakeRecordLength,
-				},
-			},
-			flags: append(flags,
-				"-implicit-handshake",
-				"-false-start",
-				"-advertise-alpn", "\x03foo"),
-		})
-
-		// False Start without session tickets.
-		testCases = append(testCases, testCase{
-			name: "FalseStart-SessionTicketsDisabled" + suffix,
-			config: Config{
-				CipherSuites:           []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
-				NextProtos:             []string{"foo"},
-				SessionTicketsDisabled: true,
-				Bugs: ProtocolBugs{
-					ExpectFalseStart:         true,
-					MaxHandshakeRecordLength: maxHandshakeRecordLength,
-				},
-			},
-			flags: append(flags,
-				"-false-start",
-				"-select-next-proto", "foo",
-			),
-			shimWritesFirst: true,
-		})
-
-		// Server parses a V2ClientHello.
-		testCases = append(testCases, testCase{
-			protocol: protocol,
-			testType: serverTest,
-			name:     "SendV2ClientHello" + suffix,
-			config: Config{
-				// Choose a cipher suite that does not involve
-				// elliptic curves, so no extensions are
-				// involved.
-				CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
-				Bugs: ProtocolBugs{
-					MaxHandshakeRecordLength: maxHandshakeRecordLength,
-					SendV2ClientHello:        true,
-				},
-			},
-			flags: flags,
-		})
-
-		// Client sends a Channel ID.
-		testCases = append(testCases, testCase{
-			protocol: protocol,
-			name:     "ChannelID-Client" + suffix,
-			config: Config{
-				RequestChannelID: true,
-				Bugs: ProtocolBugs{
-					MaxHandshakeRecordLength: maxHandshakeRecordLength,
-				},
-			},
-			flags: append(flags,
-				"-send-channel-id", channelIDKeyFile,
-			),
-			resumeSession:   true,
-			expectChannelID: true,
-		})
-
-		// Server accepts a Channel ID.
-		testCases = append(testCases, testCase{
-			protocol: protocol,
-			testType: serverTest,
-			name:     "ChannelID-Server" + suffix,
-			config: Config{
-				ChannelID: channelIDKey,
-				Bugs: ProtocolBugs{
-					MaxHandshakeRecordLength: maxHandshakeRecordLength,
-				},
-			},
-			flags: append(flags,
-				"-expect-channel-id",
-				base64.StdEncoding.EncodeToString(channelIDBytes),
-			),
-			resumeSession:   true,
-			expectChannelID: true,
-		})
-	} else {
-		testCases = append(testCases, testCase{
-			protocol: protocol,
-			name:     "SkipHelloVerifyRequest" + suffix,
-			config: Config{
-				Bugs: ProtocolBugs{
-					MaxHandshakeRecordLength: maxHandshakeRecordLength,
-					SkipHelloVerifyRequest:   true,
-				},
-			},
-			flags: flags,
-		})
+	for _, test := range tests {
+		test.protocol = protocol
+		test.name += suffix
+		test.config.Bugs.MaxHandshakeRecordLength = maxHandshakeRecordLength
+		test.flags = append(test.flags, flags...)
+		testCases = append(testCases, test)
 	}
 }
 
@@ -2637,8 +2729,8 @@
 				CorruptTicket: true,
 			},
 		},
-		resumeSession: true,
-		flags:         []string{"-expect-session-miss"},
+		resumeSession:        true,
+		expectResumeRejected: true,
 	})
 	// Resume with an oversized session id.
 	testCases = append(testCases, testCase{
@@ -2799,7 +2891,6 @@
 				testCases = append(testCases, testCase{
 					protocol:      protocol,
 					name:          "Resume-Client-NoResume" + suffix,
-					flags:         []string{"-expect-session-miss"},
 					resumeSession: true,
 					config: Config{
 						MaxVersion:   sessionVers.version,
@@ -2811,24 +2902,21 @@
 						CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
 					},
 					newSessionsOnResume:   true,
+					expectResumeRejected:  true,
 					expectedResumeVersion: resumeVers.version,
 				})
 
-				var flags []string
-				if sessionVers.version != resumeVers.version {
-					flags = append(flags, "-expect-session-miss")
-				}
 				testCases = append(testCases, testCase{
 					protocol:      protocol,
 					testType:      serverTest,
 					name:          "Resume-Server" + suffix,
-					flags:         flags,
 					resumeSession: true,
 					config: Config{
 						MaxVersion:   sessionVers.version,
 						CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
 					},
-					expectedVersion: sessionVers.version,
+					expectedVersion:      sessionVers.version,
+					expectResumeRejected: sessionVers.version != resumeVers.version,
 					resumeConfig: &Config{
 						MaxVersion:   resumeVers.version,
 						CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
@@ -2857,109 +2945,22 @@
 }
 
 func addRenegotiationTests() {
-	testCases = append(testCases, testCase{
-		testType:        serverTest,
-		name:            "Renegotiate-Server",
-		flags:           []string{"-renegotiate"},
-		shimWritesFirst: true,
-	})
-	testCases = append(testCases, testCase{
-		testType: serverTest,
-		name:     "Renegotiate-Server-Full",
-		config: Config{
-			Bugs: ProtocolBugs{
-				NeverResumeOnRenego: true,
-			},
-		},
-		flags:           []string{"-renegotiate"},
-		shimWritesFirst: true,
-	})
-	testCases = append(testCases, testCase{
-		testType: serverTest,
-		name:     "Renegotiate-Server-EmptyExt",
-		config: Config{
-			Bugs: ProtocolBugs{
-				EmptyRenegotiationInfo: true,
-			},
-		},
-		flags:           []string{"-renegotiate"},
-		shimWritesFirst: true,
-		shouldFail:      true,
-		expectedError:   ":RENEGOTIATION_MISMATCH:",
-	})
-	testCases = append(testCases, testCase{
-		testType: serverTest,
-		name:     "Renegotiate-Server-BadExt",
-		config: Config{
-			Bugs: ProtocolBugs{
-				BadRenegotiationInfo: true,
-			},
-		},
-		flags:           []string{"-renegotiate"},
-		shimWritesFirst: true,
-		shouldFail:      true,
-		expectedError:   ":RENEGOTIATION_MISMATCH:",
-	})
-	testCases = append(testCases, testCase{
-		testType:    serverTest,
-		name:        "Renegotiate-Server-ClientInitiated",
-		renegotiate: true,
-	})
-	testCases = append(testCases, testCase{
-		testType:    serverTest,
-		name:        "Renegotiate-Server-ClientInitiated-NoExt",
-		renegotiate: true,
-		config: Config{
-			Bugs: ProtocolBugs{
-				NoRenegotiationInfo: true,
-			},
-		},
-		shouldFail:    true,
-		expectedError: ":UNSAFE_LEGACY_RENEGOTIATION_DISABLED:",
-	})
-	testCases = append(testCases, testCase{
-		testType:    serverTest,
-		name:        "Renegotiate-Server-ClientInitiated-NoExt-Allowed",
-		renegotiate: true,
-		config: Config{
-			Bugs: ProtocolBugs{
-				NoRenegotiationInfo: true,
-			},
-		},
-		flags: []string{"-allow-unsafe-legacy-renegotiation"},
-	})
+	// Servers cannot renegotiate.
 	testCases = append(testCases, testCase{
 		testType:           serverTest,
-		name:               "Renegotiate-Server-ClientInitiated-Forbidden",
+		name:               "Renegotiate-Server-Forbidden",
 		renegotiate:        true,
 		flags:              []string{"-reject-peer-renegotiations"},
 		shouldFail:         true,
 		expectedError:      ":NO_RENEGOTIATION:",
 		expectedLocalError: "remote error: no renegotiation",
 	})
-	// Regression test for CVE-2015-0291.
-	testCases = append(testCases, testCase{
-		testType: serverTest,
-		name:     "Renegotiate-Server-NoSignatureAlgorithms",
-		config: Config{
-			Bugs: ProtocolBugs{
-				NeverResumeOnRenego:           true,
-				NoSignatureAlgorithmsOnRenego: true,
-			},
-		},
-		flags:           []string{"-renegotiate"},
-		shimWritesFirst: true,
-	})
 	// TODO(agl): test the renegotiation info SCSV.
 	testCases = append(testCases, testCase{
-		name:        "Renegotiate-Client",
-		renegotiate: true,
-	})
-	testCases = append(testCases, testCase{
-		name: "Renegotiate-Client-Full",
+		name: "Renegotiate-Client",
 		config: Config{
 			Bugs: ProtocolBugs{
-				NeverResumeOnRenego: true,
+				FailIfResumeOnRenego: true,
 			},
 		},
 		renegotiate: true,
@@ -2987,6 +2988,27 @@
 		expectedError: ":RENEGOTIATION_MISMATCH:",
 	})
 	testCases = append(testCases, testCase{
+		name:        "Renegotiate-Client-NoExt",
+		renegotiate: true,
+		config: Config{
+			Bugs: ProtocolBugs{
+				NoRenegotiationInfo: true,
+			},
+		},
+		shouldFail:    true,
+		expectedError: ":UNSAFE_LEGACY_RENEGOTIATION_DISABLED:",
+		flags:         []string{"-no-legacy-server-connect"},
+	})
+	testCases = append(testCases, testCase{
+		name:        "Renegotiate-Client-NoExt-Allowed",
+		renegotiate: true,
+		config: Config{
+			Bugs: ProtocolBugs{
+				NoRenegotiationInfo: true,
+			},
+		},
+	})
+	testCases = append(testCases, testCase{
 		name:        "Renegotiate-Client-SwitchCiphers",
 		renegotiate: true,
 		config: Config{
@@ -3365,6 +3387,59 @@
 	})
 }
 
+func addTLSUniqueTests() {
+	for _, isClient := range []bool{false, true} {
+		for _, isResumption := range []bool{false, true} {
+			for _, hasEMS := range []bool{false, true} {
+				var suffix string
+				if isResumption {
+					suffix = "Resume-"
+				} else {
+					suffix = "Full-"
+				}
+
+				if hasEMS {
+					suffix += "EMS-"
+				} else {
+					suffix += "NoEMS-"
+				}
+
+				if isClient {
+					suffix += "Client"
+				} else {
+					suffix += "Server"
+				}
+
+				test := testCase{
+					name:          "TLSUnique-" + suffix,
+					testTLSUnique: true,
+					config: Config{
+						Bugs: ProtocolBugs{
+							NoExtendedMasterSecret: !hasEMS,
+						},
+					},
+				}
+
+				if isResumption {
+					test.resumeSession = true
+					test.resumeConfig = &Config{
+						Bugs: ProtocolBugs{
+							NoExtendedMasterSecret: !hasEMS,
+						},
+					}
+				}
+
+				if isResumption && !hasEMS {
+					test.shouldFail = true
+					test.expectedError = "failed to get tls-unique"
+				}
+
+				testCases = append(testCases, test)
+			}
+		}
+	}
+}
+
 func worker(statusChan chan statusMsg, c chan *testCase, buildDir string, wg *sync.WaitGroup) {
 	defer wg.Done()
 
@@ -3463,6 +3538,7 @@
 	addFastRadioPaddingTests()
 	addDTLSRetransmitTests()
 	addExportKeyingMaterialTests()
+	addTLSUniqueTests()
 	for _, async := range []bool{false, true} {
 		for _, splitHandshake := range []bool{false, true} {
 			for _, protocol := range []protocol{tls, dtls} {
diff --git a/src/ssl/test/test_config.cc b/src/ssl/test/test_config.cc
index 25906f7..363b6f3 100644
--- a/src/ssl/test/test_config.cc
+++ b/src/ssl/test/test_config.cc
@@ -65,7 +65,6 @@
   { "-expect-session-miss", &TestConfig::expect_session_miss },
   { "-expect-extended-master-secret",
     &TestConfig::expect_extended_master_secret },
-  { "-renegotiate", &TestConfig::renegotiate },
   { "-allow-unsafe-legacy-renegotiation",
     &TestConfig::allow_unsafe_legacy_renegotiation },
   { "-enable-ocsp-stapling", &TestConfig::enable_ocsp_stapling },
@@ -81,6 +80,8 @@
   { "-handshake-never-done", &TestConfig::handshake_never_done },
   { "-use-export-context", &TestConfig::use_export_context },
   { "-reject-peer-renegotiations", &TestConfig::reject_peer_renegotiations },
+  { "-no-legacy-server-connect", &TestConfig::no_legacy_server_connect },
+  { "-tls-unique", &TestConfig::tls_unique },
 };
 
 const Flag<std::string> kStringFlags[] = {
diff --git a/src/ssl/test/test_config.h b/src/ssl/test/test_config.h
index f107a0f..5d753c8 100644
--- a/src/ssl/test/test_config.h
+++ b/src/ssl/test/test_config.h
@@ -54,7 +54,6 @@
   bool expect_extended_master_secret = false;
   std::string psk;
   std::string psk_identity;
-  bool renegotiate = false;
   bool allow_unsafe_legacy_renegotiation = false;
   std::string srtp_profiles;
   bool enable_ocsp_stapling = false;
@@ -78,6 +77,8 @@
   std::string export_context;
   bool use_export_context = false;
   bool reject_peer_renegotiations = false;
+  bool no_legacy_server_connect = false;
+  bool tls_unique = false;
 };
 
 bool ParseConfig(int argc, char **argv, TestConfig *out_config);
diff --git a/src/tool/CMakeLists.txt b/src/tool/CMakeLists.txt
index 4bb6ca2..74c1ac8 100644
--- a/src/tool/CMakeLists.txt
+++ b/src/tool/CMakeLists.txt
@@ -15,4 +15,8 @@
   transport_common.cc
 )
 
-target_link_libraries(bssl ssl crypto)
+if (APPLE OR WIN32 OR ANDROID)
+  target_link_libraries(bssl ssl crypto)
+else()
+  target_link_libraries(bssl ssl crypto -lrt)
+endif()
diff --git a/src/util/all_tests.go b/src/util/all_tests.go
index 91822d1..49954df 100644
--- a/src/util/all_tests.go
+++ b/src/util/all_tests.go
@@ -22,16 +22,21 @@
 	"os"
 	"os/exec"
 	"path"
+	"strconv"
 	"strings"
+	"syscall"
 	"time"
 )
 
 // TODO(davidben): Link tests with the malloc shim and port -malloc-test to this runner.
 
 var (
-	useValgrind = flag.Bool("valgrind", false, "If true, run code under valgrind")
-	buildDir    = flag.String("build-dir", "build", "The build directory to run the tests from.")
-	jsonOutput  = flag.String("json-output", "", "The file to output JSON results to.")
+	useValgrind     = flag.Bool("valgrind", false, "If true, run code under valgrind")
+	useGDB          = flag.Bool("gdb", false, "If true, run BoringSSL code under gdb")
+	buildDir        = flag.String("build-dir", "build", "The build directory to run the tests from.")
+	jsonOutput      = flag.String("json-output", "", "The file to output JSON results to.")
+	mallocTest      = flag.Int64("malloc-test", -1, "If non-negative, run each test with each malloc in turn failing from the given number onwards.")
+	mallocTestDebug = flag.Bool("malloc-test-debug", false, "If true, ask each test to abort rather than fail a malloc. This can be used with a specific value for --malloc-test to identity the malloc failing that is causing problems.")
 )
 
 type test []string
@@ -83,6 +88,7 @@
 	{"crypto/lhash/lhash_test"},
 	{"crypto/modes/gcm_test"},
 	{"crypto/pkcs8/pkcs12_test"},
+	{"crypto/refcount_test"},
 	{"crypto/rsa/rsa_test"},
 	{"crypto/thread_test"},
 	{"crypto/x509/pkcs7_test"},
@@ -156,25 +162,59 @@
 	return exec.Command("valgrind", valgrindArgs...)
 }
 
-func runTest(test test) (passed bool, err error) {
+func gdbOf(path string, args ...string) *exec.Cmd {
+	xtermArgs := []string{"-e", "gdb", "--args"}
+	xtermArgs = append(xtermArgs, path)
+	xtermArgs = append(xtermArgs, args...)
+
+	return exec.Command("xterm", xtermArgs...)
+}
+
+type moreMallocsError struct{}
+
+func (moreMallocsError) Error() string {
+	return "child process did not exhaust all allocation calls"
+}
+
+var errMoreMallocs = moreMallocsError{}
+
+func runTestOnce(test test, mallocNumToFail int64) (passed bool, err error) {
 	prog := path.Join(*buildDir, test[0])
 	args := test[1:]
 	var cmd *exec.Cmd
 	if *useValgrind {
 		cmd = valgrindOf(false, prog, args...)
+	} else if *useGDB {
+		cmd = gdbOf(prog, args...)
 	} else {
 		cmd = exec.Command(prog, args...)
 	}
 	var stdoutBuf bytes.Buffer
+	var stderrBuf bytes.Buffer
 	cmd.Stdout = &stdoutBuf
-	cmd.Stderr = os.Stderr
+	cmd.Stderr = &stderrBuf
+	if mallocNumToFail >= 0 {
+		cmd.Env = os.Environ()
+		cmd.Env = append(cmd.Env, "MALLOC_NUMBER_TO_FAIL="+strconv.FormatInt(mallocNumToFail, 10))
+		if *mallocTestDebug {
+			cmd.Env = append(cmd.Env, "MALLOC_ABORT_ON_FAIL=1")
+		}
+		cmd.Env = append(cmd.Env, "_MALLOC_CHECK=1")
+	}
 
 	if err := cmd.Start(); err != nil {
 		return false, err
 	}
 	if err := cmd.Wait(); err != nil {
+		if exitError, ok := err.(*exec.ExitError); ok {
+			if exitError.Sys().(syscall.WaitStatus).ExitStatus() == 88 {
+				return false, errMoreMallocs
+			}
+		}
+		fmt.Print(string(stderrBuf.Bytes()))
 		return false, err
 	}
+	fmt.Print(string(stderrBuf.Bytes()))
 
 	// Account for Windows line-endings.
 	stdout := bytes.Replace(stdoutBuf.Bytes(), []byte("\r\n"), []byte("\n"), -1)
@@ -186,6 +226,21 @@
 	return false, nil
 }
 
+func runTest(test test) (bool, error) {
+	if *mallocTest < 0 {
+		return runTestOnce(test, -1)
+	}
+
+	for mallocNumToFail := int64(*mallocTest); ; mallocNumToFail++ {
+		if passed, err := runTestOnce(test, mallocNumToFail); err != errMoreMallocs {
+			if err != nil {
+				err = fmt.Errorf("at malloc %d: %s", mallocNumToFail, err)
+			}
+			return passed, err
+		}
+	}
+}
+
 // shortTestName returns the short name of a test. Except for evp_test, it
 // assumes that any argument which ends in .txt is a path to a data file and not
 // relevant to the test's uniqueness.
diff --git a/src/util/bot/toolchain_vs2013.hash b/src/util/bot/toolchain_vs2013.hash
deleted file mode 100644
index 4ed8816..0000000
--- a/src/util/bot/toolchain_vs2013.hash
+++ /dev/null
@@ -1 +0,0 @@
-ee7d718ec60c2dc5d255bbe325909c2021a7efef
diff --git a/src/util/bot/vs_toolchain.py b/src/util/bot/vs_toolchain.py
index fd76f39..2a54b9e 100644
--- a/src/util/bot/vs_toolchain.py
+++ b/src/util/bot/vs_toolchain.py
@@ -34,8 +34,9 @@
 
     toolchain = toolchain_data['path']
     version = toolchain_data['version']
-    version_is_pro = version[-1] != 'e'
-    win8sdk = toolchain_data['win8sdk']
+    win_sdk = toolchain_data.get('win_sdk')
+    if not win_sdk:
+      win_sdk = toolchain_data['win8sdk']
     wdk = toolchain_data['wdk']
     # TODO(scottmg): The order unfortunately matters in these. They should be
     # split into separate keys for x86 and x64. (See CopyVsRuntimeDlls call
@@ -49,10 +50,10 @@
     # otheroptions.express
     # values there.
     gyp_defines_dict = gyp.NameValueListToDict(gyp.ShlexEnv('GYP_DEFINES'))
-    gyp_defines_dict['windows_sdk_path'] = win8sdk
+    gyp_defines_dict['windows_sdk_path'] = win_sdk
     os.environ['GYP_DEFINES'] = ' '.join('%s=%s' % (k, pipes.quote(str(v)))
         for k, v in gyp_defines_dict.iteritems())
-    os.environ['WINDOWSSDKDIR'] = win8sdk
+    os.environ['WINDOWSSDKDIR'] = win_sdk
     os.environ['WDK_DIR'] = wdk
     # Include the VS runtime in the PATH in case it's not machine-installed.
     runtime_path = ';'.join(vs2013_runtime_dll_dirs)
@@ -63,9 +64,8 @@
 def _GetDesiredVsToolchainHashes():
   """Load a list of SHA1s corresponding to the toolchains that we want installed
   to build with."""
-  sha1path = os.path.join(script_dir, 'toolchain_vs2013.hash')
-  with open(sha1path, 'rb') as f:
-    return f.read().strip().splitlines()
+  # Use Chromium's VS2013.
+  return ['ee7d718ec60c2dc5d255bbe325909c2021a7efef']
 
 
 def FindDepotTools():
@@ -85,7 +85,6 @@
       bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1')))
   if sys.platform in ('win32', 'cygwin') and depot_tools_win_toolchain:
     depot_tools_path = FindDepotTools()
-    json_data_file = os.path.join(script_dir, 'win_toolchain.json')
     get_toolchain_args = [
         sys.executable,
         os.path.join(depot_tools_path,
diff --git a/src/util/doc.go b/src/util/doc.go
index 20feae5..540d6ca 100644
--- a/src/util/doc.go
+++ b/src/util/doc.go
@@ -209,12 +209,24 @@
 }
 
 func getNameFromDecl(decl string) (string, bool) {
-	for strings.HasPrefix(decl, "#if") {
+	for strings.HasPrefix(decl, "#if") || strings.HasPrefix(decl, "#elif") {
 		decl = skipLine(decl)
 	}
 	if strings.HasPrefix(decl, "struct ") {
 		return "", false
 	}
+	if strings.HasPrefix(decl, "#define ") {
+		// This is a preprocessor #define. The name is the next symbol.
+		decl = strings.TrimPrefix(decl, "#define ")
+		for len(decl) > 0 && decl[0] == ' ' {
+			decl = decl[1:]
+		}
+		i := strings.IndexAny(decl, "( ")
+		if i < 0 {
+			return "", false
+		}
+		return decl[:i], true
+	}
 	decl = skipPast(decl, "STACK_OF(")
 	decl = skipPast(decl, "LHASH_OF(")
 	i := strings.Index(decl, "(")
diff --git a/src/util/generate_build_files.py b/src/util/generate_build_files.py
index 94de546..e534a56 100644
--- a/src/util/generate_build_files.py
+++ b/src/util/generate_build_files.py
@@ -90,6 +90,7 @@
       ],
       'sources': [
         '%s',
+        '<@(boringssl_test_support_sources)',
       ],
       # TODO(davidben): Fix size_t truncations in BoringSSL.
       # https://crbug.com/429039
@@ -99,9 +100,12 @@
 
       test_names.sort()
 
-      test_gypi.write("""  ],
-  'variables': {
-    'boringssl_test_targets': [\n""")
+      test_gypi.write('  ],\n  \'variables\': {\n')
+
+      self.PrintVariableSection(
+          test_gypi, 'boringssl_test_support_sources', files['test_support'])
+
+      test_gypi.write('    \'boringssl_test_targets\': [\n')
 
       for test in test_names:
         test_gypi.write("""      '%s',\n""" % test)
@@ -174,10 +178,16 @@
   """Filter function that can be passed to FindCFiles in order to remove
   non-test sources."""
   if is_dir:
-    return True
+    return dent != 'test'
   return '_test.' in dent or dent.startswith('example_')
 
 
+def AllFiles(dent, is_dir):
+  """Filter function that can be passed to FindCFiles in order to include all
+  sources."""
+  return True
+
+
 def FindCFiles(directory, filter_func):
   """Recurses through directory and returns a list of paths to all the C source
   files that pass filter_func."""
@@ -304,6 +314,9 @@
                           stdout=err_data)
   crypto_c_files.append('err_data.c')
 
+  test_support_cc_files = FindCFiles(os.path.join('src', 'crypto', 'test'),
+                                     AllFiles)
+
   test_c_files = FindCFiles(os.path.join('src', 'crypto'), OnlyTests)
   test_c_files += FindCFiles(os.path.join('src', 'ssl'), OnlyTests)
 
@@ -312,6 +325,7 @@
       'ssl': ssl_c_files,
       'tool': tool_cc_files,
       'test': test_c_files,
+      'test_support': test_support_cc_files,
   }
 
   asm_outputs = sorted(WriteAsmFiles(ReadPerlAsmOperations()).iteritems())